Person *person = new Person("淼淼"); DecorateA *deA = new DecorateA(); DecorateB *deB = new DecorateB(); DecorateC *deC = new DecorateC(); deA->setComponent(person); deB->setComponent(deA); deC->setComponent(deB); deC->show();
代码如上,那deA deB deC 还有person,应该这么来delete了?
假如想下面这样delete的话,会出错:
delete deC;
delete deB;
delete deA;
delete person;
倒过来也会的、
问一下各位,想这种情况,应该怎么析构了?
源码 可以参照这里:
https://git.oschina.net/wuxiangfeng/DesignModeStudy.git
解决方案:15分
和调用子对象构造/习惯函数一样,一般建议倒着来。
但是lz的很特殊,肯定没有处理好引用关系。
最基本的先把引用关系去除再delete就没问题了。
但是lz的代码本身问题非常大。随便看了一个:
但是lz的很特殊,肯定没有处理好引用关系。
最基本的先把引用关系去除再delete就没问题了。
但是lz的代码本身问题非常大。随便看了一个:
DecorateB::~DecorateB(void) { if(component != nullptr) { delete component; component = NULL; } }
可以看出,component的“结束生命”的控制权在析构函数里,
new/delete必须遵守在同一个层次里面。所以肯定new也必须在构造函数里面。
可惜构造是在外部手动构造的。像这种多次引用的,建议使用引用计数。
Person *person = new Person("淼淼"); DecorateA *deA = new DecorateA(); DecorateB *deB = new DecorateB(); DecorateC *deC = new DecorateC(); deA->setComponent(person); deB->setComponent(deA); deC->setComponent(deB); deC->show(); deA->Release(); deB->Release(); deC->Release(); person->Relase();
B的: 其他的也相似
DecorateB::clear() { if(component != nullptr) { component->Relase(); component = nullptr; } } DecorateB::~DecorateB() { this->clear(); } void DecorateB::setComponent(Person* component) { this->clear(); this->component = component; if(component) component->AddRef(); }
对了,C++没有参数不用写void,那是C的标准。这里参考的是COM的接口AddRef/Release
解决方案:3分
对电脑而言没有乱码,只有二进制字节;对人脑才有乱码。啊 GBK:0xB0 0xA1,Unicode-16 LE:0x4A 0x55,Unicode-16 BE:0x55 0x4A,UTF-8:0xE5 0x95 0x8A
推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。
推荐使用WinHex软件查看硬盘或文件或内存中的原始字节内容。
解决方案:2分
其实还有一个办法
从代码看
Person
和
DecorateA
两个类没有任何直接关系
DecorateA 只是把 Person 作为 成员使用
因此 DecorateA 的析构函数,完全可以不必关心 Person 指针。
让 负责 new Person 的代码 ,析构 Person 就可以了
这样即便不是 new 的对象 DecorateA等类 依然可以引用
从代码看
Person
和
DecorateA
两个类没有任何直接关系
DecorateA 只是把 Person 作为 成员使用
因此 DecorateA 的析构函数,完全可以不必关心 Person 指针。
让 负责 new Person 的代码 ,析构 Person 就可以了
这样即便不是 new 的对象 DecorateA等类 依然可以引用