C++箴言:拷贝一个对象的所有组成部分

C++箴言:拷贝一个对象的所有组成部分,第1张

C++箴言:拷贝一个对象的所有组成部分,第2张

在一个设计良好的面向对象系统中,为了压缩对象内部的空空间,只保留了两个函数用于复制对象:一般称为复制构造函数和复制赋值运算符。我们统称它们为复制功能。如果需要,编译器会生成一个复制函数,明确了编译器生成的版本正是你所期望的:它们复制了被复制对象的所有数据。

当你声明你自己的复制函数时,你是在告诉编译器你不喜欢默认实现中的某些东西。编译器似乎对此很愤怒,他们会以一种奇怪的方式进行报复:当你的实现中有一些几乎确定的错误时,它只是不会告诉你。

考虑一个象征客户的类,其中copy函数是手写的,以便记录对他们的呼叫:

void log call(const STD::string & funcName);//创建日志条目

类别客户{
公共:
...
客户(const客户& RHS);
客户&操作员=(const客户& RHS);
...

private:
STD::string name;
};
Customer::Customer(const Customer & rhs)
:name(RHS . name)//复制RHS的数据
{
logCall("客户复制构造函数");
}

Customer & Customer::operator =(const Customer & RHS)
{
log call("客户复制赋值运算符");
name = RHS . name;//复制rhs的数据
return * this;//参见第10项
}

这里的一切看起来都很好,实际上也很好——直到另一个数据成员被添加到Customer:

上课日期{...};//对于时间上的日期

类别客户{
公共:
...//和以前一样

private:
STD::string name;
Date last transaction;
};

这里,现有的复制函数只是部分复制:它们复制客户的名称,但不复制它的最后一个事务。然而,大多数编译器并不关心这一点,即使在最高警告级别。这是他们对你自己写复制函数的报复。你拒绝了他们写的复制功能,所以如果你的代码不完善,他们不会告诉你。结论是显而易见的:如果向类中添加数据成员,就必须更新复制函数。(还需要更新类中的所有构造函数和任何非标准形式的operator=。这个问题最令人困惑的一种情况是,它会通过继承发生。考虑:

class priority Customer:public Customer {//派生类
public:
...
优先级客户(const priority customer & RHS);
优先级客户&操作员=(常量优先级客户& RHS);
...

private:
int优先级;
};
priority customer::priority customer(const priority customer & RHS)
:priority(RHS . priority)
{
log call(" priority customer复制构造函数");
}

priority customer &
priority customer::operator =(const priority customer & RHS)
{
log call(" priority customer复制赋值运算符");
priority = RHS . priority;
return * this;
}

位律师回复
DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
白度搜_经验知识百科全书 » C++箴言:拷贝一个对象的所有组成部分

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情