错误:基类' A1'有私人复制构造函数

时间:2016-06-23 10:04:33

标签: c++ c++11 clang copy-constructor

在Windows平台上使用Clang 3.7

请参阅以下代码:

class A1
{
public:
    A1(char* name){}
    virtual ~A1() {}
private:
    A1(const A1&) {}
};

class B1 : public A1
{
public:
    B1(): A1(""){}
};

我收到以下错误:

 MyFile(31): 8: error: base class 'A1' has private copy constructor
         B1(): A1(""){}
               ^
 MyFile(25): 2: note: declared private here
         A1(const A1&) {}
         ^

使A1复制构造函数公开,消除错误!

这里发生了什么?

注意:通过改变(我应该)

A1(const char* name)

我没有错误,所有编译都按预期编译

2 个答案:

答案 0 :(得分:6)

我想这只是生成诊断的假象。

  • 首先,查找尝试查找与您的"调用"匹配的构造函数。 (这不是电话,而是其他什么)
  • 如您所知,char*private不匹配
  • 唯一的其他候选人是A1
  • 编译器尝试查看是否可以从""参数中实例化临时private以使其正常工作
  • 这样做,它所能找到的只是$timeout(queryCallback, 100, false);构造函数
  • 在做其他任何事情之前,编译器决定抱怨

一个可能认为这是一个执行质量问题。

有趣的是,GCC 6.1.0 (even in pedantic C++14 mode) compiles your code as originally written只吐出了破坏的字面转换的警告。

答案 1 :(得分:3)

您不能使用字符串文字调用构造函数Categories,因为字符串文字不能转换为A1(char* name)(这种弃用的转换确实存在于c ++ 11之前)。或者更确切地说,一个调用构造函数的程序格式不正确,并允许实现拒绝编译。

因此,重载决策寻找其他替代方案。具有相同数量参数的唯一其他可能的替代方案是复制构造函数。

无论出于何种原因,clang似乎更喜欢从字符串文字到char*的隐式转换,从而创建一个临时的,可用于复制初始化,而不是使用文字的直接构造。此行为导致令人困惑的编译错误。

两种选择都是格式不正确的,并且铿锵有力地警告它:A1。如果你将标准模式设置为早于c ++ 11(在这种情况下,程序将是格式良好的,即使它确实使用了不推荐的转换),程序也会编译。有趣的是,如果我们不允许转换,那么即使在当前的标准模式下,程序也会编译:

warning: ISO C++11 does not allow conversion from string literal to 'char *' [-Wwritable-strings]

G ++表现不同,你的程序编译得很好(当然还有适当的警告)。两个编译器似乎都符合这方面的标准。

故事的道德:总是阅读警告。在这种情况下,警告非常清楚,并且易于解决,而同一个错误间接导致错误,这对于解决错误没有帮助。