Lemonyun 2022. 4. 27. 15:18

 

//C++ 스킬3: 기본제공 타입의 객체는 직접 초기화하기, 멤버 초기화리스트를 자주 쓰기, 비지역 정적 객체들의 초기화 순서 문제 피하기
#include<iostream>
class Hello {
public:
Hello(const std::string& name) {
m_name = name; // 생성자에서 데이터 멤버를 초기화 할때 대입을 하는 것은 string에 대해서 기본생성자를
m_a = 0; // 호출해서 이미 초기화 시킨 상태에서 복사 대입 연산자를 연달아 호출하는 것
}
private:
int m_a;
std::string m_name;
};
// 어떤 데이터 멤버가 멤버 초기화 리스트에 들어가지 않았고 그 데이터 멤버의 타입이 사용자 정의 타입이면, 컴파일러가 자동으로 그들 멤버에 대해 기본 생성자를 호출하게 되어있음
//멤버 초기화 리스트를 사용하면 이를 피할 수 있음
//데이터 멤버가 참조자나 상수로 되어있으면 반드시 초기화 되어야하기 때문에 초기화 리스트를 사용하는 것이 의무적임
class World {
public:
World(const std::string& name) :
m_name(name), // 멤버 초기화 리스트 // 컴파일러에서 멤버가 초기화 되는 순서는 선언된 순서와 같으므로 순서를 맞춰 주자
m_a(0)
{
}
private:
int m_a;
std::string m_name;
};
// 여러개의 번역 단위에서 비지역 정적 객체들의 초기화순서는 정해져있지 않음
// 비지역 정적 객체를 지역 정적 객체로 바꾸어 해결할 수 있음
// 2번 정적 객체를 생성할 때 1번 정적 객체를 사용한다고 가정하면 1번 객체는 초기화가 되어있어야 한다.
// 지역 정적 객체를 초기화하고 참조자로 반환하는 함수를 정의하고
// 2번 클래스 생성자에서 1번 객체를 사용하는 대신에 함수를 사용하여 객체를 불러오게 되면 초기화 순서를 보장할 수 있다.
class FileSystem {
public:
std::size_t numDisks() const;
};
FileSystem& tfs() {
static FileSystem fs; // 지역 정적 객체를 정의하고 초기화하고
return fs; // 참조자로 반환
}
std::size_t FileSystem::numDisks() const {
std::cout << "hello";
return 10;
}
class Directory {
public:
Directory();
};
Directory::Directory() {
std::size_t disks = tfs().numDisks(); // 비지역 정적 객체를 참조하는 것이 아니라 지역 정적 객체의 참조자를 반환하는 함수를 대신해서 사용
}
Directory& tempDir() {
static Directory td;
return td;
}
int main(void) {
Directory temp = tempDir();
}

C++ 스킬3: 기본제공 타입의 객체는 직접 초기화하기, 멤버 초기화리스트를 자주 쓰기, 비지역 정적 객체들의 초기화 순서 문제 피하기