Clang Tidy:调用复制构造函数以外的基构造函数
Clang-Tidy: Calling a base constructor other than the copy constructor
我从Clang Tidy收到以下消息:
Clang-Tidy: Calling a base constructor other than the copy constructor
代码是这样的:
#include <memory>
#include <set>
using namespace std;
class Node : enable_shared_from_this<Node>
{
public:
explicit Node(Node *parent = nullptr) : parent(parent) { parent->children.insert(shared_from_this()); }
Node(const Node &that) : parent(that.parent), children(that.children) {}
private:
Node *parent; // C++14 "weak pointer"
set<shared_ptr<Node>> children;
};
我在任何地方都找不到Clang Tidy关于这条消息的文档。
它意味着什么,为什么要给予它?
-Wextra
:下有类似的警告
<source>: In copy constructor 'Node::Node(const Node&)':
<source>:10:5: warning: base class 'class std::enable_shared_from_this<Node>' should be explicitly initialized in the copy constructor [-Wextra]
10 | Node(const Node &that) : parent(that.parent) { if (that.parent) that.parent->children.insert(shared_from_this()); }
| ^~~~
您应该在成员初始值设定项列表中显式使用复制构造函数:
Node(const Node &that) : enable_shared_from_this(that), parent(that.parent) { if (that.parent) that.parent->children.insert(shared_from_this()); }
但是,使用enable_shared_from_this
还有其他问题。首先,您必须始终公开继承该类:
class Node : public std::enable_shared_from_this<Node>
// ~~~~~~~~~~^
此外,当拥有的std::shared_ptr
尚未构造(尤其是在类构造函数中(时,不允许调用shared_from_this()
。在C++17中,这样做将抛出std::bad_weak_ptr
,在早期的标准版本中,这是未定义的行为。
在我看来,这个消息相对来说相当清晰,假设它专门指向复制构造函数。不过,它也可以通过提及有问题的基础来改进。
Node
继承了enable_shared_from_this<Node>
。您手动定义的复制构造函数在初始值设定项列表中没有提到这个基类。因此,基类将默认初始化。在复制构造函数中默认初始化基类或成员很可能不会产生预期效果,更可能是疏忽。这就是clang整洁产生诊断的原因。
在这种特殊情况下,enable_shared_from_this<Node>
被默认初始化没有问题,因为它的复制构造函数被定义为执行与其默认构造函数相同的操作。但这是一个罕见的例外。
通过正确初始化基础,您可以满足clang整洁并避免依赖这种特殊情况:
Node(const Node &that) : enable_shared_from_this(that), parent(that.parent) { /*...*/}
但是,这里有更严重的问题。首先,必须公开继承std::enable_shared_from_this
。您当前正在私下继承它。
其次,不能在构造函数中使用shared_from_this
。当构造函数运行时,正在构造的对象还没有处于std::shared_ptr
的控制之下。因此,调用shared_from_this
将简单地抛出std::bad_weak_ptr
(因为C++17;在此之前未定义的行为(。
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 当从函数参数中的临时值调用复制构造函数时
- 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数
- 使用复制构造函数复制双精度数组
- C 无可行的构造函数复制类型的变量
- 没有可行的构造函数复制类型 'MyString' 的数组元素
- 编译时,复制构造函数/复制分配和正常功能调用优化之间是否存在任何区别
- 如何最小化调用列表构造函数(复制构造函数)的次数?
- C 11矢量构造函数复制与范围
- 我定义了一个非复制构造函数;复制构造函数还会被隐式定义吗
- 可以将构造函数复制为转换运算符
- 将基类指针的构造函数复制到子类
- C++树类:构造函数/复制/内存泄漏
- 如何制作这个在模板构造函数复制中使用类型定义的类型的模板
- 将构造函数复制为模板化的成员函数
- 绕过私有复制构造函数/复制赋值C++
- C++通过构造函数复制对象
- 复制构造函数 - 复制C++中的对象
- 将带unique_ptr的类的构造函数复制到作为成员的抽象类