c++赋值兼容原则

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>

using namespace std;

class Parent
{
public:
    Parent()
    {
    
    }
    Parent(int a)
    {
        this->a = a;
    }
    void func1()
    {
    
    }
    void func3()
    {
        cout << "parent..........." << endl;
    }
    int c;
    int d;
    static int e;
private:
    int a;
};
//子类也会继承父类的静态成员变量,这个静态成员变量被父类和子类共同持有,父类的多个对象和子类的多个对象都可以更改这个静态成员变量
int Parent::e = 100;

class Child :public Parent
{

public:
    //调用子类的构造函数时,一定会调用父类的构造函数
    //先调用父类的构造函数,在调用子类的构造函数,析构满足之前的规则,谁先构造,谁后析构,即子类后构造先析构,父类先构造后析构
    Child()//Child():Parent(3); 当父类没有默认构造函数时,子类的构造函数需要使用函数初始化列表
    {
        
    }
    Child(int b)
    {
        this->b = b;
    }
    void func2()
    {
        Parent::c = 10;//这是给父类里的c赋值,用作用域赋值,如果不存在相同变量,则可以直接用this->c调用
        this->c = 10;//这是给子类里另一个c赋值
        this->d = 10;
    }
    //父类和子类有有相同的函数
    //这即为函数的重定义,完全相同的函数,函数体内的流程改变即为重定义,重写只发生在多态时,为特殊的一种重定义,但不论重写与重定义都和重载不同,完全是两个概念
    void func3()
    {
        cout << "child............" << endl;
    }
    ~Child()
    {

    }
    //父类和子类有相同的变量
    int c;//子类空间会现在父类对象中创建一个变量c,然后再在子类别的空间创建另一个变量c
private:
    int b;
};

int main()
{
    static int a;//只是在类里不计算
    cout << "sizeof(static int a)=" << sizeof(a) << endl;


    Parent p1;
    Child c1;
    p1 = c1;//子类对象空间比父类对象空间大,可以把父类空间赋值满,因此子类对象可以为父类对象赋值
    //p1.func2();这是错误的,访问不到
    //c1 = p1;这是错误的,子类对象空间比父类对象空间大,父类对象不可以把子类对象赋值满,因此父类对象不可以为子类对象赋值

    Parent *p2 = NULL;
    Child *c2 = NULL;

    Parent p3;
    Child c3;

    p2 = &c3;//父类的指针可以指向子类的对象,因为子类包含父类所有空间,父类指针访问的范围超出不了子类对象的空间
    //c2 = &p3;这是错误的,子类对象空间比父类对象空间大,因此子类指针如果指向父类对象,会访问越界,因此子类指针不可以指向父类对象,即子类地址可以给父类指针赋值,也满足大的可以给小的赋值
    //p2->func2();这是错误的,p2虽然指向子类对象,但它只能访问子类对象中包含的父类对象的区域,对于子类额外定义的东西,父类指针是不能调用的
    //这个规则也适用于父类的对象,引用,指针,都是只能访问子类对象中包含的父类对象的区域,对于子类额外定义的东西,父类的对象,引用,指针都是不能调用的

    Parent &p4 = c1;//父类的引用引用子类的对象,满足大的给小的赋值,因为p4即为c1的别名,p4比c1小,所以可以引用
    //p4.fun2();这是错误的,访问不到
    Child &c4 = c1;
    p4 = p1;//这是赋值,不是更改引用的指向,父类的对象给父类的对象赋值
    p4 = c1;//这是赋值,不是更改引用的指向,子类的对象给父类的对象赋值,与前面赋值一致,满足大的可以给小的赋值
    p4 = c4;//也是赋值,不是更改引用的指向,子类的引用给父类的引用赋值,本质就是子类的对象给父类的对象赋值
    //总的来说,等号右边的一定是子类对象,即大的可以给小的赋值
    //也就是1.子类的对象可以给父类的对象赋值和初始化,2.父类的指针可以指向子类对象(即子类对象的地址可以给父类指针赋值),3.父类的引用可以引用子类的对象(即给子类的对象取一个父类型的别名)

    Child c5;
    c5.func3();
    return 0;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值