c++中用*this返回一个对象,会调用复制构造函数吗?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++中用*this返回一个对象,会调用复制构造函数吗?相关的知识,希望对你有一定的参考价值。

有这样一段代码:
#include <iostream>
using namespace std;
class num
public:
num()n=1;cout<<"构造函数执行\n";
num(int i)n=i;cout<<"带参数的构造函数执行\n";
num(const num&s)n=s.n;cout<<"复制构造函数执行\n";
~num()cout<<"析构函数执行\n";
int get()constreturn n;
void set(int x)n=x;
void add()++n;
const num &operator++()
++n;return *this;
const num operator++(int o)
num temp(*this);
++n;
return temp;
private:
int n;;
int main()
num i;
cout<<"i:"<<i.get()<<endl;
i.add();
cout<<"i:"<<i.get()<<endl;
num n=i++;
cout<<"i:"<<i.get()<<endl;
cout<<"n:"<<n.get()<<endl;
return 0;


执行结果:为什么复制构造函数值执行了一次?我认为应该是执行了两次才对啊!
我这样理解原因是;当*this返回时,返回源对象(对象执行自加后)时,会调用复制构造函数创建一个副本;当n=i++;时也会调用复制构造函数创建一个副本。
本人是菜鸟,希望大神指点迷津!!!!!!!!!!!!!!

三种情况下都会调用复制构造函数:

    作为函数的对象参数,进行传。当然,不能是引用类型的参数。

    对象作为函数的返回值,注意,返回的也不能是引用类型的。用*this返回一个对象,如果函数不是申明返回引用类型的对象,就会调用复制构造函数,这是对象在堆栈中传递的一个过程。

    用一个对象初始化另一个正在构造的对象。

==========================

你定义的复制构造函数被执行了两次,两次都发生在代码行

num n=i++;

const num operator++(int o)

    num temp(*this); <--这里用*this初始化temp
    ++n;
    return temp;     <--这里temp被返回时,会调用复制构造函数。

 这里的i和n的值都是通过复制构造函数来改变的,没有调用赋值函数。如果改成

num n; i++; n=i;

则变成了一次无参数构造,两次复制构造,一次赋值。 

i++; num n = i;

则有三次复制构造。

==================================================

你的

const num &operator++()

    ++n;
    return *this;

不会调用构造函数是,因为返回的是引用类型对象。

参考技术A 只有申请变量时才会调用构造函数,你上边重载运算符中
const num &operator++() //这个没有变量的申请
++n;return *this;
const num operator++(int o) //这个才有变量的申请.
num temp(*this);
++n;
return temp;
也是说++调用到第一个函数的话,是没有构造函数被调用的.
const num &operator++()

++n;
return *this;

const num operator++()

++n;
return *this;
两个函数是不同的. 一个返回地址,一个新变量 不加& 它是返回复制一个变量,就会调用回调函数,返回地址的则不会. 扯来扯去也是申请变量了就有回调,没申请就没得谈.
参考技术B 只有申请变量时才会调用构造函数,你上边重载运算符中
const num &operator++() //这个没有变量的申请
++n;return *this;
const num operator++(int o) //这个才有变量的申请.
num temp(*this);
++n;
return temp;
也是说你的++调用到第一个函数的话,是没有构造函数被调用的.追问

我问哈!这个问题:返回对象本身即 return *this;是否会调用构造函数呢?
我的意思是从:
const num &operator++()

++n;
return *this
;
到:
num n=i++;

复制构造函数被调用了几次?

追答

看来你理解还是不够深.
const num &operator++()

++n;
return *this;

const num operator++()

++n;
return *this;
两个函数是不同的. 一个返回地址,一个新变量 不加& 它是返回复制一个变量,就会调用回调函数,返回地址的则不会. 扯来扯去也是申请变量了就有回调,没申请就没得谈.

追问

谢谢你!我一直没注意到&符号,所以很纠结。多谢你的提醒。

本回答被提问者采纳

c++的复制构造函数

在C++中,下面三种对象需要调用拷贝构造函数(有时也称“复制构造函数”):
  1) 一个对象作为函数参数,以值传递的方式传入函数体;
  2) 一个对象作为函数返回值,以值传递的方式从函数返回;
  3) 一个对象用于给另外一个对象进行初始化(常称为赋值初始化);
  如果在前两种情况不使用拷贝构造函数的时候,就会导致一个指针指向已经被删除的内存空间。对于第三种情况来说,初始化和赋值的不同含义是拷贝构造函数调用的原因。事实上,拷贝构造函数是由普通构造函数和赋值操作符共同实现的。描述拷贝构造函数和赋值运算符的异同的参考资料有很多。
  通常的原则是:①对于凡是包含动态分配成员或包含指针成员的类都应该提供拷贝构造函数;②在提供拷贝构造函数的同时,还应该考虑重载"="赋值操作符号。

  拷贝构造函数,又称复制构造函数,是一种特殊的构造函数,它由编译器调用来完成一些基于同一类的其他对象的构建及初始化。其唯一的形参必须是引用,但并不限制为const,一般普遍的会加上const限制。此函数经常用在函数调用时用户定义类型的值传递及返回。拷贝构造函数要调用基类的拷贝构造函数和成员函数。如果可以的话,它将用常量方式调用,另外,也可以用非常量方式调用。

 

2.拷贝构造函数的参数必须使用引用,是为了避免拷贝构造函数无限制的递归下去。

以上是关于c++中用*this返回一个对象,会调用复制构造函数吗?的主要内容,如果未能解决你的问题,请参考以下文章

c++,类的对象作为形参时一定会调用复制构造函数吗?

C++返回值为对象时复制构造函数不执行怎么破

在哪些情况下调用 C++ 复制构造函数?

C++中复制构造函数被调用的三种情况

C++函数指针与成员函数指针

C++构造和析构