基本应用
#include <iostream>
#include <string>
using namespace std;
class People{
private:int age;
private:string name;
public:People(string name,int age){
this->name = name;
this->age = age; //this是一个指针,指向当前的对象
}
public: void println(){
cout << "姓名为" << name << ",年纪为:" << age << endl;
}
};
class Student:public People{//设置继承方式为public
public:Student(string name,int age):People(name,age){
//继承父类的构造函数
}
};
int main()
{
Student stu("小明",12);
stu.println();
return 0;
}
继承方式
- 公共继承
- 保护继承
私有继承
公共继承 ```cpp class People{ };
class Student:public People{ //保留父类所有成员的访问权限 };
- 保护继承
```cpp
class People{
};
class Student:protected People{
//保留父类protected及private的成员的访问权限
//将父类所有public的成员修改为protected
};
- 私有继承 ```cpp class People{ };
class Student:private People{ //所有父类的成员都修改为private };
<a name="q53GX"></a>
###
<a name="eVEOa"></a>
### 访问与父类同名的变量及方法
```java
#include <iostream>
#include <string>
using namespace std;
class People{
public:void say(){
cout << "People say" << endl;
}
public:static void go(){
cout << "People go" << endl;
}
};
class Student:public People{
public:void say(){
cout << "Student say" << endl;
}
public:static void go(){
cout << "Student go" << endl;
}
};
int main()
{
Student stu;
stu.say();//调用Student中的成员函数say
stu.People::say();//访问父类中的成员函数say
Student::go();//调用Student中的静态函数go
Student::People::go();//访问父类中的静态函数go
return 0;
}
Student say People say Student go People go
一个类继承多个类
class People{
};
class Animal{
};
class Student:public People,public Animal{
};
注:C++开发中不建议用多继承
多态及虚函数
多态的概念和Java是一样的,即允许父类和子类进行类型转换
#include <iostream>
#include <string>
using namespace std;
class Animal{
public:
//virtual为声明speak为虚函数
virtual void speak(){
cout << "动物在说话" << endl;
};
};
class Dog:public Animal{
public:
void speak(){
cout << "狗在说话" << endl;
};
};
class Cat:public Animal{
public:
void speak(){
cout << "猫在说话" << endl;
};
};
void doSpeak(Animal& animal){
animal.speak();
}
int main()
{
Cat cat;
Dog dog;
doSpeak(cat);
doSpeak(dog);
return 0;
}
注:
- 如果不声明speak是虚函数(virtual),则执行doSpeak时,无论传参是Cat还是Dog,输出结果都会是Animal中的“动物在说话”
- 但在声明speak是虚函数以后,就会发现,在这种场景下,实际上父类的speak函数的实现是没有意义,那么这种场景下,可以把父类的speak修改为纯虚函数,即抽象函数。
纯虚函数及抽象类
如果一个类中有个纯虚函数,这个类就叫抽象类,其概念和特点其实和Java是一样的
class Animal{ public: virtual void speak();//也可以写成 virtual void speak() = 0; };
class Dog:public Animal{ public: void speak(){ cout << “狗在说话” << endl; }; };
class Cat:public Animal{ public: void speak(){ cout << “猫在说话” << endl; }; };
void speak(Animal& animal){ animal.speak(); }
int main() { Cat cat; Dog dog;
speak(cat);
speak(dog);
return 0;
}
<a name="iiAiK"></a>
### 虚析构函数和纯虚析构函数
**场景:**在多态使用时,如果子类有属性开辟到堆区,那么父类指针在释放时无法调用到子类的析构函数,如果子类没有堆区数据,是可以无写虚析函数的
**解决方案:**将父类的析构函数改为虚析构或纯虚析构。<br />虚析构和纯虚析构的共性:
- 可以解决父类指针释放子类对象
- 都需要有具体的函数实现
虚析构或纯虚析构的区别
- 纯虚析构由于是抽象类,无法实例化。
<a name="SO1sD"></a>
#### 虚析构函数
```c
#include <iostream>
#include <string>
using namespace std;
class Animal{
public:
virtual void speak();
virtual ~Animal(){};//虚析构函数
};
class Dog:public Animal{
string* name;
public:
Dog(string name):Animal()
{
this->name = new string(name);
}
void speak(){
cout << "狗在说话" << endl;
};
~Dog(){
if (name != NULL)
{
delete name;
}
}
};
void speak(Animal& animal){
animal.speak();
}
int main()
{
Dog dog("哈密瓜");
speak(dog);
return 0;
}
纯虚析构函数
#include <iostream>
#include <string>
using namespace std;
class Animal{
public:
virtual void speak();
virtual ~Animal() = 0;//纯虚析构函数
};
Animal::~Animal(){}; //如果是纯虚析构函数,则这一行不能少,否则编译无法通过,因为如果少了这一行,编译器会认为基类没有了析构函数
class Dog:public Animal{
string* name;
public:
Dog(string name):Animal()
{
this->name = new string(name);
}
void speak(){
cout << "狗在说话" << endl;
};
~Dog(){
if (name != NULL)
{
delete name;
}
}
};
void speak(Animal& animal){
animal.speak();
}
int main()
{
Dog dog("哈密瓜");
speak(dog);
return 0;
}