c++ - 除了声明构造函数私有(private)之外,还有其他禁止某个 C++ 类构造的方法吗?

标签 c++ construction

假设我有一个带有一些const reference 成员变量的类,我想禁止某种类型的构造。所以我会声明相应的构造函数私有(private)。当然,构造函数必须初始化类的所有const reference成员变量。然而,这样做会导致代码看起来很奇怪:

class A {
};

class B {
  B(const A& a): host(a) {}
private:
  B():host(A()) {}   // This is ugly and not needed !!
  const A& host;
};

除了将构造函数声明为私有(private)之外,还有其他方法可以禁止某种构造类型吗?我不想让编译器为我编写构造函数。

最佳答案

简单地不要定义这个:

B():host(A()) {}   // This is ugly and not needed !!

也就是说,下面应该做你想做的事:

class B {
  B(const A& a): host(a) {}
private:
  //B():host(A()) {}   // This is ugly and not needed !!
  const A& host;
};

这个想法是,如果您定义了一个带有参数的构造函数,那么默认构造函数就不会由编译器生成。这意味着,不能默认创建上述类的实例!

 B b1; //error - needs default constructor which doesn't exist!
 B b2(a); //ok - only way to create an instance!

C++11解决方案

在 C++11 中,您可以明确地告诉编译器不要生成特定的构造函数,如下所示:

struct B
{
     B(const A &a) {}

     B() = delete;      //disable
};

不仅如此。还有更多内容,如下所述:

现在是有趣的部分

您还可以有选择地禁用选定 类型的构造函数,这使得delete 更有趣。考虑一下,

struct A
{
       A (int) {}
};

不仅可以使用int 参数创建此类的对象,还可以使用隐式转换为int 的任何类型创建该对象。例如,

A a1(10);  //ok
A a2('x'); //ok - char can convert to int implicitly

B b; 
A a3(b); //ok - assume b provides user-defined conversion to int

现在假设,出于某种原因,我不希望 A 类的用户使用 charclass B 创建对象,幸运或不幸的是,它可以隐式转换为int,然后您可以将它们禁用为:

struct A
{
     A(int) {}
     A(char) = delete;      //disable
     A(const B&) = delete;  //disable
};

现在开始:

A a1(10);  //ok
A a2('x'); //error

B b; 
A a3(b); //error - assume (even if) b provides user-defined conversion to int

在线演示:http://ideone.com/EQl5R

错误信息非常清楚:

prog.cpp:9:5: error: deleted function 'A::A(char)'
prog.cpp:10:5: error: deleted function 'A::A(const B&)'

关于c++ - 除了声明构造函数私有(private)之外,还有其他禁止某个 C++ 类构造的方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7317530/

相关文章:

c++ - 越界访问数组不会出错,为什么?

c++ - 类构造函数和类成员变量的意外输出值

c++ - C++ 中用于对象构造的 ** 习语

java - 使用 Java 以编程方式生成 HTMLDocument

c++ - 利用容器的移动语义和元素初始化

c++ - 清空 C++ 对象

c++ - 使用 OpenMP 创建 FFTW 计划

C++: "error: expected ' ,' or ' .. .' before ' (' token"

c++ - 如何在 Visual Studio 2017 中使用 Qt 库?

c++ - 通过构造函数就地构造成员变量