具有责任转移的转换构造函数

Conversion constructor with responsibility transfer

本文关键字:转换 构造函数 转移 有责任      更新时间:2023-10-16

这是对这个问题的追问。

我需要实现一个转换操作,将成员对象的责任从一个对象传递到另一个对象。转换操作发生在类层次结构中。有一个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项目,所以智能指针或boost库可能不可用(我不知道,虽然)-我只是记得这可能是一个解决方案,但我从未使用过它们。

我认为您需要查看引用计数对象。从本质上讲,对象本身跟踪它自己的使用情况,而不是存储指向对象的原始指针,而是使用引用计数指针。

Scott Meyers说:

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

由于你是在嵌入式系统上,我不确定你是否可以使用boost::shared_ptr<>,但没有什么能阻止你像Meyers概述的那样实现它。

因此,与其在基类中拥有一个指向相关对象的原始指针,不如拥有一个共享指针/引用计数指针,以便在对象被复制到Child2时防止对象被删除。通过Child2的构造,它将有2个引用,因此当Child1被删除时不会死亡。但是,当Child2被删除时,它将被删除。