2011-10-14 4 views
0

다음은 후속 조치 this입니다.책임 전환이있는 변환 생성자

구성원 개체에 대한 책임을 한 개체에서 다른 개체로 전달하려면 변환 작업을 구현해야합니다. 변환 작업은 클래스 계층 구조에서 수행됩니다. Base 클래스와 두 개의 파생 클래스, 예를 들어 Child1Child2이 있습니다. Base 클래스에는 변환이 발생하는 동안 Child1에서 Child2으로 전달해야하는 동적으로 생성 된 객체가 있으며 Child1의 소멸자가이를 파괴하지 못하게합니다. 내가 달성하기 위해 노력하고있어 설명하기 위해 간단한 예제를 작성했습니다 :

#include <iostream> 
using namespace std; 

class Base { 
public: 
    Base() { 
     p_int = new int; *p_int = 0; 
     cout << "In Base constructor, reserving memory." << endl; 
    } 
    Base(const Base& other) : p_int(other.p_int), a(other.a) { 
     cout << "In Base copy-constructor." << endl; 
    } 
    virtual ~Base() { delete p_int; p_int = NULL; cout << "Freeing memory." << endl; } 

    void setpInt(int val) { *p_int = val; } 
    void setInt(int val) { a = val; } 
    virtual void print() { 
     cout << "Base: "; 
     cout << (long)p_int << ":" << *p_int << " " << a << endl; 
    } 
protected: 
    int* p_int; 
    int a; 
}; 

class Child1 : public Base { 
public: 
    Child1() : Base() {}; 
    Child1(const Base& base) : Base(base) {} 

    void print() { 
     cout << "Child1: "; 
     cout << (long)p_int << ":" << *p_int << " " << a << endl; 
    } 
}; 

class Child2 : public Base { 
public: 
    Child2() : Base() {}; 
    Child2(const Base& base) : Base(base) {} 

    void print() { 
     cout << "Child2: "; 
     cout << (long)p_int << ":" << *p_int << " " << a << endl; 
    } 
}; 

int main() { 
    Child1* c1 = new Child1(); 
    c1->setpInt(3); 
    c1->setInt(2); 
    c1->print(); 

    Child2* c2 = new Child2(*c1); 
    c2->print(); 

    delete c1;  //Obviously c1's destructor is called here. 
    c2->print(); 

    delete c2; 

    return 0; 
} 

을 그리고 결과는 다음과 같습니다

In Base constructor, reserving memory. 
Child1: 158711832:3 2 
In Base copy-constructor. 
Child2: 158711832:3 2 
Freeing memory. 
Child2: 158711832:0 2 
Freeing memory. 

내가에서 할 노력하고있어 할 수있는 방법이 있나요 깨끗한 방법? 매우 무거 우므로 p_int을 복사 할 수 없습니다. 이 프로젝트는 임베디드 AVR 프로젝트이므로 스마트 포인터 나 라이브러리를 사용하지 못할 수도 있습니다. (필자는 잘 모르겠다.) 단지 해결책 일지 모르지만 아직 사용하지는 못했습니다.

+0

예제는 파생 클래스가 비어 있기 때문에 약간 빈약합니다. 당신이하고있는 일은 뻔뻔 스럽지만 * 일반적으로 이것은 좋지 않습니다. 그러나 실제 사례 없이는 말할 수 없습니다. 하나의 파생 클래스를 다른 파생 클래스로 변환하려면 분할 변환이 아닌 진정한 변환 생성자를 제공해야합니다. 일종의 이동 의미 (예 :'Child2 c2 (std :: move (* c1)) '등)를 원하면 rvalue 참조에 바인드 시키십시오. –

답변

2

참조 카운트 개체를 볼 필요가 있다고 생각합니다. 본질적으로, 객체 자체는 사용법 자체를 추적하며 객체에 원시 포인터를 저장하는 대신 참조 카운트 된 포인터를 사용합니다.

스콧 마이어스는 여기에 대해 이야기 : 당신이 임베디드 시스템에있어으로

http://www.aristeia.com/BookErrata/M29Source.html

, 난 당신이 boost::shared_ptr<>을 사용할 수 있습니다 모르겠지만 마이어스는 설명으로 이것을 구현을 중지 아무것도 없다.

기본 클래스에서 문제의 객체에 대한 원시 포인터 대신에 Child2에 복사 된 객체의 삭제를 방지하는 공유 포인터/참조 카운트 포인터가 있어야합니다. Child2의 생성에 의해 2 개의 참조가 생기므로 Child1이 삭제되면 죽지 않습니다. 그러나 Child2가 삭제되면됩니다.