C++基础15---基类对象模型与派生类对象模型探索

1 派生类对象模型

1.1 派生类对象的组成部分

派生类对象包含多个组成部分,包括:
(1)派生类自己定义的子对象(成员变量、成员函数)。
(2)派生类从基类继承得到的子对象(基类中定义的成员变量、成员函数)。

1.2 基类指针与派生类指针

由于子类对象中包含父类的对象,因此,子类的指针范围大于父类指针范围。所以,可以用父类指针指向子类对象,而子类指针无法指向父类对象。

#include <iostream>
using namespace std;

class Animal
{

};

class Dog : public Animal
{

};

int main() {
    Animal *animal1 = new Dog; //父类指针可以指向子类对象,此时编译器帮我们隐式的做了子类到父类的转换
//    Dog *dog = new Animal; //错误, 子类指针不可以指向父类对象。编译器无法完成父类到子类的转换
}

2 派生类构造函数

(1)派生类其实使用基类的构造函数来初始化基类部分的成员,即,基类控制基类部分的初始化,派生类控制派生类部分的初始化。
(2)在创建子类对象时,先调用基类构造函数,再调用派生类构造函数。

#include <iostream>
using namespace std;

class Animal
{
public:
    Animal()
    {
        cout << "Animal类构造函数" << endl;
    }
};

class Dog : public Animal
{
public:
    Dog()
    {
        cout << "Dog类构造函数" << endl;
    }
};

int main() {
    Dog *dog = new Dog; //Animal类构造函数, Dog类构造函数
}

(3)通过派生类构造函数给基类构造函数传值

#include <iostream>
using namespace std;

class Animal
{
public:
    Animal(int age) : m_Age(age)     //初始化列表
    {
        cout << "Animal的年龄是" << m_Age << endl;
    }
    int m_Age;
};

class Dog : public Animal
{
public:
    Dog(int age1, int age2) : Animal(age1), m_Age(age2)   //将age1传递给父类Animal的构造函数,将age2传递给自己的构造函数
    {
        cout << "Dog的年龄是" << m_Age << endl;
    }
    int m_Age;
};

int main() {
    Dog(10, 20);  //Animal的年龄是10,  Dog的年龄是20
}

3 继承关系的传递性

继承具有传递性,B是A的子类,C是B的子类,则C继承了A和B的所有成员。

#include <iostream>
using namespace std;

class Animal
{
public:
    int m_Age;
    Animal(int age) : m_Age(age){}
};

class Dog : public Animal
{
public:
    string m_Name;
    Dog(int age, string name) : Animal(age), m_Name(name){}
};

class Erha : public Dog
{
public:
    Erha(int age, string name) : Dog(age, name){}   //Dog类构造函数需要m_Age,和m_Name来进行初始化
};


int main() {
    Erha erha(10, "shiyi");
    cout << erha.m_Name << " " << erha.m_Age;
}

4 不成为基类

在某个类后面加上final关键字,则该类不允许其他类继承

class Animal final
{
};

class Dog : public Animal //错误, Animal类不允许被继承
{
};

5 静态类型与动态类型

(1)静态类型是指变量声明时的类型,在编译时已经确定。
(2)动态类型是指基类指针/引用所指内存中对象的类型,在运行时才能确定。
(3)只有基类指针/引用才会出现静态类型和动态类型不一致的问题。(基类指针/引用指向子类对象)。

6 父类与子类间的拷贝与赋值

(1)用子类对象初始化父类对象时,会自动调用父类的拷贝构造函数。

#include <iostream>
using namespace std;

class Animal
{
public:
    int m_Animal;
    Animal(int i) : m_Animal(i){} //使用拷贝构造函数时,系统不再自动为我们定义构造函数,需手动定义
    Animal(const Animal& tmpDog) //tmpDog得到了Dog类对象的引用,但是其只能处理自己的成员不能处理子类成员
    {
        m_Animal = tmpDog.m_Animal; // 自己定义拷贝构造函数时,系统不再逐一拷贝,须手动拷贝成员
        cout << "执行Animal拷贝构造函数" << endl;  // 10
//        cout << m_Dog << endl;  //错误,不可以处理子类成员
        cout << m_Animal << endl;
    }
};

class Dog : public Animal
{
public:
    int m_Dog;
    Dog(int i, int j) : Animal(i), m_Dog(j){}
};


int main() {
    Dog dog(10, 20);
    Animal animal(dog);  //执行Animal拷贝构造函数
}

(2)子类对象赋值给父类对象时,会自动调用赋值运算符

#include <iostream>
using namespace std;

class Animal
{
public:
    Animal& operator=(const Animal& tmpDog)
    {
        cout << "调用赋值运算符" << endl;  //调用赋值运算符
        return *this;
    }
};

class Dog : public Animal
{
    
};

int main() {
    Animal animal;
    Dog dog;
    animal = dog;  //子类对象赋值给父类对象,自动调用赋值运算符
}

结论:
用派生类对象给基类对象赋值/拷贝时,只有该派生类对象的基类部分参与拷贝或赋值,其余部分不参与。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值