使用对装饰对象的成员引用在C++中实现装饰器类,但未按预期工作
Implementation of the decorator class in C++ using a member reference to the decorated object not working as expected
我正在尝试学习C++中的装饰器模式实现。我已经尝试使用引用和指向装饰对象的指针作为成员(组合(来实现装饰器类。一次对decorator的调用就能正常工作。然而,当我尝试将多个装饰器实例链接在一起时,只有当我将指向装饰对象的指针用作装饰器类成员时,它才有效。对于具有装饰对象引用的实现,它意外失败(请参见下面的输出(。我使用的是启用了C++11的GCC。这是代码。类RedRose是一个使用指向基本接口的指针的装饰器,而类BlueRose使用对基本接口的引用。如果我犯了一个天真的错误,我很抱歉,但我错过了什么?
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
class Flower
{
public:
Flower() {}
virtual string str() = 0;
};
class Rose : public Flower
{
public:
Rose() {}
string str() override {
return "A rose";
}
};
class RedRose : public Rose
{
private:
Flower *rose;
public:
explicit RedRose(Flower *rose) : rose{rose} {}
string str() override
{
ostringstream oss;
oss << rose->str() << " that is red ";
return oss.str();
}
};
class BlueRose : public Rose
{
private:
Flower &rose;
public:
explicit BlueRose(Flower &rose) : rose{rose} {}
string str() override
{
ostringstream oss;
oss << rose.str() << " that is blue";
return oss.str();
}
};
int main(int argc, char *argv[])
{
Rose rose; // The decorated object
// Chaining together docorator with pointer implementation
RedRose red_rose{&rose};
RedRose red_red_rose{&red_rose};
RedRose red_red_red_rose{&red_red_rose};
cout << red_rose.str() << endl;
cout << red_red_rose.str() << endl;
cout << red_red_red_rose.str() << endl;
Rose rose2;
// Chaining together docorator with reference implementation
BlueRose blue_rose{rose2};
BlueRose blue_blue_rose{blue_rose};
BlueRose blue_blue_blue_rose{blue_blue_rose};
cout << blue_rose.str() << endl;
cout << blue_blue_rose.str() << endl;
cout << blue_blue_blue_rose.str() << endl;
getchar();
}
这是的输出
A rose that is red
A rose that is red that is red
A rose that is red that is red that is red
A rose that is blue
A rose that is blue
A rose that is blue`
如果删除复制构造函数,就会看到问题:
class Flower
{
public:
Flower() {}
Flower(const Flower&) = delete;
virtual string str() = 0;
};
error: use of deleted function ‘BlueRose::BlueRose(const BlueRose&)’
BlueRose blue_blue_rose{blue_rose};
BlueRose
的构造函数采用Flower&
,另一个采用const BlueRose&
,因此首选复制构造函数。
一种解决方案是生成构造函数:
template<typename T>
explicit BlueRose(T &rose) : rose{rose} {}
但实际上,您不应该使用引用,因为如果包装对象的生存期比装饰器短,它们可能会挂起。尝试std::unique_ptr
。
相关文章:
- CV_OCL_RUN宏如何在OpenCV(版本3.4.5)的goodFeaturesToTrack实现中工作?
- 实现 DFS 在较短的输入下工作正常,但在较大的输入下会抛出分段错误
- nth_element基于修改后的quick_sort实现,无法按预期工作
- 这个数组交集的实现是如何工作的
- 查找表究竟是如何工作的,以及如何实现它们
- 只有第一个缓冲区可以在C++中实现的Double缓冲区中工作
- 尝试实现二叉搜索算法,似乎无法使其工作
- popen() 如何工作以及如何在 Linux 上实现它到 C++ 代码中
- opengl32.lib如何在Windows(仅1.1版本)上工作?它是否真正实现了OpenGL函数
- 在 gcc 上自己的元组实现段错误,同时在 clang 中工作
- 运算符 [] 函数的实现是如何工作的
- 如何以相同的方法在子类中超载的相同方法来实现工作变量参数方法
- 实现快速排序,几乎可以工作但不能
- 在Graph实现中,对和向量是如何工作的
- 在C 中实现此类工作流程的最佳方法
- 这种珠子排序算法的 c++ 实现是如何工作的
- 有可能实现一个与数组而不是单个对象一起工作的内存池吗
- 我正试图在我的SFML Platformer中实现双跳,但它并没有按预期的方式工作
- C++,当每个工作线程都必须执行几个不同的任务时,如何为任务实现线程池
- 解释在opencv中实现的阴影检测代码的工作原理