C++构造函数、拷贝构造函数、赋值运算符漫谈(一)——函数参数传递

简介:

在讨论C++函数参数之前,我们先来看一下C程序是如何调用函数的。

 

如图,为C语言的函数调用记录,C++也类似。当有如下函数:

void fooX x0);

如果有如下调用方式:

X xx;

foo(xx);

    编译器(对于C)会将实参xx以“位逐次拷贝”方式复制给形参x0(注:X0即在上图函数活动记录中的参数位置)。在C++中,如果一个Class也展现了“位逐次拷贝语义”【1】,且用户没有定义拷贝构造函数,那么编译器按照这种方式进行拷贝没有问题。但是当一个Class不展现“位逐次拷贝语义”的情况(四种),或者用户定义了拷贝构造函数呢?这种情况编译器必须采用一定措施避免这种直接位拷贝的发生(否则拷贝构造函数将不能发生作用)。C++编译器是这样做的:

     调用函数前,先引入一个X的临时变量temp,并以实参xx为参数调用拷贝构造函数(这由编译器安插代码完成)。如:

X temp(此处不调用构造函数,只分配空间)

temp.X::X(xx);(这两行代码是由编译器插入)

    之后怎么办呢?如果直接foo(temp),问题又回到之前了,因为只是相当于temp变成了实参,实参到形参x0的拷贝依然是“位逐次拷贝”。所以C++编译器必须做第二个转化,修改函数foo的声明,将其修改为:

void foo(X& x0);

即函数参数变为引用,传入的将是temp的地址。

测试:

class X
{
public:
X()
{cout<<"X()"<<endl;};
X(const X& x)
{
  cout<<"X(const X& x)"<<endl;
}
X& operator=(const X&)
{
   cout<<"="<<endl;
}
~X()
{cout<<"destructor"<<endl;}
};
void foo(X x0)
{
}
int _tmain(int argc, _TCHAR* argv[])
{
X xx;
foo(xx);
}


运行结果:

 

可以看出函数参数的传入需要调用拷贝构造函数构建一个临时对象(注:并不是构建形参,形参已经被转化为引用,不再是对象),另外临时对象在函数退出时销毁。

总结:函数形参中,对象值传递的方式都转化为临时对象和引用传递。

【1】一个类不展现“位逐次拷贝”的四种情况:

(1) 这个类有member object,并且这个member object对应的Class定义了拷贝构造函数。

(2) 这个类的父类定义了拷贝构造函数。

(3) 这个类中有虚函数(包括其父类有的情况)。

 (4)这个类的继承连中有虚基类。

目录
相关文章
|
5天前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
27 5
|
11天前
|
存储 编译器 C++
【c++】类和对象(中)(构造函数、析构函数、拷贝构造、赋值重载)
本文深入探讨了C++类的默认成员函数,包括构造函数、析构函数、拷贝构造函数和赋值重载。构造函数用于对象的初始化,析构函数用于对象销毁时的资源清理,拷贝构造函数用于对象的拷贝,赋值重载用于已存在对象的赋值。文章详细介绍了每个函数的特点、使用方法及注意事项,并提供了代码示例。这些默认成员函数确保了资源的正确管理和对象状态的维护。
40 4
|
1月前
|
C++
C++构造函数初始化类对象
C++构造函数初始化类对象
21 0
|
1月前
|
C++
C++入门4——类与对象3-2(构造函数的类型转换和友元详解)
C++入门4——类与对象3-2(构造函数的类型转换和友元详解)
21 0
|
13天前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
36 4
|
1月前
|
存储 编译器 对象存储
【C++打怪之路Lv5】-- 类和对象(下)
【C++打怪之路Lv5】-- 类和对象(下)
27 4
|
1月前
|
编译器 C语言 C++
【C++打怪之路Lv4】-- 类和对象(中)
【C++打怪之路Lv4】-- 类和对象(中)
24 4
|
1月前
|
存储 安全 C++
【C++打怪之路Lv8】-- string类
【C++打怪之路Lv8】-- string类
22 1
|
1月前
|
存储 编译器 C++
【C++类和对象(下)】——我与C++的不解之缘(五)
【C++类和对象(下)】——我与C++的不解之缘(五)
|
1月前
|
编译器 C++
【C++类和对象(中)】—— 我与C++的不解之缘(四)
【C++类和对象(中)】—— 我与C++的不解之缘(四)