gpt4 book ai didi

c++ - 唯一指针和 3 法则

转载 作者:太空狗 更新时间:2023-10-29 20:51:11 28 4
gpt4 key购买 nike

当我需要多态行为时,我经常发现自己在 C++ 中使用唯一指针。我通常实现如下所示的纯抽象类:

class A { 
public:
virtual A* clone() const = 0; // returns a pointer to a deep copy of A
// other methods go here
};

当我想用它自己的 A 实例来修饰另一个类时,clone 方法就派上用场了,例如:

#include <memory>

class B {
private:
std::unique_ptr<A> a_ptr;
public:
// ctor
B(const A& a) {
a_ptr = std::unique_ptr<A>(a.clone());
//...
}
// copy ctor
B(const B& other) : B(*other.a_ptr) {}
};

我总是最终在 B 中实现复制构造函数以避免编译器错误(MSVC 给出了关于尝试引用已删除函数的模糊消息),因为唯一指针,这是完全有意义的。我的问题可以总结如下:

  1. 我真的需要 B 中的复制构造函数吗?也许有一个更好的模式可以让我完全避免它。

  2. 如果 1 是,我可以就此打住吗?我是否需要实现其他默认功能? IE。有没有我还需要默认构造函数和析构函数的场景?

在实践中,每当我觉得需要实现默认函数时,我通常会在其他三个函数的旁边实现一个移动构造函数;我通常使用 copy-and-swap 惯用语(根据 GManNickG's answer in this thread )。我认为这不会改变任何东西,但也许我错了!

非常感谢!

最佳答案

首先,我认为您的克隆函数的签名可能是

virtual std::unique_ptr<A> clone() = 0;

因为您想要 A 实例的深层拷贝和 B 中的独占所有权。其次,当您希望类可复制时,您确实必须为您的类定义一个复制构造函数。赋值运算符也是如此。这是因为 std::unique_ptr 是一个只能移动的类型,它阻碍了编译器生成默认实现。

不需要其他特殊的成员函数,尽管它们可能有意义。编译器不会为您生成移动构造函数和移动赋值运算符(因为您提供了自己的复制/赋值函数),但在您的情况下,您可以轻松 = default; 它们。析构函数同样可以用 = default; 定义,这符合 core guidelines .

请注意,通过 = default 定义析构函数应该在翻译单元中完成,因为 std::unique_ptr 需要在释放其资源时知道完整类型。

你是否需要默认构造函数完全取决于你想如何使用 B 类。

关于c++ - 唯一指针和 3 法则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51322684/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com