首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >C++ -为什么这段代码在没有明显的构造函数匹配的情况下会编译呢?

C++ -为什么这段代码在没有明显的构造函数匹配的情况下会编译呢?
EN

Stack Overflow用户
提问于 2014-08-02 02:50:57
回答 2查看 127关注 0票数 2

请考虑以下代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Foo {
 public:
  explicit Foo(double) {}
};

Foo * test();
Foo * test() {
  return new Foo(Foo(1.0));   // (1)
}

我的问题与第(1)行有关。这非常类似于一个bug,我花了一些时间才找到它。我没有注意到由于复制/粘贴错误,该类型已经指定了两次。正确的行文显然是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  return new Foo(1.0);

有趣的是,这一更改似乎也没有编译警告:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  return new Foo(Foo(Foo(Foo(1.0))));

为什么这些示例编译时不带警告,即使使用-Wall -Weverything标志?为什么Foo::Foo(double)接受Foo的一个实例作为一个有效的double参数?这是运算符的一些特殊行为吗?

我的原始代码是在一个更大的上下文中,并且用两个基于LLVM-3的编译器进行了测试.都是在没有警告或错误情况下编译的。有了一种,代码实际上起了我预期的作用,事实上,有一段时间我没有意识到有一个bug。对于另一个实例,Foo实例的行为非常奇怪--我无法真正正确地描述它--就好像返回指针的稍后副本“神奇地”变成了与原始指针不同的值,从而导致两个协作对象之间的状态不匹配,这些对象应该持有指向共享Foo的等效指针,但由于某种原因,在分配后保持不同的值。在我明白这是怎么回事之前,这看起来真的很奇怪!

有趣的是,下面这两个编译器一起编译:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Foo { public: explicit Foo(double) {} };
class Bar { public: explicit Bar(double) {} };

Foo * testFoo() { return new Foo(Foo(1.0)); }
Bar * testBar() { return new Bar(Bar(1.0)); }

但以下版本没有:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Foo * testFooBar() { return new Foo(Bar(1.0)); }
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-08-02 02:55:05

编译器会自动生成一个复制构造函数Foo(const Foo&),可能还会根据确切的版本/设置Foo(Foo&&)移动构造函数。这与操作符new或任何指针魔术无关。您的代码只需调用编译器为您定义的完全正常的复制/移动构造函数即可。就这样。这种行为是标准规定的。一个不可复制的类(至少在标准的原始版本中)实际上是毫无价值的。

如果不希望自动生成副本构造函数,通常的技术是将它们定义为已删除或私有。

还请注意,在某些情况下,编译器有权从程序中实际删除整个对象,即使通常不应该。如果在Foo构造函数中使用指针到Foo设置了hijinks,则必须在所有构造函数和析构函数中严格处理它们,这意味着必须编写自己的复制/移动构造函数、析构函数和赋值运算符,否则编译器运行对象时将成为裁剪器。

票数 7
EN

Stack Overflow用户

发布于 2014-08-02 03:19:29

您正在观察的构造函数是复制构造函数。每个类都有一个副本构造函数。如果未在类定义中声明任何副本构造函数,则将隐式为您声明副本构造函数。

隐式声明的复制构造函数的特定签名取决于类定义,即基础和成员--通常是表单X::X(X const &),但必要时可以是X::X(X &)X::X(X volatile &)。异常规范尽可能严格。隐式声明的复制构造函数的定义通常由复制基和成员组成,但在某些情况下可以定义为删除(例如,如果您声明了一个移动构造函数)。

(在C++的未来版本中,如果声明副本或移动赋值运算符,则隐式声明的复制构造函数将被定义为“删除”。在C++11和C++14中,它是默认的。)

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

https://stackoverflow.com/questions/25094217

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文