*C++(33)类型兼容性原则

类型兼容性原则

类型兼容规则是指在需要基类对象的任何地方,都可以使用公有派生类的对象来替代。通过公有继承,派生类得到了基类中除构造函数、析构函数之外的所有成员。这样,公有派生类实际就具备了基类的所有功能,凡是基类能解决的问题,公有派生类都可以解决。类型兼容规则中所指的替代包括以下情况:

  • 子类对象可以当作父类对象使用
  • 子类对象可以直接赋值给父类对象
  • 子类对象可以直接初始化父类对象
  • 父类指针可以直接指向子类对象
  • 父类引用可以直接引用子类对象
  • 在替代之后,派生类对象就可以作为基类的对象使用,但是只能使用从基类继承的成员。

类型兼容规则是多态性的重要基础之一。

示例程序

#include <iostream>

using namespace std;
//  子类对象可以当作父类对象使用
//  父类指针可以直接指向子类对象
//  父类引用可以直接引用子类对象

//  子类对象可以直接初始化父类对象
//  子类对象可以直接赋值给父类对象
class Parent
{
public:
    void setAB(int a, int b)
    {
        this->a = a;
        this->b = b;
    }
    void printAB() const 
    {
        cout << "a = " << a << ", b = " << b << endl;
    }
private:
    int a;
    int b;
};

class Child :public Parent
{
public:
    void setC(int c)
    {
        this->c = c;
    }

    void printC()
    {
        cout << "c = " << c << endl;
    }
private:
    int c;
};

// 子类对象可以当作父类对象来使用
void func1()
{
    // Parent p;
    Child p;
    p.setAB(1,2);
    p.printAB();
}

void test(Parent *p)
{
    p->printAB();  // printAB(p)
}

void test(const Parent &p)
{
    p.printAB();  // printAB(p)
}

void func3()
{
    Parent p;
    p.setAB(1,2);
    // test(&p);
    test(p);


    Child c;
    c.setAB(5,6);
    c.setC(9);
    // test(&c);
    test(c);
}

// 父类指针可以直接指向子类对象
void func2()
{
    // c1 是子类对象的指针
    Child *c1 = new Child;
    c1->setAB(1,2);
    c1->setC(3);

    // p 是基类的指针   c1 是派生类的指针
    // p 是父类的指针   c1 是子类的指针,指向子类的对象
    // 父类指针可以直接指向子类对象, p可以直接指向一个子类的对象
    // 所以可以直接将 c1 赋值给 p
    // 将子类对象当作父类对象来使用
    Parent *p;

    p = c1;
    // p 是 Parent 类型的指针,所以只能使用 Parent 中的内容
    p->printAB();


    Parent *p2 = new Child;
}


// 子类对象可以直接初始化父类对象
void func4()
{
    Child c;
    c.setAB(1,2);
    c.setC(3);

    Parent &p1 = c;

    // 子类对象可以直接初始化父类对象
    Parent p = c; // Parent(c) ===>  Parent(const Parent &obj)  ====>  Parent(&c) ==> Parent(const Parent *const obj)
    test(&p);


    // 子类对象可以对父类对象赋值
    Child c2;
    c2.setAB(5,6);
    c2.setC(10);

    // Parent &operator=(const Parent &obj)
    // 父类引用可以直接引用子类对象
    // p.operator=(c2);
    p = c2;
    test(p);
}

int main()
{
    // func1();
    // func2();
    // func3();
    //func4();
    return 0;
}


func1()执行结果:
a = 1,b = 2

func2()执行结果:
a = 1,b = 2

func3()执行结果:
a = 1,b = 2
a = 5,b = 6

func4()执行结果:
a = 1,b = 2
a = 5,b = 6
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值