c++ Primer 第十三章 拷贝控制 重点梗概

1. 基本操作:拷贝、赋值与销毁

  • 拷贝构造函数:参数为该类的一个const引用
  • 拷贝赋值运算符重载
  • 析构函数:由于析构函数不接受参数,因此它不能被重载。
    拷贝构造函数和拷贝赋值运算符的不一样在于前者不需要先重置当前对象,而后者需要。原因在于前者是构造函数,本身是没有经过初始化的。

合成xxx函数

编译器帮忙定义的上述三种函数:调用成员(非static)的xxx函数构造该类的xxx函数。

三五法则

  • 需要析构函数的类也需要拷贝和赋值操作
  • 需要拷贝操作的类也需要赋值操作,反之亦然

阻止拷贝

新标准建议使用 = delete来完成拷贝的相关函数的调用阻止。

2. 拷贝控制和资源管理

  • 行为像值的类
    每个对象都应该拥有一份自己的拷贝
  • 行为像指针的类
    类似于自建一个简单的shared_ptr

3. 交换操作

避开std::swap而使用自定义swap的方式

using std::swap;
swap(lhs.h,rhs.h);
//其他的swap

4. 拷贝控制示例类

//Message.h
#pragma once
#include <set>
#include <string>
#include "Folder.h"

using namespace std;
class Message
{
	friend class Folder;
public:
	explicit Message(const string& str = "") :contents(str) {}//构造函数
	Message(const Message&); //拷贝构造函数
	Message& operator= (const Message&);//拷贝赋值运算符
	~Message();
	void save(Folder&);
	void remove(Folder&);
private:
	string contents;
	set<Folder*> folders;

	void add_to_folders(const Message&);
	void remove_from_folders();
};
//Folder.h
#pragma once
#include "Message.h"

using namespace std;

class Folder
{
	friend class Message;
public:
	Folder() {}
	Folder(const Folder&);
	Folder& operator=(const Folder&);
	void addMessage(Message&);
	void rmMessage(Message&);
	~Folder(); //要从保存在本文件夹当中的Message里面删除该Folder
private:
	set<Message*> messages;
	void tell_message_add(Message*);
	void tell_message_rmv(Message*);

};

实现

//Message.cpp
#include "Message.h"

Message::Message(const Message& message):contents(message.contents),folders(message.folders)
{
	add_to_folders(*this);
}

Message& Message::operator=(const Message& message)
{
	remove_from_folders();
	contents = message.contents;
	folders = message.folders;
	add_to_folders(*this);
	return *this;
}

void Message::add_to_folders(const Message& message)
{
	for (auto f : message.folders)
		f->addMessage(*this);
}

void Message::remove_from_folders()
{
	for (auto f : folders)
		f->rmMessage(*this);
}

void Message::save(Folder& folder)
{
	folders.insert(&folder);
	folder.addMessage(*this);
}

void Message::remove(Folder& folder)
{
	folders.erase(&folder);
	folder.rmMessage(*this);
}

Message::~Message()
{
	remove_from_folders();
}

//Folder.cpp
#include "Folder.h"


Folder::Folder(const Folder& folder):messages(folder.messages)
{
	for (auto m : folder.messages)
		tell_message_add(m);
}

Folder& Folder::operator=(const Folder& folder)
{
	for (auto oldM : messages)
		tell_message_rmv(oldM);
	messages = folder.messages;
	for (auto newM : messages)
		tell_message_add(newM);
	return *this;
}

void Folder::tell_message_add(Message* mPtr)
{
	mPtr->folders.insert(this);
}


void Folder::tell_message_rmv(Message* mPtr)
{
	mPtr->folders.erase(this);
}

void Folder::addMessage(Message& m)
{
	messages.insert(&m);
}

void Folder::rmMessage(Message& m)
{
	messages.erase(&m);
}

Folder::~Folder()
{
	for (auto oldM : messages)
		tell_message_rmv(oldM);
}

5. 动态内存管理类

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值