当我定义一个具有该类的非引用返回类型的函数时,哪一个类的默认或复制构造函数被调用?

问题描述:

我很困惑,为什么我必须编写这个类的拷贝构造函数,当我在第一个提到的类的返回类型中定义一个函数在另一个类中时。当我定义一个具有该类的非引用返回类型的函数时,哪一个类的默认或复制构造函数被调用?

例如:

class Foo{ 
    // attributes 
public: 
    Foo(){...} 

    // I had to write the CC 
    Foo(const Foo& obj){ 
     //... 
    } 
} 

class Bar{ 
// .... 

// This is the function 
Foo SomeFunction() 
{ 
    Foo myVar; 

    // .... 

    return myVar; 
} 

我检查了由荷兰国际集团cout的拷贝构造函数实际上是被调用。

我需要确认,因为在这种情况下调用默认的构造函数似乎更符合逻辑,就像在创建myVar的这一行中一样。

我是初学者,所以我试图围绕这些调用包围我的头。

+1

'myVar'是函数内部的局部变量,它需要被复制到外部变量。 – songyuanyao

+0

@songyuanyao所以复制构造函数在复制时被调用? – developer10

+0

是的,通过复制ctor或复制分配。 – songyuanyao

线

Foo myFunc; 

调用默认的构造函数。

线

return myFunc; 

调用拷贝构造函数,因为函数的返回类型是Foo。从函数返回的对象不是myFunc,而是myFunc的副本。当函数返回时,myFunc被删除。副本是调用函数获取的内容。

如果编译器能够使用RVO(return value optimization),那么将myFunc返回给调用函数,而不是副本。在这种情况下,复制构造函数将不会被调用。

+1

中实际存在复制操作,具体取决于编译器的优化功能,如果应用NRVO,return语句实际上也可以调用移动构造函数。 –

+1

@TheParamagneticCroissant,一般的好点。对于这个特定的情况,隐式声明的移动构造函数被删除,因为OP有一个拷贝构造函数,至少这是我的理解。 –

+0

是的,我不想挑剔,只是增加了这一点,因为OP可能有兴趣知道,如果他/他未来遇到可移动类型。 –

您不必在C++上编写CC。编译器应该给你一个。 是的,在这种情况下将调用CC,因为您试图将返回值作为副本传递。

+0

默认的cc在这种情况下不起作用,因为我必须有一些指针被初始化。 – developer10

+0

你不应该低估这一点,因为你没有展示完整的类实现,我说的完全是真实的。如果你的类有没有定义CC的属性,那就是你在使用一个属性时需要指定的属性。 – Bhupesh

+0

不是我低估了你的答案。 – developer10