条款12:复制对象时请勿忘每一个成分
当为一个类实现自己的构造函数,相关赋值函数,析构函数,则必须有责任对类中的每一个成员进行初始化、赋值、释放。因此:如果为一个类添加一个成员,就必须同时相应修改上面几类函数。
看一个简单的类
class Terminal { Terminal(const int termid) : m_termId(termid) {} ~Terminal() {} Terminal(const Terminal & terminal) { this->m_termId = terminal.m_termId; } Terminal & operator = (const Terminal &terminal) { if (this != &terminal) { this->m_termId = terminal.m_termId; } return *this; } private: int m_termId; };
为Terminal类新增加一个成员m_name后,对应的函数如下修改
class Terminal { public: Terminal() : m_termId(0), m_name(NULL) {} Terminal(const int termid, const char* name) : m_termId(termid) { if (name == NULL) { this->m_name = new char[1]; *this->m_name = '\0'; } this->m_name = new char[strlen(name) + 1]; strcpy(this->m_name, name); } ~Terminal() { if (m_name != NULL) delete m_name; m_name =NULL; } Terminal(const Terminal & terminal) { this->m_termId = terminal.m_termId; this->m_name = new char[strlen(terminal.m_name) + 1]; strcpy(this->m_name, terminal.m_name); } void Swap(Terminal& terminal) //自定义swap,避免重分配内存 { std::swap(this->m_termId, terminal.m_termId); std::swap(this->m_name, terminal.m_name); } Terminal & operator = (Terminal terminal) { Swap(terminal); return *this; } private: int m_termId; char *m_name; };
在继承类中如何去复制每一个成员呢?
class TcpTerminal : public Terminal { public: TcpTerminal(const int type) : m_type(type) {} TcpTerminal(const TcpTerminal & rhs) : m_type(rhs.m_type) {} TcpTerminal & operator = (const TcpTerminal &rhs) { if (this != &rhs) this->m_type = rhs.m_type; return *this; } private: int m_type; };
此继承类实现出现有如下问题
TcpTerminal tcp(2); //调用基类Terminal的默认构造函数初始化继承的基类成员 TcpTerminal tcp2(tcp); //调用基类Terminal的默认构造函数初始化继承的基类成员,如果tcp对象基类成员有值,经过拷贝tcp2中基类成员没有得到赋值 tcp = tcp2; //没有对基类成员赋值,则还是保留原来的基类成员
修改上面的代码实现对基类成员的拷贝
class TcpTerminal : public Terminal { public: TcpTerminal(const int type, const int termId, const char* name) : Terminal(termId, name), m_type(type) {} TcpTerminal(const TcpTerminal & rhs) : m_type(rhs.m_type), Terminal(rhs) {} TcpTerminal & operator = (const TcpTerminal &rhs) { if (this != &rhs) { this->m_type = rhs.m_type; Terminal::operator = (rhs); } return *this; } private: int m_type; };
调用如下
TcpTerminal tcp(2, 3, "tcp"); TcpTerminal tcp2(tcp); TcpTerminal tcp3(4, 5, "tcp3"); tcp = tcp3;
当为一个类实现copy函数时,需记住以下两点
(1)拷贝local成员变量
(2)调用base class捏的适当的copying函数
记住
①要确保拷贝函数拷贝对象的所有的数据成员,及其基类的所有部分,不要有遗漏。
②不要尝试去实现一个拷贝函数来供其它的拷贝函数调用。取而代之的是,把公共部分放入一个“第三方函数”中共所有拷贝函数调用。
条款12:复制对象时请勿忘每一个成分,布布扣,bubuko.com
时间: 2024-10-24 10:38:00