C++_赋值兼容规则

赋值兼容规则

所谓赋值兼容规则是指在需要基类对象的任何地方都可以使用公有派生类的对象来替代。这样,公有派生类实际上就具备了基类的所有特性,凡基类能解决的问题,公有派生类也能解决。

例如,下面声明的两个类:

class Base{
    //...
};
class Derived:public Base{
    //...
};

根据赋值兼容规则,在基类Base的对象可以使用的任何地方, 都可以用派生类derive的对象来替代,但只能使用从基类继承来的成员

以下几种情况是合法的:

  • (1) 可以用派生类对象给基类对象赋值
Base b;
Derived d;
b=d;

这样赋值的效果是,对象b中所有数据成员都将具有对象d中对应数据成员的值。

  • (2) 可以用派生类对象来初始化基类的引用
Derived d;
Base &br=d;
  • (3) 可以把派生类对象的地址赋值给指向基类的指针
Derived d;
Base *bptr=&d;

这种形式的转换,是在实际应用程序中最常见到的。

  • (4) 可以把指向派生类对象的指针赋值给指向基类对象的指针
Derived *dptr;
Base *bptr=dptr;
例 赋值兼容规则实例
#include <iostream.h>
class base{
public:
    int i;
    base(int x) {i=x;}
    void show()
    {cout<<"base "<<i<<endl;}
};
class derive:public base{
public:
    derive(int x):base(x) { };
    void show()
    {cout<<"derive "<<i<<endl;}
};
void main(){
    base b1(11); b1.show();
    derive d1(22);
    b1=d1; b1.show();
    derive d2(33);
    base &b2=d2; b2.show();
    derive d3(44);
    base *b3=&d3; b3->show();
    derive *d4=new derive(55);
    base *b4=d4; b4->show();
    delete d4;
}
Base 11
Base 22
Base 33
Base 44
Base 55

说明:

  • (1). 声明为指向基类对象的指针可以指向它的公有派生的对象,但不允许指向它的私有派生的对象。
  • (2). 允许将一个声明为指向基类的指针指向其公有派生类的对象,但是不能将一个声明为指向派生类对象的指针指向其基类的一个对象。
  • (3). 声明为指向基类对象的指针,当其指向公有派生类对象时,只能用它来直接访问派生类中从基类继承来的成员,而不能直接访问公有派生类中定义的成员。

若想访问其公有派生类的特定成员,可以将基类指针用显示类型转换为派生类指针。

class base{
    //...
};
class derive: private base {
    //...
};
void main(){
    base op1,*ptr;
    derive op2;
    ptr=&op1;
    ptr=&op2; //错误,不允许指向它的私有派生类对象
    //...
}
#include<iostream.h>
class Base{
    //...
};
class Derived: public Base{
    //...
};
void main(){
    Base obj1;
    Derived obj2,*ptr;
    ptr=&obj2;
    ptr=&obj1;// 错误, 将派生类指针指向基类对象
    //...
}
class A {
    //...
public:
    void print1();
};
class B: public A {
    //...
public:
    print2();
};
void main(){
    A op1,*ptr; // 定义基类A的对象op1和基类指针ptr
    B op2; // 定义派生类B的对象op2
    ptr=&op1; // 将指针ptr指向基类对象op1
    ptr->print1(); // 调用基类函数print1()
    ptr=&op2; // 将指针ptr指向派生类对象op2
    ptr->print1(); // 调用对象op2从其基类继承来的成员函数print1()
    ptr->print2(); // 错误,基类指针ptr不能访问派生类中定义    的成员函数print2()
    ((B*)ptr)-> print2();
}
posted @ 2020-02-28 12:35  鲸90830  阅读(869)  评论(0)    收藏  举报