C++学习-类对象的复制控制(5)

本文深入探讨了C++中对象复制控制的概念,包括复制构造函数、赋值操作符及析构函数的作用,并通过实例展示了如何禁止对象的复制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

作者:gzshun. 原创作品,转载请标明出处!
来源:http://blog.youkuaiyun.com/gzshun


前面学习了构造函数的用法与初始化列表的特性,本章还是学习构造函数的内容。类型还能控制复制、赋值或撤销该类型的对象,这时候,类通过特殊的成员函数:复制构造函数、赋值操作符和析构函数来控制这些行为。这些都属于类对象的复制控制,挺重要的一部分内容。


一、本文内容的应用

1.复制构造函数的例子:
string str1("hello");
string str2(str1);
2.赋值操作符的例子:
string str1("hello");
string str2 = str1;

二、复制构造函数的应用于哪些地方
什么样的函数才是复制构造函数?
只有单个形参,而且该形参是对本类类型对象的引用(常用const修饰)。
复制构造函数用于:
1.用一个同类型的对象显示或隐式初始化一个对象。
eg:
string str1("hello");
string str2(str1);
2.作为函数的实参
eg:
void Show(string str);
...
string str1("hello");
Show(str1); //存在一个复制操作,将str1对象隐式复制到Show函数的临时对象


3.作为函数的返回值

eg:
string getString() const
{
string str("hello");
...
return str;
}
...
string str1 = getString(); //将getString函数的返回值的string对象复制到str1对象


4.初始化顺序容器的元素

eg:
vector<string> vec(5); //声明了一个vector,包含5个string对象;
//编译器首先使用string默认构造函数创建一个临时对象来初始化vec,然后使用复制构造函数将临时值复制到vec的每个元素中。


5.根据元素初始化式列表初始化数组元素

这里要强调的是:初始化式列表
a.每个元素调用一次默认构造函数
string str[10]; //调用了10次默认构造函数
b.每个元素调用一次复制构造函数
string str1, str2, str3, str4;
string str[] = { str1, str2, str3, str4};

三、合成的复制构造函数和合成的赋值操作符
如果用户没有显示的定义复制构造函数或赋值操作符,编译器将会默认的合成一个复制构造函数。复制构造函数与合成复制构造函数,或者赋值操作符与合成赋值操作符不同,编译器默认合成的函数的行为是"逐个成员初始化",将新对象初始化为原对象的副本。逐个成员初始化不包括static成员,只负责初始化非static成员。

四、小试牛刀

这里编写一个最简单的例子,来展示一下类对象的复制控制。

#include <iostream> using namespace std; class CObj { public: CObj() { cout << "默认构造函数" << endl; } CObj(const CObj &obj) { cout << "复制构造函数" << endl; } CObj & operator=(const CObj &obj) { if (&obj != this) { cout << "赋值操作符" << endl; } return *this; } }; int main() { CObj obj1; cout << endl; CObj obj2(obj1); cout << endl; CObj obj3; obj3 = obj2; return 0; }
执行结果:

默认构造函数 复制构造函数 默认构造函数 赋值操作符
四、禁止复制
1.有些类需要完全禁止复制,怎么办?

只需将复制构造函数声明为私有成员函数即可。
解释:因为如果不声明定义,编译器将会默认合成一个复制构造函数。
例子:

#include <iostream> using namespace std; class CObj { public: CObj() { cout << "默认构造函数" << endl; } private: CObj(const CObj &obj) { cout << "复制构造函数" << endl; } }; int main() { CObj obj1; CObj obj2(obj1); return 0; }
编译报错:

error: 'CObj::CObj(const CObj&)' is private

这就是禁止复制的效果,正是这里想要的。


2.连友元函数和成员函数的复制也要禁止,怎么办?
如果想要连友元函数和成员函数的复制也禁止,那么可以声明一个私有的复制构造函数但不对其定义。
解释:因为友元函数或成员函数可以访问到类的私有成员,所以当然能调用私有的复制构造函数,所有将复制构造函数声明为私有但不定义,就能避免友元或成员函数的调用。
例子:

#include <iostream> using namespace std; class CObj { public: CObj() { cout << "默认构造函数" << endl; } friend void fcopy(); private: CObj(const CObj &obj); }; void fcopy() { CObj obj1; CObj obj2(obj1); } int main() { fcopy(); return 0; }
编译报错:
undefined reference to `CObj::CObj(CObj const&)'
这也正是这里需要的结果,禁止复制成功,OK。


再接再厉!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值