关于继承体系下的操作符重载问题讨论(一)
2009-06-22 10:48
260 查看
为了引出问题,我们先来看下面这个小例子,假设现在有一个LimitValue代理类,它提供了有限的内置型
操作,为了测试上的方便,我们只对该类进行简单的设计:
...
class LimitValue{
public:
LimitValue(int value):value_(value){}
LimitValue& operator=(const LimitValue& rhs){
cout<<"In LimitValue,call LimitValue::operator=(const LimitValue&)"<<endl;
value_ = rhs.value_;
}
private:
int value_;
};
接下来我们有一个Day类,继承该类LimitValue,我们希望它也具有赋值操作符运算:
class Day:public LimitValue{
public:
Day(int days,int selfData):LimitValue(days),selfValue_(selfData){}
Day& operator=(const Day& rhs){
cout<<"In Day,call operator=(const Day&) "<<endl;
selfValue_ = rhs.selfValue_;
return *this;
}
int getSelfValue()const{
return selfValue_;
}
private:
int selfValue_;
};
在Day的copy assign操作符函数中我们没有对base class进行操作,我当时的想法是:编译器在对子类进行赋
值操作时候会自动调用子类的copy assign操作符运算.貌似不错,但到底是不是这样做的呢?我们用事实来说明这
个结论是否成立?开始写测试代码:
我们需要一个输出函数:
void OutputValue(const Day& day)
{
cout<<"value_="<<day.getValue()<<" selfValue="<<day.getSelfValue()<<endl;
}
{
...
Day d1(1,1);
Day d2(2,2);
cout<<"Before assign,d1:";
OutputValue(d1);
cout<<"d2:";
OutputValue(d2);
d2 = d1;
cout<<"After assign,d1:";
OutputValue(d1);
cout<<"d2:";
OutputValue(d2);
...
}
//运行以后输出结果:
// Before assign,d1:value_=1 selfValue=1
// d2:value_=2 selfValue=2
// In Day,call operator=(const Day&)
// After assign,d1:value_=1 selfValue=1
// d2:value_=2 selfValue=1
一看输出结果,晕倒,竟然不是与我想的正好相反:它压根就不调用base class的赋值操作运算,真够懒的,我们
这好自己动手添加对base class的赋值操作,这很容易修改:
Day& Day::operator=(const Day& rhs)
{
cout<<"In Day,call operator=(const Day&) "<<endl;
LimitValue::operator=(rhs); //添加对子类的copy assign调用
selfValue_ = rhs.selfValue_;
return *this;
}
//运行以后输出结果:
// Before assign,d1:value_=1 selfValue=1
// d2:value_=2 selfValue=2
// In Day,call operator=(const Day&)
// In LimitValue,call operator=()
// After assign,d1:value_=1 selfValue=1
// d2:value_=1 selfValue=1
问题搞定,呵呵,这里我们要记住了喔:
在子类的操作符重载函数中,编译器不会为我们自动调用其基类对应操作符函数.
记好了喔,到这里的时候你不免会提出这样一个问题:如果我们要是不为子类提供这样的操作符函数,而是使用
编译器为我们提供的默认的实现,那么是否会调用基类对于的操作符函数呢?好,我们把这个问题留到下一篇继续讨
论.
操作,为了测试上的方便,我们只对该类进行简单的设计:
...
class LimitValue{
public:
LimitValue(int value):value_(value){}
LimitValue& operator=(const LimitValue& rhs){
cout<<"In LimitValue,call LimitValue::operator=(const LimitValue&)"<<endl;
value_ = rhs.value_;
}
private:
int value_;
};
接下来我们有一个Day类,继承该类LimitValue,我们希望它也具有赋值操作符运算:
class Day:public LimitValue{
public:
Day(int days,int selfData):LimitValue(days),selfValue_(selfData){}
Day& operator=(const Day& rhs){
cout<<"In Day,call operator=(const Day&) "<<endl;
selfValue_ = rhs.selfValue_;
return *this;
}
int getSelfValue()const{
return selfValue_;
}
private:
int selfValue_;
};
在Day的copy assign操作符函数中我们没有对base class进行操作,我当时的想法是:编译器在对子类进行赋
值操作时候会自动调用子类的copy assign操作符运算.貌似不错,但到底是不是这样做的呢?我们用事实来说明这
个结论是否成立?开始写测试代码:
我们需要一个输出函数:
void OutputValue(const Day& day)
{
cout<<"value_="<<day.getValue()<<" selfValue="<<day.getSelfValue()<<endl;
}
{
...
Day d1(1,1);
Day d2(2,2);
cout<<"Before assign,d1:";
OutputValue(d1);
cout<<"d2:";
OutputValue(d2);
d2 = d1;
cout<<"After assign,d1:";
OutputValue(d1);
cout<<"d2:";
OutputValue(d2);
...
}
//运行以后输出结果:
// Before assign,d1:value_=1 selfValue=1
// d2:value_=2 selfValue=2
// In Day,call operator=(const Day&)
// After assign,d1:value_=1 selfValue=1
// d2:value_=2 selfValue=1
一看输出结果,晕倒,竟然不是与我想的正好相反:它压根就不调用base class的赋值操作运算,真够懒的,我们
这好自己动手添加对base class的赋值操作,这很容易修改:
Day& Day::operator=(const Day& rhs)
{
cout<<"In Day,call operator=(const Day&) "<<endl;
LimitValue::operator=(rhs); //添加对子类的copy assign调用
selfValue_ = rhs.selfValue_;
return *this;
}
//运行以后输出结果:
// Before assign,d1:value_=1 selfValue=1
// d2:value_=2 selfValue=2
// In Day,call operator=(const Day&)
// In LimitValue,call operator=()
// After assign,d1:value_=1 selfValue=1
// d2:value_=1 selfValue=1
问题搞定,呵呵,这里我们要记住了喔:
在子类的操作符重载函数中,编译器不会为我们自动调用其基类对应操作符函数.
记好了喔,到这里的时候你不免会提出这样一个问题:如果我们要是不为子类提供这样的操作符函数,而是使用
编译器为我们提供的默认的实现,那么是否会调用基类对于的操作符函数呢?好,我们把这个问题留到下一篇继续讨
论.
相关文章推荐
- 关于继承体系下的操作符重载问题讨论(二)
- 关于子类继承父类属性的问题讨论(希望得到大神指点)
- 关于继承的问题的一些讨论
- 关于继承的讨论,以及私有属性继承的问题
- 关于继承问题的讨论
- 关于原型链和继承问题的思考:为什么不能直接把父类的prototype赋值给子类的prototype
- [全程建模]关于UML与新概念名词的问题讨论
- 关于PicoBlaze 读操作的一个问题的讨论(二)
- 关于prototype使用位置问题的讨论
- C#关于继承后,添加泛型集合中后,再次遍历的问题 !!!
- 关于“JAVA中为什么没有了多继承并出现了接口”这一问题引发的一些思考
- [导入]关于petshop中simplepager(继承自Repeater)覆写DataSource的问题
- 【原创】关于C#多线程安全问题的讨论
- 关于虚拟目录继承根Web.Config的问题解决办法
- 关于DevExpress GridControl 和TreeList在窗体被继承后无法设计问题
- 关于继承和虚函数的入门讨论
- 关于Excel的导出问题(.net方法与javascript方法之间的讨论)
- 关于网页元素的定位问题及offsetParent的讨论
- 关于 打印设置 的问题 讨论。
- 关于Hibernate实现继承树的问题