首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >隐式转换返回时是否需要复制构造函数?

隐式转换返回时是否需要复制构造函数?
EN

Stack Overflow用户
提问于 2014-06-16 07:43:32
回答 3查看 1.9K关注 0票数 22

下面的代码在Visual C++ 2013中编译得很好,但不是在GCC或Clang下编译的。

哪个是对的?

通过隐式转换返回对象时是否需要可访问的复制构造函数?

代码语言:javascript
复制
class Noncopyable
{
    Noncopyable(Noncopyable const &);
public:
    Noncopyable(int = 0) { }
};

Noncopyable foo() { return 0; }

int main()
{
    foo();
    return 0;
}

GCC:

代码语言:javascript
复制
error: 'Noncopyable::Noncopyable(const Noncopyable&)' is private
  Noncopyable(Noncopyable const &);
  ^
error: within this context
 Noncopyable foo() { return 0; }

嘎吱声:

代码语言:javascript
复制
error: calling a private constructor of class 'Noncopyable'
Noncopyable foo() { return 0; }
                    ^
note: implicitly declared private here
        Noncopyable(Noncopyable const &);
        ^
warning: C++98 requires an accessible copy constructor for class 'Noncopyable' when binding a reference to a temporary; was private [-Wbind-to-temporary-copy]
Noncopyable foo() { return 0; }
                           ^
note: implicitly declared private here
        Noncopyable(Noncopyable const &);
        ^
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-06-16 08:10:57

当您创建一个表达式时,会创建一个返回类型的临时对象,并使用该表达式初始化该对象,然后将该对象(如果不是return选项)移到返回值中。因此,您需要一个可访问的副本或移动构造函数。

但是,可以使用带括号的列表直接初始化返回值。因此,以下工作:

代码语言:javascript
复制
Noncopyable foo() { return {0}; }

实例化中也有类似的情况。

票数 15
EN

Stack Overflow用户

发布于 2014-06-16 08:00:46

12.8复制和移动类对象class.copy

1/ 类对象可以通过两种方式复制或移动:通过初始化(12.1,8.5),包括函数参数传递(5.2.2)和函数值返回的 (6.6.3); .

6.6.3中,返回语句stmt.return

2/ .表达式的值被隐式转换为其出现的函数的返回类型。返回语句可以涉及临时对象 (12.2)的构造和复制或移动

和12.2临时对象class.temporary

1/ 类类型的临时程序是在不同的上下文中创建的:绑定到prvalue的引用(8.5.3),返回prvalue的 (6.6.3),创建prvalue的转换(4.1,5.2.9,5.2.11,5.4),.注意:即使没有调用析构函数或复制/移动构造函数,也应满足所有语义限制,例如可访问性(第11条)和函数是否被删除(8.4.3)。..。

我认为GCC和clang是正确的--我甚至会说,只要您按值返回,返回类型就必须有一个可访问的副本或移动构造函数。

逻辑是创建一个临时类型以将原始类型转换为新类型(intNoncopyable),然后创建该临时类型的副本以返回函数。

它本质上与以下内容相同:

代码语言:javascript
复制
Noncopyable foo() { return Noncopyable(0); }

你希望那里需要一份副本吗?我当然会的。

票数 5
EN

Stack Overflow用户

发布于 2014-06-16 08:11:08

  • 函数foo按值返回Noncopyable对象。因此,从理论上讲,必须调用副本构造函数。
  • 如果您使复制构造函数可用(即public)并打印一条消息来标记它的唤起,您将看到该消息没有打印演示,并且只会引发重载的转换操作符。
  • 这是由于复制优化的事实。
  • 因此,不是重载的转换操作符需要一个复制构造函数,而是foo的返回语句需要一个副本构造函数,因为您按值返回。
  • 最终,复制构造函数不会因为复制省略而被调用,但仍然必须可用。
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24238786

复制
相关文章

相似问题

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