这就是声明构造函数private和声明=delete之间的区别
Which is the difference between declaring a constructor private and =delete?
例如,我想声明一个类,但我希望客户端不能使用复制构造函数(或复制赋值操作符)
下面两个都不允许使用复制构造函数:
1。
class Track
{
public:
Track(){};
~Track(){};
private:
Track(const Track&){};
};
2。
class Track
{
public:
Track(){};
~Track(){};
Track(const Track&)=delete;
};
其中一种方法比另一种方法"更正确"还是相等?有什么副作用吗?
//Does not compile with both the above ways
int main()
{
Track l;
Track p(l);
}
将其设为私有是"老"的做法。构造函数仍然存在,但它是私有的,并且只能从另一个类成员函数中调用。
= delete
删除构造函数。它不是由编译器生成的,它根本不存在。
所以最有可能,= delete
是你想要的。(不过需要注意的是,并非所有编译器都支持这种语法,所以如果考虑可移植性…)
声明复制构造函数private
仍然允许Track
类的成员函数复制构造该类的实例,而删除它只是禁止复制构造该对象。
在c++ 11中,删除复制构造函数是表达类不可复制这一事实的正确方式(当然,除非您让Track
的成员函数或Track
的友元函数复制构造Track
对象)。
将构造函数设为私有基本上是旧c++中的一个"hack",因为这是阻止用户使用它们的唯一方法。delete
特殊成员函数的功能仅在c++ 11中引入,这是表示类不可复制的更好、更惯用的方式。由于意图是明确的。
私有构造函数除了完全禁止使用之外还有其他用途(例如,它们可以被静态类成员函数调用)。因此,仅仅将构造函数设为私有并不能很好地传达意图,并且产生的错误也不是很清楚。
您的第一个解决方案向读者传达了复制构造函数是私有的,不能使用。第二个解决方案只在c++ 11中有效。正因为如此,我认为更易于移植和可读的实现将是您的第一个,使用私有属性。
在第一种情况下,您实质上是声明一个私有复制构造函数,然后不提供任何实现。通过将它们声明为private,非成员就不能复制它。
在第二种情况下,语法禁止复制。这是c++原生的。
对于程序员来说,主要的区别在于可读性和对代码的理解。第一种情况是多余的,为什么要声明复制构造函数,使其私有,而不实现它。客户端必须在这里推断很多。
你可以直接使用"= delete",并清楚地表明你想要做什么
第一种方法并不能阻止类自身复制自身。解决这个问题的传统方法是将复制构造函数声明为private 和,使其不被实现。
然而,这样做的一个问题是意图可能不明显。阅读代码的人可能不理解为什么存在孤立声明,并可能错误地删除它。注释可以提供帮助,如果Boost对您可用,则可以私下继承boost::noncopyable
。
如果使用c++ 11,请使用delete
。原因是它使调用显式和意图清晰。你仍然可以意外地使用私有构造函数(例如,在一组受限的作用域中),但编译器将禁止你使用已删除的构造函数。
如果你的必要的工具链不支持删除的构造函数(= delete
),你不应该定义它(如在你的问题中看到的)——只有声明它,并保持它未定义,例如:private: n Track(const Track&);
- 在.cpp文件之间传递结构声明,而不使用全局头文件
- 在"template"和函数声明之间使用:template<typename trait> using tr = base_trait<trait> void fn(tr::t
- 使用 enable_if 在按值传递与按引用传递之间更改函数声明
- 如何声明不同类型的模板化类之间的转换
- 类型测试对象的动态数组的这两个声明之间的区别?
- C++ 中的类之间的数据重新循环 - 错误:'<class name>'未在此范围内声明
- 重复符号 --- 定义和声明之间的差异
- 以下声明之间的区别
- 一条线和两行声明之间的差异
- 恒定声明全局或在使用它的函数中声明恒定声明之间有什么区别?
- 在构造函数中创建数组与在 C++ 中创建声明之间的区别
- 以下声明之间的区别是什么
- 以下声明之间的区别
- pimpl 最终用户的全局远向声明与私有远向声明之间的区别
- C++中include指令和forward声明之间的区别
- 这两个与灰泥相关的声明之间有区别吗
- 2D矢量声明之间的区别
- c++0x:解决函数定义后接空声明和简单声明之间的歧义
- 带有 extern 和没有 extern 的函数的本地/块范围声明之间的区别
- C中的这些声明之间有什么区别