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

Posted

tags:

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

如果类中没有定义复制构造函数 那对象就不能作为形参?如题。。。。

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

答:如果参数是引用传递,则不会调用任何构造函数;如果是按值传递,则调用复制构造函数,按参数的值构造一个临时对象,这个临时对象仅仅在函数执行是存在,函数执行结束之后调用析构函数。

如果类中没有定义复制构造函数 那对象就不能作为形参?

答:如果没有定义,编译器会自动为你定义一个,编译器自己定义的复制构造函数是按类成员变量的值复制的。有几个成员变量就重新创建一个对象,那个对象的成员变量和被复制的对象其成员变量的值相同。这里如果成员变量有指针的时候,就会出现多个指针指向同一个对象的问题。
参考技术A 可以传引用或指针,但如果是按值传递的话,没有可用的复制构造函数就不行了。(不过如果类中没有复制构造函数,编译器会自动生成一个最简单的浅复制)

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++ 复制构造函数?

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

c++ 类的复制函数

类的复制控制

当我们将对象作为参数传递给方法时,为啥会调用复制构造函数?

拷贝构造函数