什么是抽象类的编译器生成构造函数没有数据成员

时间:2015-07-22 18:29:01

标签: c++ constructor abstract-class language-lawyer static-analysis

我正在运行静态分析工具并收到错误,因为没有数据成员的抽象类没有构造函数。

给定一个没有数据成员的抽象类:

class My_Interface
{
  public:
    virtual void interface_function(void) = 0;
};
  1. 是否由编译器生成任何构造函数?
  2. 如果生成构造函数,它的内容是什么?
  3. 如果生成了构造函数,它是否会被a消除 优化级别?
  4. 静态分析中的规则文档说:
    如果你没有在类中编写至少一个构造函数,编译器将会 默认情况下为您编写公共构造函数。此规则检测您是否 不要声明至少一个构造函数。

    规则文档引用了Scott Meyers," Effective C ++:55改进程序和设计的具体方法",第三版。

    我的理解是编译器不会为上述情况生成构造函数。

    编辑1:
    这不是许多构造函数问题的重复,因为:

    1. 这个没有数据成员。
    2. 这不是在询问是否需要构造函数,而是会发生什么 何时未提供构造函数。
    3. 这是C ++语言。

3 个答案:

答案 0 :(得分:1)

即使在这种情况下,编译器至少理论上也会合成一个构造函数。即使您无法创建此类的实例,也会在创建派生类的过程中调用构造函数(覆盖interface_function,因此可以实例化)。

鉴于这基本上是一个纯粹的接口类,构造函数可能不会做任何事情,所以大多数编译器可能会优化它(很可能甚至当你不告诉它优化代码时)

答案 1 :(得分:0)

  
      
  1. 是否由编译器生成任何构造函数?
  2.   

是。一些。首先,来自[class.ctor]:

  

类X的默认构造函数是类X的构造函数,它没有参数或者每个都没有   不是函数参数包的参数具有默认参数。如果没有用户声明的构造函数   对于类X,没有参数的非显式构造函数被隐式声明为默认值(8.4)。   隐式声明的默认构造函数是其类的内联公共成员。违约默认值   如果出现以下情况,则将类X的构造函数定义为已删除:

以下是几个要点,但都不适用。所以我们有相同的:

My_Interface() = default;

然后,从[class.copy]:

  

如果类定义没有显式声明复制构造函数,则隐式声明非显式构造函数。如果类定义声明了移动构造函数或移动赋值运算符,则隐式声明的副本   构造函数定义为已删除;否则,它被定义为默认值(8.4)。

所以我们有:

My_Interface(const My_Interface&) = default;

此外:

  

如果类X的定义没有显式声明移动构造函数,则隐式地使用非显式构造函数   宣布为违约,当且仅当如此   (9.1) - X没有用户声明的拷贝构造函数,
  (9.2) - X没有用户声明的复制赋值运算符,
  (9.3) - X没有用户声明的移动赋值运算符,和
  (9.4) - X没有用户声明的析构函数。

所以我们也有:

My_Interface(My_Interface&& ) = default;
  
      
  1. 如果生成了构造函数,它的内容是什么?
  2.   

生成所有三个,这三个都是= default;

  
      
  1. 如果生成了构造函数,是否会被优化级别消除?
  2.   

三个构造函数都不是琐事,因为My_Interface具有虚函数。因此,至少需要初始化/复制vtable。因此即使没有任何成员初始化/复制/移动,某些也必须发生。

答案 2 :(得分:0)

Q1。是否由编译器生成任何构造函数?

答案:是的。从C ++ 11标准:

  

12.1构造函数

     

5类X默认构造函数是类X的构造函数,可以在不带参数的情况下调用。如果   对于类X没有用户声明的构造函数,隐式声明了没有参数的构造函数   违约(8.4)。隐式声明的默认构造函数是其类的inline public成员。

我在标准中没有看到任何回答其他两个问题的内容。但是,在您的情况下,由于存在virtual成员函数,因此默认构造函数必须至少设置对象的虚拟表。