当前位置:   article > 正文

C++的继承和派生(二)派生类的构造函数和析构函数_第2关:派生类的构造和析构函数

第2关:派生类的构造和析构函数

派生类的构造函数

  • 在上一篇博客中提到,基类的成员函数可以被继承,可以通过派生类的对象来访问,但这仅仅指的是普通的成员函数,而类的构造函数不能被继承
  • 如何解决:
    在派生类的构造函数中调用调用基类的构造函数,注意,不是直接在派生类构造函数体中直接调用基类的构造函数,这样只会创建一个临时对象,并不能达到初始化的目的。所以为了初始化基类成员,需要在派生类构造函数的初始化列表显示、调用基类的构造函数

看下面的代码

class Person{
privatechar * m_name;
public:
	Person(char* name):m_name(name) { }
};

class Student :public Person {
private:
	int m_age;
public:
	Student(char* name,int age) :Person(name) ,m_age(age){}

	void Display() {
		cout << m_age << " " << m_name << endl;
	}
};

int main() {
	Student stu("少爷",18);
	stu.Display();

	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

运行结果

18 少爷
  • 1
  • 继承中构造函数的调用原则

    1、子类对象创建时会首先调用父类的构造函数
    2、父类的构造函数在执行结束后,在执行子类的构造函数
    3、当父类的构造函数有参数时,需要在子类的初始化列表中显示调用
    4、派生类不能调用间接基类的构造函数

派生类的析构函数

  • 和构造函数类似,析构函数也不能被继承,与构造函数不同的是,在派生类的析构函数中不用显式的调用基类的构造函数,因为一个类只有一个析构函数,编译器知道该如何选择,无需程序员干涉。但是析构函数的执行顺序与构造函数相反

看下面的代码

class Person{
private:
	char * m_name;
public:
	char * m_name;
	Person(){
		cout << "Person()" << endl;
	}
	~Person(){
		cout << "~Person()" << endl;
	}
};

class Student :public Person {
private:
	int m_age;
public:
	Student(){
		cout << "Student()" << endl;
	}
	~Student(){
		cout << "~Student()" << endl;
	}
};

int main() {
	Student stu;
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

运行结果

Person()
Student()
~Student()
~Person()
  • 1
  • 2
  • 3
  • 4

  • 再补充个知识点:
    当对象建立在栈上面时,是由编译器分配内存空间的,调用构造函数来构造栈对象。当对象使用完后(离开作用域,所占内存自动释放),然后会自动调用析构函数。编译器管理了对象的整个生命周期。如果编译器无法调用类的析构函数,情况会是怎样的呢?比如,类的析构函数是私有的,编译器无法调用析构函数来释放内存。
    编译器在为类对象分配栈空间时,会先检查类的析构函数的访问性,如果类的析构函数是私有的,则编译器不会在栈空间上为类对象分配内存。因此,将析构函数设为私有,类对象就无法建立在栈上了。这样就只能使用new操作符来建立对象,构造函数是公有的,可以直接调用。类中必须提供一个destory函数,来进行内存空间的释放。类对象使用完成后,必须调用destory函数。

请看下面的代码

class Human{
public :
	void test(){
		printf("human...\n");
	}
	void destroy(){
		delete this;
	}

private:
	~Human(){
		printf("delete successful!...\n");
	}
};

int main(){
	Human* hp=new Human();
	hp->test();
	hp->destroy();
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

运行结果

human...
delete successful!...

  • 1
  • 2
  • 3
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/106046
推荐阅读
相关标签
  

闽ICP备14008679号