일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 멀티코어
- Atomic
- random access
- thread
- observer pattern
- sequential
- Multithread
- Design Pattern
- 메모리관리
- 한국산업기술대학교
- 쓰레드
- C
- 옵저버 패턴
- 게임공학과
- vector
- 프레임워크
- 디자인패턴
- 옵저버
- EFFECTIVE C++
- 복사생성자
- Unreal
- MultiCore
- multi-core
- 스마트포인터
- c++
- stl
- material
- 멀티코어 프로그래밍
- 멀티쓰레드
- 유니크포인터
- Today
- Total
태크놀로지
[Effective C++] 객체 생성시 초기화 방법 본문
초기화 : 객체가 항상 초기화 된다는 보장이 없다. 따라서 모든 객체를 사용하기전 항상 초기화 해주어야한다.
1. 대입과 초기화와 헷갈리지 말자.
class X;
// 멤버변수 theName, theAddress ,,,
// 1. 대입 : 초기화가 아닌 대입이 되고 있다.
X(name, address,,,) {
theName = name;
theAddress = address;
,,,
}
// 2. 초기화 : 멤버 초기화 리스트
X(name, address,,,) : theName(name), theAddress(address) ,,,
두번째 방법이 왜 더 효율적인가?
첫번째 방법은 기본생성자를 통해 미리 초기화 한후, 값을 대입해주고 있다.
-> 기본생성자 호출 -> 복사 대입연산자 호출
두번째 방법은 데이터 멤버에 대한 생성자의 인자로 쓰이고 있다. 따라서 theName은 name으로부터 복사생성자에 의해 초기화되고 나머지도 동일하다.
-> 복사생성자 호출
* 초기화 할 멤버 초기화 리스트가 길어질경우, 별도의 Initialize함수로 분리하는것도 나쁘지않음. 그것또한 대입이기 때문에 성능상으로는 멤버 초기화 리스트가 가장좋음.
2. 초기화 순서
기본클래스 생성자 호출 -> 파생클래스 생성자 호출
클래스 데이터 멤버는 선언된 순서대로 초기화 됨.
※ 주의 멤버 초기화 리스트에 넣는 멤버들의 순서대로 초기화 됨
3. 정적 객체 초기화
정적 객체 범위
- 전역 객체
- namespace로 묶인 전역객체
- 클래스 내의 static 객체
- 함수 내의 static 객체
- 파일 유효범위내의 static 객체
- 지역 정적 객체 : 함수 안에 있는 static 객체
- 비지역 정적 객체 : 그 이외에 나머지
정적 객체 특징
이러한 정적 객체는 프로그램이 끝날때 자동으로 소멸됨. (main함수의 실행 ~ main함수 끝날때까지 생존)
분할된 파일에서의 각각의 정적변수 초기화 순서는 정해져 있지 않다.
문제 발생의 예제
class FileSystem;
FileSystem fs;
class Directory;
Directory::Directory( param ){
size_t disks = fs.numDisk(); // fs 객체 사용
}
-> FileSystem보다 Directory가 먼저 생성될경우 에러 발생
해결책
FileSystem& GetInstance(){
static FileSystem fs;
return fs;
}
Directory::Directory(){
size_t disks = fs().numDisk();
}
-> 비지역 (정적객체 -> 지역 정적 객체)로 변경 (대표적인 예 - 싱글톤)
정리
- 기본제공 타입의 객체는 직접 초기화 하자 ex) int a = 5;
- 대입이 아닌 멤버 초기화 리스트를 즐겨 사용하자.
- 멤버 초기화 리스트를 나열할때 선언된 순서와 똑같이 나열하자.
- 비지역 정적 객체들의 초기화 순서는 알 수 없기 때문에, 비지역 -> 지역 정적객체로 바꾸어 해결하자
스터디 진행후 토론내용 정리
1. static 멤버 변수의 초기화는 헤더파일에서 불가능하다.
- 여러곳에서 헤더파일을 include 할때마다 static 멤버 변수를 여러번 정의 및 초기화 하는 상황이 발생
2. 클래스 내에 static 멤버 변수 선언은 메모리를 잡지 않는다. 단지 컴파일러에게 존재를 알려주는것뿐
- 정의, 즉 초기화를 해주어야만 메모리를 잡는다.
+ static 붙은 전역변수 : 해당 cpp파일 내에서만 사용가능
+ extern 붙은 전역변수 : 다른 파일에서 사용이 가능함과 동시에 메모리가 공유된다.
ansohxxn.github.io/cpp/chapter8-10/
출처
'C++' 카테고리의 다른 글
[Effective C++] 대입연산자, 제대로 메모리 관리를 하고 있는가? (0) | 2020.11.24 |
---|---|
[Effective C++] 생성자와 소멸자, 제대로 메모리 관리를 하고 있는가? (0) | 2020.11.19 |
[Effective C++] 왜 const를 사용해야하는가 (0) | 2020.11.18 |
[C++/STL] Ranking System 분석 (0) | 2020.09.25 |
[C++/STL] Ranking System 소개 및 구현 (0) | 2020.09.25 |