Post List

2015년 1월 4일 일요일

Object 사용전에는 반드시 초기화하자.

* 기본 Type는 직접 초기화합니다. Compiler 별로 자동으로 되는 것도 있고 안되는 것도 있습니다.

* 생성자에서, Member 변수에 대입문으로 넣지말고, 초기화 리스트를 사용합시다. 초기화 리스트 사용시에는 Member  변수가 선언된 순서대로 나열합시다.

class C {
public:
    C(const std::string& name, const std::string& address, const std::list<PhoneNumber>& phones);
private:
    std::string theName;
    std::string theAddress;
    std::list<PhoneNumber> thePhones;
    int numTimesConsulted;
};

C::C(const std::string& name, const std::string& address, const std::list<PhoneNumber>& phones)
{
    theName = name;         // 이건 대입이지 초기화가 아니다.
    theAddress = address;
    thePhones = phones;
    numTimesConsulted = 0;
}

C::C(const std::string& name, const std::string& address, const std::list<PhoneNumber>& phones)
:   theName(name)         // 이것이 초기화이다.
,   theAddress(address)
,   thePhones(phones)
,   numTimesConsulted(0)
{
}

* 각각의 번역 단위(하나의 object file)에서 비지역 정적 객체(다른 파일의 static object)들의 초기화 순서 문제는 피해서 설계해야 합니다. 비지역 정적 객체를 지역 정적 객체로 바꾸면 됩니다.

// FileSystem.h
class FileSystem {
public:
    std::size_t numDisks() const;
};

extern FileSystem tfs; // 사용자가 사용하게 될 객체

// Directory.h
class Directory {
public:
    Directory(params);
};

// Directory.cpp
Directory::Directory(params) {
    std::size_t disks = tfs.numDisks(); // tfs가 초기화 되었는지 확신할 수 있는가 ?
}

위의 예제의 경우 tfs를 FileSyste.cpp에서 초기화 했다고 했을 때, FileSystem.obj 와 Directory.obj 중 뭐가 먼저 Compile 될지는 모른다.
비지역 정적 객체를 직접 사용하지 말고, 호출하는 함수로 구현하면 안전하게 사용할 수 있다. 즉 비지역 정적 객체가 지역 정적 객체로 바뀐 것이다. 디자인 패턴의 Singleton Pattern과 비슷하다.

// FileSystem.h
class FileSystem {
public:
    std::size_t numDisks() const;
};

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

// Directory.h
class Directory {
public:
    Directory(params);
};

Directory& tempDir() {
    static Directory td;
    return td;
}

// Directory.cpp
Directory::Directory(params) {
    std::size_t disks = tfs().numDisks();
}



댓글 없음:

댓글 쓰기