继承机制中的构造器和析构器

正如前面所说的,C++支持程序员自己写出将创建或销毁一个对象时自动调用的方法,也就是构造器和析构器。

在没有继承机制的情况下,我们很容易理解这些方法在创建或销毁一个对象的时候被调用。但是一旦使用了继承机制,构造器和析构器就变得有点复杂了。

比如基类有个构造器,如Animal(),它将在创造Pig类型的对象时最先被调用,如果Pig类也有一个构造器,它将排在第二个被调用。因此基类必须在子类之前初始化原则!

如果构造器带着输入参数,事情将变得稍微复杂了,例如:

class Animal
{
public:
	Animal(std::string theName);
	std::string name;
};

class Pig : public Animal
{
public:
	Pig(std::string theName);
};

那么我们的方法应该如何定义呢?

Animal::Animal(std::string theName)
{
	name = theName;
}

Pig::Pig(std::string theName) : Animal(theName)
{

}

在子类的构造器里面是没有东西的,直接继承的基类里的。

注意在子类的构造器定义里的“:Animal(theName)”语法含义是:

- 当调用Pig()构造器时(以theName作为输入参数),Animal()构造器也将被调用(theName输入参数将传递给它)。

- 于是我们调用Pig pig(“小猪猪”),将把字符串“小猪猪”传递给Pig()和Animal(),赋值动作将实际发生在Animal()方法里。

#include <iostream>
#include <string>

class Animal
{
public:
	std::string mouth;
	std::string name;

	Animal(std::string theName);
	void eat();
	void sleep();
};

class Pig : public Animal
{
public:
	void climb();
	Pig(std::string theName);
};

class Turtle : public Animal
{
public:
	void swim();
	Turtle(std::string theName);
};

Animal::Animal(std::string theName)
{
	name = theName;
}

Pig::Pig(std::string theName) : Animal(theName)
{
}

Turtle::Turtle(std::string theName) : Animal(theName)
{
}

void Animal::eat()
{
	std::cout << "I'm eatting!" << std::endl;
}

void Animal::sleep()
{
	std::cout << "T'm sleeping!" << std::endl;
}

void Pig::climb()
{
	std::cout << "我会爬树!" << std::endl;
}

void Turtle::swim()
{
	std::cout << "我会游泳!" << std::endl;
}

int main()
{
	Pig pig("小猪猪");
	Turtle turtle("小甲鱼");

	std::cout << "这只猪的名字是:" << pig.name << std::endl;
	std::cout << "我看的视频的作者是:" << turtle.name << std::endl;

	return 0;
}

析构器

在销毁每个对象时,基类的析构器也将被自动调用,但是这些事情编译器会自动替你处理。

因为析构器不需要输入参数,所以根本不需要使用:SuperClassMethod(arguments)语法!

与构造器的情况相反,基类的析构器将在子类的最后一条语句执行完毕后才被调用。

例子:

#include <iostream>
#include <string>

class BaseClass
{
public:
	BaseClass();
	~BaseClass();

	void doSomething();
};

class SubClass : public BaseClass
{
public:
	SubClass();
	~SubClass();
};

BaseClass::BaseClass()
{
	std::cout << "进入基类构造器" << std::endl;
	std::cout << "我在基类构造器里干了什么" << std::endl;
}

BaseClass::~BaseClass()
{
	std::cout << "进入基类析构器" << std::endl;
	std::cout << "我在基类析构器里干了什么" << std::endl;
}

void BaseClass::doSomething()
{
	std::cout << "我干了某些事" << std::endl;
}

SubClass::SubClass()
{
	std::cout << "进入子类构造器" << std::endl;
	std::cout << "我在子类构造器里干了什么" << std::endl;
}

SubClass::~SubClass()
{
	std::cout << "进入子类析构器" << std::endl;
	std::cout << "我在子类析构器里干了什么" << std::endl;
}

int main()
{
	SubClass subclass;
	subclass.doSomething();

	std::cout << "完事,收工" << std::endl;

	return 0;
}

输出如图:

继承机制中的构造器和析构器

应该能看明白了吧