详解在C++中显式默认设置的函数和已删除的函数的方法
在 C++11 中,默认函数和已删除函数使你可以显式控制是否自动生成特殊成员函数。已删除的函数还可为您提供简单语言,以防止所有类型的函数(特殊成员函数和普通成员函数以及非成员函数)的参数中出现有问题的类型提升,这会导致意外的函数调用。
注意 此外,C++11 标准指定将以下附加规则:
这些规则的结果也可能泄漏到对象层次结构中。例如,如果基类因某种原因无法拥有可从派生类调用的默认构造函数 - 也就是说,一个不采用任何参数的 public 或 protected 构造函数 - 那么从基类派生的类将无法自动生成它自己的默认构造函数。 这些规则可能会使本应直接的内容、用户定义类型和常见 C++ 惯例的实现变得复杂 ― 例如,通过以私有方式复制构造函数和复制赋值运算符,而不定义它们,使用户定义类型不可复制。 struct noncopyable { noncopyable() {}; private: noncopyable(const noncopyable&); noncopyable& operator=(const noncopyable&); }; 在 C++11 之前,此代码段是不可复制的类型的惯例形式。但是,它具有几个问题: struct noncopyable { noncopyable() =default; noncopyable(const noncopyable&) =delete; noncopyable& operator=(const noncopyable&) =delete; }; 请注意如何解决与 C++11 之前的惯例有关的问题: struct widget { widget()=default; inline widget& operator=(const widget&); }; inline widget& widget::operator=(const widget&) =default; 请注意,只要特殊成员函数可内联,便可以在类主体外部默认设置它。 struct widget { // deleted operator new prevents widget from being dynamically allocated. void* operator new(std::size_t) = delete; }; 删除普通成员函数或非成员函数可阻止有问题的类型提升导致调用意外函数。这可发挥作用的原因是,已删除的函数仍参与重载决策,并提供比提升类型之后可能调用的函数更好的匹配。函数调用将解析为更具体的但可删除的函数,并会导致编译器错误。 // deleted overload prevents call through type promotion of float to double from succeeding. void call_with_true_double_only(float) =delete; void call_with_true_double_only(double param) { return; } 请注意,在前面的示例中,使用 call_with_true_double_only 参数调用 float 将导致编译器错误,但使用 call_with_true_double_only 参数调用 int 不会导致编译器错误;在 int 示例中,此参数将从 int 提升到 double,并成功调用函数的 double 版本,即使这可能并不是预期目的。若要确保使用非双精度参数对此函数进行的任何调用均会导致编译器错误,您可以声明已删除的函数的模板版本。 template < typename T > void call_with_true_double_only(T) =delete; //prevent call through type promotion of any T to double from succeeding. void call_with_true_double_only(double param) { return; } // also define for const double,double&,etc. as needed. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |