首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >错误:基类“A1”具有私有副本构造函数

错误:基类“A1”具有私有副本构造函数
EN

Stack Overflow用户
提问于 2016-06-23 10:04:33
回答 2查看 874关注 0票数 8

在windows平台上使用Clang3.7

见以下代码:

代码语言:javascript
复制
class A1
{
public:
    A1(char* name){}
    virtual ~A1() {}
private:
    A1(const A1&) {}
};

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

我得到以下错误:

代码语言:javascript
复制
 MyFile(31): 8: error: base class 'A1' has private copy constructor
         B1(): A1(""){}
               ^
 MyFile(25): 2: note: declared private here
         A1(const A1&) {}
         ^

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

这里发生何事?

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

代码语言:javascript
复制
A1(const char* name)

我没有收到任何错误,并且都按预期进行编译。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-06-23 10:21:06

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

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

出于任何原因,clang似乎更喜欢从string文字到A1的隐式转换,从而创建一个临时的,可以用于复制初始化,而不是直接从文字构造。这种行为会导致令人困惑的编译错误。

这两种选择都是错误的,而且clang对此发出了适当的警告:warning: ISO C++11 does not allow conversion from string literal to 'char *' [-Wwritable-strings]。如果您将标准模式设置为比c++11更早的模式(在这种情况下,程序将是格式良好的,即使它确实使用了不推荐的转换),程序也会编译。有趣的是,如果我们不允许转换,那么即使在当前的标准模式下,程序也会编译:

代码语言:javascript
复制
class A1
{
public:
    explicit A1(char* name){} // note the explicit
    virtual ~A1() {}
private:
    A1(const A1&) {}
};

G++的行为不同,您的程序编译得很好(当然有适当的警告)。在这方面,这两个汇编者似乎都遵守了标准。

故事的寓意:永远也要读警告。在这种情况下,警告是非常清楚的,并且很容易解决,而相同的错误间接地导致了一个错误,对解决错误没有帮助。

票数 3
EN

Stack Overflow用户

发布于 2016-06-23 10:17:58

我想,这只是诊断是如何产生的一个假象。

  • 首先,查找试图找到一个构造函数来匹配您的“调用”(它不是一个调用,而是其他什么)
  • 如你所知,服用char*的人不匹配
  • 唯一的另一个候选人是private
  • 编译器试图查看它是否可以从您的A1参数实例化临时""以使其工作。
  • 在这样做时,它所能找到的还是private构造函数。
  • 编译器决定在做任何其他事情之前抱怨这一点。

有人可能会说,这是一个执行质量问题。

有趣的是,GCC 6.1.0 (even in pedantic C++14 mode) compiles your code as originally written,只对断线的文字转换发出警告。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37988456

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档