Item 4: Make sure that objects are initialized before they're used

모르핀·2021년 4월 18일
0

C++기초

목록 보기
4/7

Constructor

아래의 코드는 멤버 변수를 초기화하는 것이 아니라 대입하고 있는 것이다.

class MyClass
{
private:
    string theName;
    string theAddress;
    int theNumber;
public:
    MyClass(const string& name, const string& address, int number)
    {
    
        theName = name;
        theAddress = address;
        theNumber = number;
    }
};

멤버 변수를 초기화하려면 다음과 같이 해야한다.

class MyClass
{

private:
    string theName;
    string theAddress;
    int theNumber;
public:
//initialization list의 순서가 다르더라도, 멤버 변수는 선언된 순서대로 초기화가 진핸된다. 
    MyClass(const string& name, const string& address, int number) //initialization list
    :   theName(name),
        theAddress(address), 
        theNumber (number)
        {}
};

전자의 코드는 기본 생성자를 부르고 대입을 하기 때문에 후자의 코드보다 효율성이 떨어진다.
그리고 멤버 변수가 const거나 reference면 반드시 후자를 택해야한다.

MyClass() 
: theName(),
  theAddress(), 
  theNumber ()
  {}

그리고 일관성과 실수를 피하기 위해서 initialization list를 사용하는 것이 좋다.

static object initialization

정적 객체(static object)

자신이 생성된 시점부터 프로그램이 끝날 때까지 살아있는 객체입니다.

이들 중 함수 안에 있는 정적 객체를 지역 정적 객체(local static object)라고 하고, 나머지는 비지역 정적 객체(non-local static object)라고 합니다.

그런데 비지역 정적 객체의 경우에는 초기화 순서가 정해져 있지 않습니다. 그리하여 다음과 같은 코드는 초기화 순서 때문에 에러가 날 수 있습니다.

extern FileSystem tfs;

class Directory
{

public:
    Directory()
    {
        size_t disks = tfs.numDisks(); //tfs가 먼저 초기화 될지 tmpDir이 먼저 초기화 될지 모른다.
    }
};

Directory tmpDir();

이러한 문제점을 고치는 방법은 간단합니다.

지역 정적 객체, 자신이 있는 함수가 호출되기 전까지는 초기화가 되지 않는 점을 이용한다면 아래와 같은 코드와 같이 쉽게 해결할 수 있습니다.

FileSystem& tfs() 
{
    static FileSystem fs; 
    return fs;
}

...

Directory& tempDir()
{
    static Directory td; 
    return td;
}
profile
플어머

0개의 댓글