派生类与父类的初始化

(1)派生类继承了基类(父类)的包括成员函数和属性的所有性质,只是private部分的东西不能直接调用(不可见),需要通过使用父类的成员函数才能接触到父类属性,如果是没被子类重写过的父类成员函数,可以直接用原名调用,如果是被子类重写的父类函数,调用时应加上作用域解析运算符(如Time::),否则默认调用的是本类(也就是子类)的被重写之后的版本。

(2)生成派生类对象时必须是首先创建基类的对象,所以构造函数和初始化也是先从基类开始的,所以经常需要在派生类的构造函数中使用到成员初始化列表把通过派生类构造函数传进来的参数再传给父类构造函数进行父类属性的初始化。

(3)释放对象的顺序也创建对象的顺序相反,也就是先执行派生类的析构函数,才执行父类的析构函数。

派生类与父类的初始化派生类与父类的初始化派生类与父类的初始化派生类与父类的初始化



这里我写了一个简单的示例程序:

Time.h:

#pragma once
/*
* Time.h
*
*  Created on: 2016-4-16
*      Author: lvlang
*/

#ifndef TIME_H_
#define TIME_H_

#include <iostream>
using namespace std;

class Time
{
private:
	int hours;
	int minutes;
	int seconds;
	static int count;
public:
	Time();
	Time(int h = 0, int m = 0, int s = 0);//如果不传入值则自动初始化为0
	void AddHr(int h);
	void AddMin(int m);
	void reset(int h = 0, int m = 0, int s = 0);
	void show()const;//const在这里表明本函数不会也不能去修改属性
	Time sum(const Time &t)const; //传引用比传值效率高
	Time operator+(const Time &t)const;
	const Time &max(const Time &t1, const Time &t2);
	~Time();
};


#endif /* TIME_H_ */



Time.cpp

/*
* Time.cpp
*
*  Created on: 2016-4-16
*      Author: lvlang
*/

#include "Time.h"
#include <cstdlib>//支持abort()函数

int Time::count = 0;

Time::Time()
{
	hours = minutes = seconds = 0;
	count++;
}

Time::Time(int h, int m, int s)
{
	if (h < 0 || h > 24 || m > 60 || m < 0 || s > 60 || s < 0)
	{
		cout << "初始化参数输入有误,程序终止!" << endl;
		abort();
	}
	hours = h;
	minutes = m;
	seconds = s;
	count++;

}

void Time::AddHr(int h)
{
	hours = (hours + h) % 24;
}

void Time::AddMin(int m)
{
	int temp = this->minutes + m;
	this->hours += temp / 60;
	this->minutes = temp % 60;
}

void Time::reset(int h, int m, int s)
{
	if (h < 0 || h > 24 || m > 60 || m < 0 || s > 60 || s < 0)
	{
		cout << "参数输入有误,程序终止!" << endl;
		abort();
	}
	this->hours = h;
	this->minutes = m;
	this->seconds = s;
}

void Time::show()const
{
	cout << "Hours: " << this->hours << " Minutes: " << this->minutes 
		<< " Seconds: " << this->seconds <<" Count: "<<count<< endl;
}
Time Time::sum(const Time &t)const
{
	Time temp(0,0,0);
	int ts = (this->seconds + t.seconds) / 60;
	temp.seconds = (this->seconds + t.seconds) % 60;
	temp.minutes = (this->minutes + t.minutes + ts) % 60;
	int tm = (this->minutes + t.minutes + ts) / 60;
	temp.hours = (this->hours + t.hours + tm) % 24;
	return temp;
	//return *this;//返回当前对象(this为指向当前对象的指针)
}

Time Time::operator+(const Time &t)const
{
	Time temp(0,0,0);
	int ts = (this->seconds + t.seconds) / 60;
	temp.seconds = (this->seconds + t.seconds) % 60;
	temp.minutes = (this->minutes + t.minutes + ts) % 60;
	int tm = (this->minutes + t.minutes + ts) / 60;
	temp.hours = (this->hours + t.hours + tm) % 24;
	return temp;//return之后会自动调用一次析构函数把temp的空间回收
}

const Time& Time::max(const Time &t1, const Time &t2)
{
	return t1;
}

Time::~Time()
{
	cout << "Time析构函数被调用" << endl;
}



MyTime.h

#pragma once

#ifndef MYTIME_H
#define MYTIME_H
#include "Time.h"

class MyTime : public Time
{
private:
	int year;
public:
	MyTime(int y, int h, int m, int s);
	~MyTime();
	void show()const;//重写或者说覆盖
	//重载是指具有相同的函数名,但具有不同的参数形式,如运算符重载
};

#endif


MyTime.cpp

#include "MyTime.h"

MyTime::MyTime(int y, int h, int m, int s) : Time(h,m,s)
//成员初始化列表,“:Time(h,m,s)”表示先拿h,m,s的值去初始化基类Time的属性(调用父类构造函数),然后才初始化MyTime类
{
	year = y;
	Time::show();//若不用Time::则默认使用MyTime类的show重写函数	
	AddHr(6);
	Time::show();//若不用Time::则默认使用MyTime类的show重写函数	
}

void MyTime::show()const
{
	cout <<"Year: "<<year <<endl;
}

MyTime::~MyTime()
{
	cout << "这是MyTime析构函数" << endl;
}


main.cpp

#include "MyTime.h"

int main()
{
	/*Time time(10,10,10);
	time.show();
	time.AddHr(2);
	time.show();
	time.AddMin(20);
	time.show();
	Time t(1, 1, 1);
	t.show();
	t.reset(9, 9, 9);
	t.sum(time);
	t.show();*/
	
	/*t = t + time;
	t.show();*/

	MyTime mytime(2000, 12, 12, 12);
	mytime.show();
	Time time(1, 1, 1);
	time.show();

	return 0;
}


派生类与父类的初始化