提问人:bbbg 提问时间:4/10/2023 更新时间:4/10/2023 访问量:71
C++ 中的原型设计模式示例
Prototype Design Pattern Example in C++
问:
我正在学习原型设计模式并实现演示,我将深度复制构造函数和克隆函数添加到这些类中,但我不确定我是否正确实现了它们。我在otherNode中做了dynamic_cast转换,这有点奇怪。有什么建议吗?
class base {
public:
explicit base() {}
virtual ~base() = default;
virtual base* clone() const = 0;
};
class ttNode : public base {
public:
explicit ttNode() : base() {}
~ttNode() = default;
};
class SonNode : public ttNode {
public:
SonNode() : ttNode() {}
~SonNode() = default;
base* clone() const override {
return new SonNode(*this);
}
private:
int c_{0};
int a_{0};
};
class FatherNode : public ttNode {
public:
FatherNode() : ttNode() {}
~FatherNode() = default;
FatherNode(const FatherNode& node) : ttNode(node) {
for (const auto &son : node.sons_) {
sons_.emplace_back(new SonNode(*son));
}
}
base* clone() const override {
return new FatherNode(*this);
}
private:
std::vector<SonNode*> sons_;
};
class otherNode : public base {
public:
otherNode() : base() {}
~otherNode() = default;
base* clone() const override { return new otherNode(*this); }
otherNode(const otherNode& node) : base(node) {
ttt = dynamic_cast<ttNode*>(node.ttt->clone());
}
private:
ttNode* ttt;
};
TEST_F(tt, base1) {
base *o = new otherNode();
base *f = new FatherNode();
base *o1 = o->clone();
base *f1 = f->clone();
delete o1;
delete f1;
}
我不能使用,因为ttNode是抽象类。ttt = new ttNode(*node.ttt);
答:
0赞
Red.Wave
4/10/2023
#1
您对原始指针的大量使用使代码难以维护。当前代码段包含大量内存泄漏。除了原始指针的问题之外,还可以根据协变返回类型和/或 CRTP 来回答这个棘手的问题。从 C++20 开始,CRTP 可以使用推导的这个参数来暗示:
class base {
public:
explicit base() {}
virtual ~base() = default;
auto static_clone(this const auto &self) { return std::make_unique<std::remove_cvref_t<decltype(self)>(self);};
};
最终将为每个派生类型创建正确类型的唯一指针。CRTP与协变返回类型的组合是我还没有尝试过的;这似乎很复杂,特别是如果我们想尝试使用智能指针进行安全测试。
但现在你有两条不同的路线可以遵循:协变返回和/或 CRTP。static_clone
评论
ttNode
base
dynamic_cast
base*
clone
clone
FatherNode*
clone
ttNode
dynamic_cast