{ 여기서 말하는 일관된 방식은 무엇인가? 복사 생성자(T(const T&))를 정의했다면, 복사 할당자(operator=), 디스트럭터(~T()) 를 정의 하라는 것이다. 왜? 복사 생성자를 정의 했다는 의미는 무엇인가 특별한 멤버 변수를 갖는 다는 것을 의미한다. 그러므로, 복사 할당자나 디스트럭터나 특별히 무엇인가 작업을 해 주어야 한다는 것이다. 자신이 뿌린 씨앗은 자신이 거두어야 한다는 것을 의미하는 것과 같다. 복사 생성자만 그러하나? 의미를 볼땐 위의 3가지 중 하나라도 정의 했다면, 다 정의 해 주는게 좋다. 누가 좋다고 하는가? 허브 셔터와 안드레이 알렉산드레스쿠가 그런다. ... 예외는 없는가? 물론 있다. 굳이 3개를 짝으로 구현할 필요가 없다면, 안해도 된다. 이때는 애초에 정의할 ..
분류 전체보기 검색 결과
{ .. 실패하지 않는다가 아니라. 실패해서는 안된다가 더 적당할 듯 싶다. 왜 그럴까? 각개 격파해서 정리한다. 디스트럭터에서 실패하면 왜 안되는가? 객체의 소멸 시점은, 자신이 속한 지역을 벗어 날 때이거나, 명시적으로 없애고자 할 때이다. 자신이 속한 지역에서 벗어 날 때는 무척 광범위한 영역에서 발생 할 수 있는데, 대표적으로 값에 의한 전달을 이용하는 함수에서 많이 일어 날 수 있을 것 같다. 값이 복사 되고 예외가 발생 했다고 치자. 이때 예외가 발생해서 지역을 탈출 하려고 하는데, 탈출 시 "스택 되감기"가 이루어 지면서, 다시 소멸자가 호출 되어 지고, 여기서 예외가 발생 한다 치자. 그러면 예외 중에 예외가 발생 한 것이니, C++ 에선 그냥 프로그램을 죽이는 함수를 호출 한다. 프로그램..
{ 이번 항목은 좀 역발상으로 이야기를 쫒아 본다. 기반 클래스의 디스트럭터가 public 과 virtual 이라면, 파생 클래스에게 어떠한 영향을 미치는가? 1. 객체 생성이 자유롭다. 2. 객체의 완전한 소멸이 기반 객체의 포인터로도 가능하다. 그렇다면, protected 와 non-virtual 이라면? 1. 객체 생성이 friend나 상속 기반에서만 이루어 진다. 2. 객체의 완전한 소멸은 항상, 파생 클래스에서만 가능하다. 이 두가지 방식을 따라야 하는 이유는 무엇인가? 메모리가 누수될 가능성이 무척 커진다. 이해 못하겠다. 예제를 보여 달라. #include #include // example class Base { public: ~Base() // non virtual { std::cout
{ 왜냐하면, 파생 객체의 생성자 호출 순서는 항상 기반 객체이기 때문이다. 잘 이해가 안간다....? 그러니까 기반 객체의 생성자가 호출 될 때 가상 함수가 호출 되어 지면, 파생 객체는 아직 만들어 지지 않았기 때문에, 파생 객체의 함수가 호출 되지 않고, 기반의 함수가 호출 된다. 이는 개발자에게 가독성은 물론이거나와 몹시 어렵다는 느낌을 줄 수 밖에 없다. 디스트럭트 역시 마찬가지다. 예제는? #include #include // example class Base { public: ~Base() {} Base( char *__p ) { Draw(__p); } public: virtual void Draw(char *) { std::cout
{ 왜냐하면 불필요한 작업을 줄일 수 있기 때문이다. 무엇이 불필요한 작업인가? 변수는 생성과 동시에 초기화값을 대입하면, 한번의 생성으로 값을 셋팅 할 수 있다. 그러니 값을 생성 하고 난 뒤에 값을 대입한다면, 불필요한 작업이 되는 것이다. 그래서 모두 초기화 목록에서 초기화 했는데, 보기가 어렵더라? 맞는 말이다. 변수가 많은 경우에는 특정 함수로 빼서 사용 하는게 더 간편하고 안전하다. 너무 이른 최적화가 아닌가? 이건 최적화 축에도 못낀다. 적당한 선에서 타협하여, 함수로 뺄찌 초기화 리스트에 넣을지 결정하는게 좋을 것 같다. }
{ 왜냐하면 멤버 변수의 정의순으로 초기화 하기 때문이다. #include #include class name { public: ~name() {} name(char *__pfirst_name, char *__plast_name ) : last_name_(__plast_name) , first_name_(__pfirst_name) , full_name_( first_name_ + " " + last_name_ ) {} const std::string& get_full_name() { return full_name_; } private: std::string full_name_; std::string first_name_; std::string last_name_; }; int main( void ) { ..
최근댓글