ved*_*edg 19 c++ destructor c++11
自从C++ 11默认生成复制构造函数和复制赋值运算符(存在用户定义的析构函数)时,我遇到了一个问题.
对于大多数足够简单的类,默认生成的构造函数,运算符和析构函数都可以.请考虑以下原因来声明析构函数:
在基类中创建虚拟析构函数虚拟:
// header
class Base1 { public: virtual ~Base1() = default; };
class Base2 { public: virtual ~Base2(); };
// source
Base2::~Base2() = default;
Run Code Online (Sandbox Code Playgroud)
在这些情况下,编译器是否会生成4个复制和移动特殊方法?如果是,那么我认为它很好,没有必要复杂化Base1或Base2.
在析构函数中打印调试消息:
// header
class D { public: ~D(); };
// source
D::~D() {
#ifdef DEBUG_THIS
std::cout << "D was destructed." << std::endl;
#endif
}
Run Code Online (Sandbox Code Playgroud)
我相信在这种情况下会生成复制构造函数和赋值运算符; 但移动构造函数和赋值运算符不会.我想避免使用已弃用的默认生成和禁用复制D.我还想避免D4次deleted声明泛滥.是否仅禁用一个复制构造函数?这是一种好风格吗?
qua*_*dev 17
使用C++ 11,一种干净的方法是遵循boost中使用的模式(参见此处)
您基本上创建了一个基类,其中复制构造函数和复制赋值被删除,并继承它:
class non_copyable
{
protected:
non_copyable() = default;
~non_copyable() = default;
non_copyable(non_copyable const &) = delete;
void operator=(non_copyable const &x) = delete;
};
class MyClass: public non_copyable
{
...
}
Run Code Online (Sandbox Code Playgroud)
M.M*_*M.M 12
删除复制构造函数和复制赋值运算符是禁用复制的最简单,最清晰的方法:
class X
{
X(X const &) = delete;
void operator=(X const &x) = delete;
};
Run Code Online (Sandbox Code Playgroud)
我不会在问题正文中跟随你所说的虚拟析构函数.这听起来像是在寻找一种方法来让你的代码占用较少的源代码字符,但对于任何看到它的人来说也更加神秘.
如果删除的功能列表困扰你,你可以将它隐藏在宏后面,我猜.
#define NON_COPYABLE_NOR_MOVABLE(T) \
T(T const &) = delete; \
void operator=(T const &t) = delete; \
T(T &&) = delete;
Run Code Online (Sandbox Code Playgroud)
当析构函数被明确默认时,将只生成复制构造函数和复制赋值运算符.即便如此,他们这一代人也被弃用了.因此,为了拥有虚拟析构函数和所有默认方法,应该编写以下内容:
struct Base
{
Base()=default;
virtual ~Base() = default;
Base(const Base&)=default;
Base& operator=(const Base&)=default;
Base(Base&&)=default;
Base& operator=(Base&&)=default;
};
Run Code Online (Sandbox Code Playgroud)
我肯定会为一个以上的Base类使用一个宏.
在用户定义析构函数的情况下,仍然会生成2种特殊方法.有以下方法可以禁用已弃用的生成复制构造函数和复制赋值运算符:
删除移动构造函数或移动赋值运算符(不是很明显但非常简短):
Base(Base&&)=delete; // shorter than deleting assignment operator
Run Code Online (Sandbox Code Playgroud)删除这两个拷贝构造函数和拷贝赋值运算符:
Base(const Base&)=delete;
Base& operator=(const Base&)=delete;
Run Code Online (Sandbox Code Playgroud)请注意,如果需要,您必须显式声明默认构造函数,例如Base()=default;.
宏或继承特殊类也可以用于此目的,但我个人更喜欢删除移动构造函数来实现我自己的宏或基类.当使用Qt或boost时,我更愿意Q_DISABLE_COPY(Base)和继承boost::noncopyable,因为它们已经实现,广为人知和可识别.
http://accu.org/index.php/journals/1896 - 这些问题的详细解释和理由.
| 归档时间: |
|
| 查看次数: |
14519 次 |
| 最近记录: |