항목 10 : 대입 연산자는 *this의 참조자를 반환하게 하자
·
STUDY/Effective C++
x = y = z = 15; x = (y = ( z = 15); 사슬처럼 엮이는 대입연산의 특징 우측연산을 클래스 대입 연산자에서도 적용을 시키자. class Widget { public: ... Widget& operator=(const Widget& rhs) { ... return *this; } ... }; 좌변 객체를의 참조자를 반환하는 형태는 관례이다. 굳이 안따라도 되지만 모든 기본제공타입들이 따르고 있을뿐만 아니라 표준 라이브러리에 속한 모든 타입들도 따르고 있다.
항목 9 : 객체 생성 및 소멸 과정 중에는 절대로 가상 함수를 호출하지 말자
·
STUDY/Effective C++
class Transaction { public: Transaction(); virtual void logTransaction() const = 0; ... }; Transaction::Transaction() //기본 클래스 생성자 { ... logTransaction(); } class BuyTransaction: public Transaction { //Transaction의 파생 클래스 public: virtual void logTransaction() const; ... }; BuyTransaction b; 위와 같은 코드가 있을때 BuyTransaction b; 코드를 작성한다면 호출되는 logTransaction함수는 BuyTransaction의 것이 아니라 Transaction의 것이다. ..
항목 8: 예외가 소멸자를 떠나지 못하도록 붙들어 놓자
·
STUDY/Effective C++
c++은 예외를 내보내는 소멸자를 좋아하지않는다. 당연하다. 소멸자가 그냥 조용히 소멸하는것이 아닌 예외까지 발생하면 프로그램의 불완전 종료 나 미정의 동작의 위험을 내포하고있기때문이다. 하지만 항사 우리가 원하는대로 코드를 짤 순 없다. 만약에 예외를 던지고 실패할 수 있는 코드를 소멸자에 넣어한다면 어떻게 해야할까 1. 프로그램 바로 끝내기 DBConn::~DBConn() { try {db.close(); } catch (...) { close 호출이 실패했다는 로그 출력; std::abort(); } } abort를 호출해서 못 볼꼴을 미리 안보여준다. 2. 예외 삼켜버리기(무시하기) DBConn::~DBConn() { try {db.close(); } catch (...) { close 호출이 실..
항목 7: 다형성을 가진 기본 클래스에서는 소멸자를 반드시 가상 소멸자로 선언하자
·
STUDY/Effective C++
다형성을 가진 기본 클래스에서 비가상 소멸자를 통해 소멸하면 어떻게 될까? class TimeKeeper { public: TimeKeeper(); ~TimeKeeper(); ... }; TimeKeeper* getTimeKeeper(); TimeKeeper *ptk = getTimeKeeper(); ... delete ptk; 기본 클래스 포인터를 통해 파생 클래스 객체가 삭제될 때 비가상 소멸자가 들어 있으면, 대부분 그 객체의 파생 클래스 부분이 소멸되지않게 된다. 파생 클래스의 소멸자도 실행되지 않지만 기본클래스 부분은 소멸 과정이 제대로 끝나 '부분소멸'이 되게된다. 이 문제를 없애기위해서는 기본 클래스에 가상 소멸자를 넣어놓으면된다. class TimeKeeper { public: TimeKe..