3.0 C++远征:is a

4-4is_a

0.派生类Soldier继承自基类Person

//Person.h
class Person
{
public:
    Person(string name = "Jim");
    ~Person();

    void play();
protected:
    string m_strName;
};

//Soldier.h
class Soldier : public Person
{
public:
    Soldier(string name = "James", int age = 20);

    ~Soldier();

    void work();
protected:
    int m_iAge;
};

1.派生类可以给基类赋值:

//main.cpp
int main(){
    Soldier s1;
    Person p1 = s1;
  
    return 0;
}

2.基类指针可以指向派生类(派生类可以取地址给基类):

//main.cpp
int main(){
    Soldier s1;
    Person *p2 = &s1;
  
    return 0;
}

3.把基类的指针或者是基类的对象或者是基类的引用作为函数的参数来使它可以接收所传入的子类的对象,并且也可以传入基类的对象

void func1(Person *p){
    ......
}

void func2(Person &p){
    ......
}

//main.cpp
int main(){
    Person p1;
    Soldier s1;
    func1(&p1);     func2(p1);
    func1(&s1);     func2(s1);
  
    return 0;
}

4.基类只能接收和访问派生类中自己有的数据成员和成员函数

//#include "Person.h"
# include "Soldier.h"

int main() {
    Soldier soldier;
    Person person;
    person = soldier;
    person.play();

    Person *p = &soldier;
    p->play();  // 使用基类声明的对象只能调用基类的方法
    //p->work();    // 使用基类声明的对象不能调用派生类的方法
  
    return 0;
}

5.通过基类的指针指向派生类的对象

//#include "Person.h"
#include "Soldier.h"

int main() {
    Person *pp = new Soldier;   // 基类的指针去指向派生类的内存空间
    pp->play();
    delete pp;  // 销毁基类的对象,执行的是基类的析构函数,派生类的内存并没有释放
    pp = NULL;
  
    return 0;
}
LOG:
Person::play()
James
Person::~Person()

6.为了防止内存的泄漏,此时需要用virtual关键字修饰析构函数。

virtual可以被继承

给基类的析构函数加一个关键字virtual,使销毁基类的对象时,可以释放派生类的对象的内存

//Person.h
class Person
{
public:
    Person(string name = "Jim");
    virtual ~Person();  // virtual关键字修饰析构函数

    void play();
protected:
    string m_strName;
};

LOG:
Person::play()
James
Soldier::~Soldier()
Person::~Person()

你可能感兴趣的:(3.0 C++远征:is a)