【问题标题】:Copy constructor is called when returning object from a function?从函数返回对象时调用复制构造函数?
【发布时间】:2017-05-12 16:36:42
【问题描述】:

我已经读过“复制对象以从函数中返回它”时调用复制构造函数。

所以我知道每当我们返回一个对象时都会调用复制构造函数,我的理解是否正确?

如果是,那么每当我们返回一个对象时,都会调用构造函数。因此,如果我们在程序的中间,将调用复制构造函数。然后将值分配给类的数据成员。那么现有的值会被替换吗?

如果不是,这句话是什么意思?

SRC:Tutorial point

 #include <iostream>

 using namespace std;

 class demo
 {
    public:
         int rate;
         demo(int init_rate);
         demo( const demo &obj_passed);
         demo display();
 };


 demo::demo(int init_rate)
 {
    cout << "\nNormal Construtor" << endl;
    rate=init_rate;
 }

 demo::demo(const demo &obj_passed) // Copy Constructor
 {
    cout << "\nCopy constructor" << endl;
    rate=obj_passed.rate;
 }

 demo demo::display()
 {
    demo temp(10);
    temp.rate=45;
    return temp; //copy constructor is not called here
     }

 int main( )
 {
          demo obj1=obj1.display(); 
          return 0;
 }

输出是

Normal Constructor

【问题讨论】:

标签: c++


【解决方案1】:

假设 T 是对象的类型,所以我们有一个函数:

T foo() {
    T returnvalue;
    // do some stuff to the return value
    return returnvalue;
}

还有一些调用它的代码:

T t = foo();

那么returnvalue 是函数foo 的局部对象。 t 是调用 foo 的函数的本地对象。最后,“foo的返回值”是一个临时对象。这三个对象的类型都是T

名义上,returnvalue被复制到临时对象,然后临时对象被复制到t,所以复制构造函数可以被调用两次。这就是你的参考在说什么。不替换任何值,调用复制构造函数以将一个对象初始化为另一个相同类型的单独对象的副本。

然而,当返回一个对象时,它并不像复制构造函数总是那么简单。在这个例子中,允许 C++ 实现通过一种称为“复制构造省略”的机制进行优化,其中它实际上对所有三个对象使用相同的位置,并且简单地省略了复制。因此,在此代码的实践中,您可能会看到复制构造函数被调用了 0、1 或 2 次。

这是针对 C++03 的。在 C++11 中,在某些情况下(同样,我的示例就是其中之一)移动构造函数优先于复制构造函数被调用。因此,在 C++11 中,如果 T 具有移动构造函数,则保证不会调用复制构造函数。同样,这些移动符合省略的条件,因此您可能会看到其中的 0、1 或 2 个。

【讨论】:

  • 在我的代码中没有调用复制构造函数...我犯了什么错误
【解决方案2】:

您似乎对复制构造函数的含义感到困惑。复制构造函数用于创建 new 对象。所以复制构造函数不会替换任何值,它会将旧值复制到新对象。

【讨论】:

    【解决方案3】:

    当你返回一个函数的本地对象时,编译器倾向于保留本地对象并将其重定向到你返回的地方(所以本地对象不会被删除,编译器不需要创建另一个对象来复制细节本地对象。) 在语句完成(;) 之后,本地对象被删除。 另一方面,如果你返回一个形参,编译器会复制对应的参数(带有复制构造函数),然后返回参数的克隆。

    【讨论】:

      猜你喜欢
      • 2010-10-14
      • 2016-10-10
      • 2019-08-12
      • 1970-01-01
      • 2013-12-08
      • 1970-01-01
      • 2017-02-08
      • 2013-10-03
      • 2016-08-12
      相关资源
      最近更新 更多