继承机制中构造器和析构器的特性
在构造器与析构器项目中 我们知道C++支持程序员自定义建立或销毁一个对象时自动调用的方法(构造器和析构器)
在没有类继承关系下的类构造器与析构器的运行规则
系统在创建某个类的实例时会第一时间自动调用这个类的 构造器
对象消亡时,析构器自动被调用,用来释放对象占用的空间
在类继承的情况下构造器与析构器的运行规则
基类的构造器将在子类的构造器调用之前被调用这是由于基类必须在子类之前被初始化的原则所导致的 与构造器的情况相反基类的析构器将在子类的最后一条语句执行完毕后才被调用(子类的析构器先调用 基类最后调用)
也就是在类继承关系下,构造器的调用顺序为基类优先,而析构器的调用顺序为子类优先.
类继承构造器
带有参数的构造器声明
class Animal
{
public:
Animal(string Tsex);//Animal基类的构造函数声明(带一个string类的参数 Tsex)
string sex;
}
//Animal基类的构造函数定义(带一个string类的参数 Tsex)
Animal::Animal(string Tsex)
{
sex = Tsex;//将传入的 构造器的参数 赋值给 类中的string类成员sex
}
//派生自Animal基类的子类monkey
class monkey :public Animal
{
public:
void climb();
monkey(string Tsex);//子类monkey的构造器 也是带有参数的构造器
};
继承机制下的派生自Animal基类和looklike基类的子类monkey的 构造器
monkey::monkey(string Tsex):Animal(Tsex)
{
//todo子类构造器中并没有设置参数 子类构造器的参数继承自基类构造器的参数
}
此时monkey
构造器在进行调用之前 首先调用了基类Animal的构造器也就是首先读取了基类构造器带的tsex
参数 到基类成员string sex
中 所以在monkey
这个子类继承Animal
这个基类的成员时sex
已经被构造器初始化赋值
注意:
在子类构造器定义中的: Animal(Tsex)
作用是 当调用monkey子类的构造器时以Tsex
作为输入参数 ,Animal基类的构造器也将被调用(将输入参数Tsex
传递给此构造器)
于是,当建立对象为monkey Monkey("雌性")
时 将把对象中的字符串传递给monkey(string Tsex)
和Animal(string Tsex)
构造器中的Tsex
赋值动作实际发生在Animal基类方法中
相关代码
class Animal
{
public:
Animal(string Tsex);
string sex;
string name;
string mouth;
};
//todoAnimal基类的构造函数
Animal::Animal(string Tsex)
{
sex = Tsex;
}
//todo派生自Animal基类和looklike基类的子类monkey
class monkey :public Animal
{
public:
void climb();
monkey(string Tsex);
};
//todo继承机制下的派生自Animal基类和looklike基类的子类monkey的 构造器
monkey::monkey(string Tsex):Animal(Tsex)
{
}
//当调用monkey派生类的构造器时 以string Tsex作为输入参数 同时Animal基类的构造器也将被调用(Tsex 输入参数将传递给他)
//当我们调用对象monkey monkey("雌性的")时 将把字符串 "雌性的" 传递给 monkey()和Animal()构造器 赋值动作实际发生在Animal()方法里
void monkey::climb()
{
cout << "我是一只小皮猴 我是爬树小能手" << endl;
}
int main()
{
//todo继承机制中的构造器和析构器
monkey Monkey("雌性的");//子类继承了基类构造器的参数
Animal ani("基类中的sex");//基类构造器参数被子类继承后仍可以使用
//当我们调用对象monkey monkey("雌性的")时 将把字符串 "雌性的" 传递给 monkey()和Animal()构造器 赋值动作实际发生在Animal()方法里
Monkey.name = "猴子";
cout << "我是一只" << Monkey.sex << Monkey.name<<endl;
Monkey.climb();
}
从程序的运行结果可以得出结论:
构造器也可以带有参数,并且可以是任何参数,这个参数的输入条件是在声明对象时在后方加上括号并在括号中输入与构造中带的输入参数一致的参数
类继承析构器
在销毁某个对象时 ,除了此对象的类析构器会被调用之外,此类的基类的析构器也将被自动调用,些事情编译器会自动替你处理。因为析构器不需要输入参数,所以根本用不着使用:SuperClassMethod(arguments)语法!
与类继承机制下构造器的情况相反,基类的析构器将在子类最后一条语句执行完毕后 才被调用
类继承机制下 基类子类的构造器和析构器的执行流程代码
#include <iostream>
#include <string>
using namespace std;
class Baseclass
{
public:
Baseclass();//todo基类构造器
~Baseclass();//todo基类析构器
void doSomething();//基类方法声明(成员函数)
};
class Subclass :public Baseclass
{
public:
Subclass();//todo子类构造器
~Subclass();//todo子类析构器
};
Baseclass::Baseclass()
{
cout << "1.已进入基类构造器" << endl;
}
Baseclass::~Baseclass()
{
cout << "2.已进入基类析构器" << endl;
}
void Baseclass::doSomething()
{
cout << "3.已进入 基类的成员函数 dosomething " << endl;
}
Subclass::Subclass()
{
cout << "4.已进入子类构造器" << endl;
}
Subclass::~Subclass()
{
cout << "5.已进入子类析构器" << endl;
}
int main()
{
Subclass Sub;
Sub.doSomething();
cout<<"执行完毕 已到达程序尾部"<<endl;
return 0;
//todo析构器将在main函数即将退出时 进行作用
}
总结:
基类的构造器将在子类的构造器调用之前被调用这是由于基类必须在子类之前被初始化的原则所导致的
与构造器的情况相反 基类的析构器将在子类的最后一条语句执行完毕后才被调用(子类的析构器先调用 基类最后调用)
析构器将在main函数即将退出时 进行作用
推荐文章
https://www.jianshu.com/p/67e166c11e52