C++中的原型设计模式

flvtvl50  于 2023-04-13  发布在  其他
关注(0)|答案(1)|浏览(111)

我正在学习原型设计模式,并实现了一个demo,我在这些类中添加了深度复制构造函数和克隆函数,但我不确定我是否正确实现了它们。我在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;
}

我不能使用ttt = new ttNode(*node.ttt);,因为ttNode是抽象类。

dwbf0jvd

dwbf0jvd1#

你对原始指针的大量使用使得代码很难维护。并且当前代码段包含大量内存泄漏。除了原始指针的问题之外,标准问题可以用covariant return types和/或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);};
};

static_clone最终将为每个派生类型创建正确的唯一指针类型。CRTP与协变返回类型的组合是我还没有尝试过的;这似乎很复杂,特别是如果我们想尝试使用智能指针的安全性。但是现在你有两种不同的路线可以遵循:协变返回和/或CRTP

相关问题