如何告诉编译器构造函数不是复制构造函数



我从GCC得到一个警告,基类应该在复制构造函数中初始化。问题是,我相信的本意是构造函数,而不是复制构造函数。下面是简化版本(我添加了初始化器Base()作为对警告的响应):

class Base { ... };
class Derived : public Base
{
  public:
    Derived(Derived& d, int x = 0)
      : Base(), m_b(d) { ... };
  protected:
    Base& m_b;
};

class Derived提供Base接口,它有一个Base成员。设计是这样的,数据可以从源流到接收器,中间有任意的中间对象可以转换或处理数据(任意的,但受接口约束)。

构造函数和复制构造函数之间的区别很重要。在构造函数的情况下,Base被默认初始化;在复制构造函数的情况下,Baserhs初始化。

是否足以使用默认构造基Base给编译器提示它是构造函数,而不是复制构造函数?

如果不是,我如何告诉编译器构造函数是而不是复制构造函数?我很高兴使用GCC扩展,比如__attribute__,来引导编译器朝正确的方向运行。

(另一个选项,更改签名,目前不能发生,因为它违反了大多数主要平台的版本控制要求,如Apple)。


有问题的文件如下:

  • asn.h
  • asn.cpp

下面是编译器的警告(为了简洁,已经删除了命名空间):

g++ -DDEBUG -g2 -O2 -Wall -Wextra -fPIC -march=native -pipe -c asn.cpp
asn.cpp: In copy constructor ‘DERGeneralEncoder::DERGeneralEncoder(DERGeneralEncoder&, byte)’:
asn.cpp:497:1: warning: base class ‘class ByteQueue’ should be explicitly initialized in the copy constructor [-Wextra]
 DERGeneralEncoder::DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag)

asn.cpp:497指向未修改的在线源代码中的第487行(第二个构造函数)。

系统是Fedora 22, x86_64,完整补丁,GCC 5.1.1:

$ uname -a
Linux localhost.localdomain 4.1.6-201.fc22.x86_64 #1 SMP Fri Sep 4 17:49:24 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
$ lsb_module
bash: lsb_module: command not found...
$ g++ --version
g++ (GCC) 5.1.1 20150618 (Red Hat 5.1.1-4)
...

在实际代码中,所讨论的构造函数复制构造函数,因为它可以用类类型的一个参数调用(因为第二个形参有默认实参)。注意,编译器甚至不会生成默认的复制构造函数,因为您提供了自己的复制构造函数。

因此,要使警告消失,只需显式初始化基类;编译器有权将其视为复制构造函数,您也应该这样做。

告诉编译器它是构造函数而不是复制构造函数的最好方法是什么?

由于复制构造函数,因此有两个选项:

  1. 破解编译器的源代码,使其误解你的源代码;
  2. 成为核心工作组的成员,并设法使在将来的c++标准版本中不再是复制构造函数。

最新更新