关于重载问题

来源:互联网 发布:星际争霸2 战术 知乎 编辑:程序博客网 时间:2024/04/29 16:38
http://blog.chinaunix.net/uid-26983585-id-3310398.html
在C++中为什么输入输出流不能重载为类成员函数?
假如说operator << ()这是一个成员函数,mealtime是一个类Time的私有成员,那么如我们看到的,如下一个输出语句:cout<<mealtime;将被编译器处理为发送一条消息到cout,cout.operator<<(mealtime);这表示operator <<必须是类ostream的一个成员,而不是类Time的一个成员。然而,即使能将这个新函数添加到标准ostream中,仍然不希望破坏标准的<iostream>库,因此operator <<必然是一个普通函数,这表示如下输出语句:cout<<mealtime将被编译器看作函数调用operator<<(cout,mealtime);这样operator<<()必须具有两个形参,第一个是ostream类,第二个是Timer类。
大部份的标准库实现中,对ostream,istream类体系采用了构造函数保护继承的方式。。。致使即使以继承的方式来扩展流类,也会在对象实例化时遭遇阻碍。。。
另一方面,标准库中的流类,其插入符函数没有声明为虚函数,因此子类不能对其实现进行覆盖,所以也使成员函数重载遭遇到实质的困难。。。
总的来说,C++标准I/O库非常繁杂且难,其实现思想很多都与常规的OOP有所出入。。。在使用的时候要谨慎,并最好遵从惯例。。。


为什么C++赋值运算符不能被继承?
1,每一个类对象实例在创建的时候,如果用户没有定义“赋值运算符重载函数”,那么,编译器会自动生成一个隐含和默认的“赋值运算符重载函数”。所以,B1的实际上的声明应该类似于下面这种情况:

class A1
{
public:
         int operator=(int a)
         {
                 return 8;
         }

         int operator+(int a)
         {
                 return 9;
         }
};

class B1 : public A1
{
public:
         B1& operator =(const B1& robj); // 注意这一行是编译器添加的
         int operator-(int a)
         {
                 return 7;
         }
};

2,C++标准规定:如果派生类中声明的成员与基类的成员同名,那么,基类的成员会被覆盖,哪怕基类的成员与派生类的成员的数据类型和参数个数都完全不同。显然,B1中的赋值运算符函数名operator =和基类A1中的operator =同名,所以,A1中的赋值运算符函数int operator=(int a);被B1中的隐含的赋值运算符函数B1& operator =(const B1& robj);所覆盖。 A1中的int operator=(int a);函数无法被B1对象访问。

3,程序中语句v = 2实际上相当于v.operator =(2);,但是A1中的int operator=(int a);已经被覆盖,无法访问。而B1中默认的B1& operator =(const B1& robj);函数又与参数2的整数类型不相符,无法调用。

4,为了确认B1中默认的B1& operator =(const B1& robj);函数的存在性,可以用以下代码验证:

B1 b;
B1 v;

v = b; // OK, 相当于调用v.operator =(b);

5,所以,“赋值运算符重载函数”不是不能被派生类继承,而是被派生类的默认“赋值运算符重载函数”给覆盖了。

这就是C++赋值运算符重载函数不能被派生类继承的真实原因!
关于本帖问题正确性的解释

0 0