对不同的类使用相同的指针
1.基类指针指向派生类
C++允许基类指针指向派生类,然而使用基类指针,只能访问基类的成员,不能访问派生类的成员。
#include<iostream>
using namespace std;
class Base {
public:
void base_message() {
cout << "Base Class. " << endl;
}
};
class Derived :public Base {
public:
void derived_message() {
cout << "Derived Class. " << endl;
}
};
void main()
{
Base* derived_pointer = new Derived();
derived_pointer->base_message(); //ok,可以访问到基类的成员函数
//derived_pointer->derived_message(); //error,不能访问到基类以外的成员函数
}
当基类和派生类的成员函数重名时,C++会确定该指针指向基类成员函数
#include<iostream>
using namespace std;
class Base {
public:
void show_message() {
cout << "Base Class. " << endl;
}
};
class Derived :public Base {
public:
void show_message() {
cout << "Derived Class. " << endl;
}
};
void main()
{
Base* derived_pointer = new Derived();
derived_pointer->show_message(); //ok,输出为Base Class
}
有时为了让编译器调用派生类的成员,此时需要使用虚拟函数(用到virtual关键字),每个虚拟函数的返回类型及参数必须相同。
#include<iostream>
using namespace std;
class Base {
public:
virtual void show_message() {
cout << "Base Class. " << endl;
}
};
class Derived :public Base {
public:
void show_message() {
cout << "Derived Class. " << endl;
}
};
void main()
{
Base* derived_pointer = new Derived();
derived_pointer->show_message(); //ok,输出为Derived Class
}
虚拟属性是可以继承的,同时也是分层的。比如下面这个例子,Derived2继承Derived1,但没重写show_message(),因此,该函数与Derived1保持一致;Derived3继承Derived2,可以继续修改show_message()
#include<iostream>
using namespace std;
class Base {
public:
virtual void show_message() {
cout << "Base Class. " << endl;
}
};
class Derived1 :public Base {
public:
void show_message() {
cout << "Derived1 Class. " << endl;
}
};
class Derived2 :public Derived1 {
};
class Derived3 :public Derived2 {
public:
void show_message() {
cout << "Derived3 Class. " << endl;
}
};
void main()
{
Base* p=new Base;
Derived1 d1;
Derived2 d2;
Derived3 d3;
p->show_message(); //输出Base Class
p = &d1;
p->show_message(); //输出Derived1 Class
p = &d2;
p->show_message(); //输出Derived1 Class
p = &d3;
p->show_message(); //输出Derived3 Class
}
析构函数定义为虚函数时,当使用delete释放基类指针对应的内存时,可以按照派生类->基类进行析构,而不是直接调用基类的析构函数,可以防止派生类中动态分配的内存没被回收的现象:
#include<iostream>
using namespace std;
class Base {
public:
Base(int size) {
p = new char(size);
}
virtual ~Base() {
delete[]p;
cout << "release pointer p success. " << endl;
cout << "Base return, " << endl;
}
private:
char* p;
};
class Derived :public Base {
public:
Derived(int size_1,int size_2): Base(size_1) {
q = new int(size_2);
}
~Derived() {
delete[]q;
cout << "release pointer q success. " << endl;
cout << "Derived return, " << endl;
}
private:
int* q;
};
void main()
{
Base* pbase = new Derived(10, 20);
delete pbase;
//输出结果:
//release pointer q success.
//Derived return,
//release pointer p success.
//Base return,
//不加virtual输出结果:
//release pointer p success.
//Base return,
}