如果您必须将某个const
类型实例的引用存储B
到您的类A
中,那么您肯定希望确保A
实例的生命周期将超过B
实例的生命周期:
B b{};
A a1{b}; // allowed
A a2{B{}}; // should be denied
B const f() { return B{}; } // const result type may make sense for user-defined types
A a3{f()}; // should also be denied!
为了使它成为可能,您应该显式地对= delete;
所有可以接受右值(const &&
和&&
)的构造函数重载。为此,您应该只= delete;
使用const &&
构造函数的版本。
struct B {};
struct A
{
B const & b;
A(B const & bb) : b(bb) { ; } // accepts only `B const &` and `B &`
A(B const &&) = delete; // prohibits both `B &&` and `B const &&`
};
这种方法允许您禁止向构造函数传递各种右值。
这也适用于内置标量。例如double const f() { return 0.01; }
,虽然它会导致如下警告:
警告:返回类型上的 'const' 类型限定符无效 [-Wignored-qualifiers]
如果您只是构造函数的版本,它仍然可以= delete;
生效&&
:
struct A
{
double const & eps;
A(double const & e) : eps(e) {} // binds to `double const &`, `double &` AND ! `double const &&`
A(double &&) = delete; // prohibit to binding only to `double &&`, but not to `double const &&`
};
double const get_eps() { return 0.01; }
A a{0.01}; // hard error
A a{get_eps()}; // no hard error, but it is wrong!
对于非转换构造函数(即非一元),存在一个问题:您可能必须为= delete;
构造函数的所有可能组合版本提供 -d 版本,如下所示:
struct A
{
A(B const &, C const &) {}
A(B const &&, C const &&) = delete;
// and also!
A(B const &, C const &&) = delete;
A(B const &&, C const &) = delete;
};
禁止混合情况,例如:
B b{};
A a{b, C{}};