객체를 사용하기 전에 반드시 그 객체를 초기화 하자 대입과 초기화는 다름...
description
Transcript of 객체를 사용하기 전에 반드시 그 객체를 초기화 하자 대입과 초기화는 다름...
객체를 사용하기 전에 반드시 그 객체를 초기화 하자
대입과 초기화는 다름
Test::Test(Int a) : value(a){
value2 = 0; // 초기화 되리란 보장 없음 operator=( 대입연산자 )}
컴파일러가 제공하는 기본 생성자 , 소멸자 , 대입 연산자를 주의 .
Class Empty {Public:Empty() { … }Empty(const Empty& rhs) { … }~Empty() { … }
Empty& operator=(const Empty& rhs) { … }};
컴파일러가 만들어낸 함수가 필요 없으면 확실히 사용을 금해 버리자
HomeForSale h1;HomeForSale h2;
HomeForSale h3(h1);//H1 = h2; //
class HomeForSale {private:HomeForSale(const HomeForSale&);HomeForSale& operator=(const HomeForSale&);};
다형성을 가진 기본 클래스에서는 소멸자를 반드시 가상 소멸자로 선언
class TimeKeeper { public: TimeKeeper(); virtual ~TimeKeeper(); };
Time Keeper* ptk = getTimeKeeper(); delete ptk;
객체 생성 및 소멸 과정 중에는 가상 함수를 호출하지 말자
기본 클래스의 생성자가 호출될 동안에는 가상 함수는 파생 클래스 쪽으로 내려가지 않는다 .
class Transaction {public:Transaction(){
init();}
virtual void logTransaction() const = 0;
private:void init(){
logTransaction();}
};
operator= 에서는 자기대입에 대한 처리가 빠지지 않도록
Widget w;w = w;
Widget& Widget::operator=(const Widget& rhs){
if(this == &rhs)return *this;
…….}
Widget& Widget::operator=(const Widget& rhs){
Bitmap* pOrg = pb;pb = new Bitmap(*rhs.pb);delete pOrg;
return* this;}
auto_ptr
auto_ptr<int> pInt(new int);
단점
동적할당을 배열 단위로 하면 정상적으로 메모리 해제가 안된다 .
한 곳의 위치를 가리키는 2 개의 auto_ptr 을 생성할 수 없다 .
a = b;
shared_ptr
참조 카운팅 방식 스마트 포인터
참조 개수가 0 이 되면 메모리 해제
shared_ptr<investment> pInv2(pInv1);
pInv1 = pInv2;
특수한 역할을 수행하는 객체에 대한 동작은 ?
Mutex m;
Lock m11(&m); // 잠금Lock m12(&m11); // ????
1. 복사를 못하게 막음
2. 관리하고 있는 자원 깊은 복사
3. 소유권 옮김 (auto_ptr 처럼 )
4. 관리하는 자원에 대한 참조 카운팅 수행
Mutex m; Lock m11(&m); Lock m12(&m11);
class Lock { public: explicit Lock(Mutex* pm) : mutexPtr(pm, unlock) {
lock(mutexPtr.get()); }
private:shared_ptr<Mutex> mutexPtr;
};
자원관리 클래스에서 관리되는 자원을 외부에서 사용할 수 있게 해야 함
class Investment {public:bool isTaxFree() const;};
shared_ptr<Investment> pi1(createInvestment());
bool taxable2 = !(pi1->isTaxFree());