1、派生类对象可以使用基类的方法,条件是方法不是私有的
RatedPlayer rplayer(1140,"Mallory","Duck",true);
rplayer.Name();
2、基类指针可以在不进行显示类型转换的情况下指向派生类对象
3、基类引用可以在不进行显式类型转换的情况下引用派生类对象
RatedPlayer rplayer1(1140,"Mallory","Duck",true);
TableTennisPlayer &rt=rplayer;
TableTennisPlayer *pt=&rplayer;
rt.Name();//引用
pr->Name();//指针
然而基类指针或引用智能用于调用基类方法,因此不能使用rt或pt来调用派生类的ResetRanking方法。
通常情况下,C++ 要求引用和指针类型与赋给的类型匹配,但这一规则对继承来说是例外。不可以将基类对象和地址赋给派生类的引用和指针。
4、对于形参为指向基类的指针的函数,也存在相似的关系(可以指向基类对象或派生类对象)。它可以使用基类对象的地址或派生类对象的地址作为实参。
void Wohs(const TableTennisPlayer*pt);
...
TableTennisPlayer player1("Tara","Boomdea",false);
RatedPlayer rplayer(1140,"Mallorty","Duck",true);
Wohs(&player1);
Wohs(&rplayer1);
5、将基类对象初始化为派生类对象
假设有这样的代码:
RatedPlayer olaf1(1840,"olaf","loaf",true);
TableTennisPlayer olaf2(olaf1);
要将基类对象olaf2初始化为派生类对象olaf1,匹配的构造函数原型:
TableTennisPlayer(const RatedPlayer&)//但是这样的原型是不存在的
虽然类定义中不存在这样的构造函数,但存在隐式复制构造函数:
TableTennisPlayer(const TableTennisPlayer &);//形参是基类引用
因为形参是基类引用,所以可以引用派生类这样将基类对象olaf1初始化为派生类对象olaf2时,将使用这个隐式的复制构造函数,它可以复制firstname,lastname,hasTable成员。
6、可以将派生来对象赋值给基类对象
RatedPlayer olaf1(1840,"olaf","loaf",true);
TableTennisPlayer winner;
winner =olaf1;
在这种情况下,程序将使用隐式重载赋值运算符:
TableTennisPlayer& operateor=(const TableTennisPlayer &)const;
形参是基类的引用,因此可以引用派生类对象。因此olaf1的基类部分被复制给winner。
tabnn0.h头文件类的声明
#ifndef TABTENN1_H_
#define TABTENN1_H_
#include<string>
using std::string;
class TableTennisPlayer{//基类
private:
string firstname;
string lastname;
bool hasTable;
public:
TableTennisPlayer(const string &fn = "none", const string &ln = "none", bool ht = false);
void Name()const;
bool HasTable()const{ return hasTable; };
void TesetTable(bool v){ hasTable = v; };
};
class RatedPlayer :public TableTennisPlayer//派生类
{
private:
unsigned int rating;
public:
RatedPlayer(unsigned int r = 0, const string &fn = "none", const string &ln = "none", bool ht = false);
RatedPlayer(unsigned int r, const TableTennisPlayer&tp);
unsigned int Rating()const { return rating; }
void ResetRating(unsigned int r){ rating = r; }
};
#endif
tabtnn1.cpp类的实现
#include<iostream>
#include"tabtenn1.h"
//用初始化列表直接使用string的赋值构造函数将firstname初始化为fn
TableTennisPlayer::TableTennisPlayer(const string &fn, const string &ln, bool ht) :firstname(fn), lastname(ln), hasTable(ht){}
void TableTennisPlayer::Name()const
{
std::cout << lastname << "," << firstname;
}
//RatedPlayer methods
RatedPlayer::RatedPlayer(unsigned int r, const string &fn, const string &ln, bool ht) :TableTennisPlayer(fn, ln, ht)
{
rating = r;
}
RatedPlayer::RatedPlayer(unsigned int r, const TableTennisPlayer &tp) : TableTennisPlayer(tp), rating(r)
{}
usett1.cpp主程序
#include<iostream>
#include"tabtenn1.h"
int main()
{
using std::cout;
using std::endl;
TableTennisPlayer player1("Tara", "Boomda", false);//使用c风格字符串初始化string对象时,将自动调用将const char*作为参数的构造函数
RatedPlayer rplayer1(1140, "Mallory", "Duck", true);
rplayer1.Name();
if (rplayer1.HasTable())
cout << ":has a table.\n";
else
cout << ":hasn't a table.\n";
player1.Name();
if (player1.HasTable())
cout << ":has a table";
else
cout << ":hasn't a table.\n";
cout << "Name:";
rplayer1.Name();//派生类使用基类方法
cout << ";Rating:" << rplayer1.Rating() << endl;
RatedPlayer rplayer2(1212, player1);
cout << "Name: ";
rplayer2.Name();
cout << ";Rating: " << rplayer2.Rating() << endl;
return 0;
return 0;
}