如何写派生类的构造函数:
第一步:完整地写出基类的构造函数,包括:
普通构造函数
默认构造函数(可不写)
复制构造函数(可不写)
第二步:写出派生类的构造函数的原型声明(类内),包括:
类名 (初始化基类1所需要的形参,初始化基类2所需要的形参,……,初始化本类所需要的形参);
第三步:写出派生类的构造函数的实现(类外),包括:
类名 作用于限定符 构造函数名称 (总的形参表):基类1(实参),基类2(实参){}
需要注意的事情:
1、基类的数据成员设置成什么访问类型都可以。
2、基类的构造函数必须写全。
3、声明当中只能写出派生类所需要的总形参表。
4、类的实现原理是这样的,它相当于(可以这样理解,但不能这样写):
类名 作用于限定符 构造函数名称 (总的形参表){
调用基类1的构造函数(实参)
调用基类2的构造函数(实参)
}
讨论:
派生类构造函数的调用者传给构造函数实参,与派生类构造函数的形参表发生形实结合,
在派生类构造函数里面使用形参进行操作,派生类的构造函数调用基类1和基类2的构造函数,
相对于基类的构造函数,派生类里面的“形参”是实参,即派生类将形参传给基类做实参。
“:基类1(实参),基类2(实参)”是一个简便写法,类似于:
“Clock::Clock(int newH, int newM, int newS):hour(newH),minute(newM),second(newS)”
其中hour,minute,second是Clock类的基本数据成员,分别用newH,newM,newS初始化。
然后我们发现这样写能够保证基类的成员被初始化(如果你写在构造函数里面,编译器不知道
你有没有初始化基类成员,这样写以后基类构造函数被调用的位置就确定了,方便检查),所以
我们就规定必须这样写了。
如何写组合类构造函数
由此也可以推出类的组合构造形式。
组合类构造函数形式:
类名:类名(形参表):
对象1(参数),对象2(参数)
……
}
三件事情需要注意:
1、继承中,总形参表后面接的是基类类型名,而在组合类当中总形参表后面接的是你所使用的类的对象名。
2、组合类写非静态数据成员时仍然可以像前面使用简便写法
3、当你想要处理剑士的成员有剑类时,而且初始化剑士的攻击力需要使用到剑类的数据的问题时:
对于剑士来说,剑类是封闭的,你不能直接访问剑类的攻击力,解决办法:
设置剑类攻击力的公有接口或把剑类攻击力设置为公有成员。
用例
下面使用一个简单的RPG游戏作为例子,分为头文件,写类实现的文件,和主函数所使用的文件。
其中powersword类继承了sword类,soilder将powersword作为数据成员。
包含类定义的头文件
//Rpg games.edition1.0,class: Game.
//RPGGAME.h
#ifndef RPGGAME_H
#define RPGGAME_H
#include <string>
using namespace std;
class Game {
public:
int display_1();
int display_2();
private:
};
class sword {
public:
sword(int, int);
int getattack_point();
int display_3();
private:
int attack_point;
int durability;
};
class powersword:public sword {
public:
powersword(int newattack_point, int newdurability, string neweffect_description);
int display_3();
private:
string effect_description;
};
class soilder {
public:
int display_4();
soilder(int newhealthpoint, int newattackpoint, int newattack_point, int newdurability, string neweffect_description) ;
private:
int healthpoint;
int attackpoint;
powersword soilderssword;
};
#endif
包含类实现的文件
//RPGGAME.cpp
#include "RPGGAME.h"
#include <iostream>
using namespace std;
//Send a welcome message to the client.
int Game::display_1()
{
cout << "Welcome to Paper&Pencil" << endl;
return 1;
}
//Send a ending message to the client.
int Game::display_2()
{
cout << "Thanks for playing!" << endl;
return 2;
}
//Sword class including attack point, and its durability.
sword::sword(int newattack_point, int newdurability):
attack_point(newattack_point), durability(newdurability)
{
}
int sword::getattack_point()
{
return attack_point;
}
int sword::display_3()
{
cout << "The information of the sword:" << endl;
cout << "attack point:" << attack_point << " ";
cout << "durability:" << durability << endl;
return 3;
}
powersword::powersword(int newattack_point, int newdurability, string neweffect_description):
sword(newattack_point, newdurability),effect_description(neweffect_description)
{
}
int powersword::display_3()
{
sword::display_3();
cout << effect_description<<endl;
return 3;
}
int soilder::display_4()
{
cout << "The information of the soilder:" << endl;
cout << "His attack point is:" << attackpoint << endl;
cout << "His health point is:" << healthpoint << endl;
soilderssword.display_3();
return 4;
}
soilder::soilder(int newhealthpoint, int newattackpoint, int newattack_point, int newdurability, string neweffect_description):
soilderssword(newattack_point, newdurability, neweffect_description), healthpoint(newhealthpoint)
{
attackpoint = soilderssword.getattack_point() + newattackpoint;
}
主函数所在文件:
#include "RPGGAME.h"
#include <iostream>
#include <string>
using namespace std;
int main() {
Game mygame;
mygame.display_1();
string biggereff;
cout << "please put the effect of the sword." << endl;
getline(cin, biggereff);
soilder mysoilder(100, 20, 20, 10, biggereff);
mysoilder.display_4();
mygame.display_2();
return 0;
}