类继承的基础语法,基础知识点,派生类和基类之间的特殊关系
//class.h
#pragma once
#include<string>
using std::string;
#ifndef _CLASS_H_
#define _CLASS_H_
//基类
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 ResetTbale(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
// fuc.cpp
#include"class.h"
#include<iostream>
//基类的实现
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::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)
{
}
// main.cpp
#include<iostream>
#include"class.h"
int main()
{
using std::cout;
using std::endl;
TableTennisPlayer player1("Tare", "Boomdea", false);
Ratedplayer rplayer1(1140, "Mallory", "Duck", true);
rplayer1.Name();
if (rplayer1.HasTable())
{
cout << ": has a table" << endl;
}
else
{
cout << ": hasn't a table" << endl;
}
player1.Name();
if (player1.HasTable())
{
cout << ": has a table" << endl;
}
else
{
cout << ": hasn't a table" << endl;
}
cout << "Name: ";
rplayer1.Name();
cout << "; Rating: " << rplayer1.Rating() << endl;
//使用复制构造函数来创建基类对象
Ratedplayer rplayer2(1212, player1);
cout << "Name: ";
rplayer2.Name();
cout << "; Rating: " << rplayer2.Rating() << endl;
system("pause");
return 0;
}
知识点:
1.派生类:
1):语法: class derivedclassname : public classname
eg:
class Ratedplayer :public TableTennisPlayer
{
private:
public:
};
2):派生类对象包含基类对象:基类的公有函数成为派生类的一部分,基类数据也成为派生类的一部分,但要访问基类的私有数据,仍需要通过基类的公有函数。
3):派生类就相当于在基类的基础上再加上额外的私有数据和公有函数。
2.派生类构造函数的要点:
1):首先创建基类对象(通过成员初始化列表来实现)。
2):派生类构造函数应通过成员初始化列表将基类信息传递给基类构造函数。
3):派生类构造函数应初始化派生类新增的数据成员。
4):若不显式的调用相应的构造函数和复制构造函数,则程序会自动调用默认的构造函数和复制构造函数来创建基类对象。
eg:
//声明
Ratedplayer(unsigned int r = 0, const string& fn = "none", const string& ln = "none", bool ht = false);
//使用基类的构造函数来创建基类对象
Ratedplayer(unsigned int r, const TableTennisPlayer& tp);
//使用基类的复制构造函数来创建基类对象
//实现
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)
{
}
3.对于基类对象和派生类对象,释放对象的顺序与创建对象的顺序相反,即先执行派生类的析构函数,再执行基类的析构函数。(仍然满足先进后出)-- 基类对象先被创建
4.派生类与基类之间的特殊关系
1):派生类对象可以使用基类的公有方法。
2):基类指针可以在不显式类型转换的情况下指向派生类对象(相反方向不允许)。
3):基类引用可以在不显式类型转换的情况下引用派生类对象(相反方向不允许)。
4):可以将基类对象初始化为派生类对象(调用基类的复制构造函数),也可以将派生对象赋给基类对象(调用基类的重载赋值运算符)。 -- 基类属于派生类(原理)
eg:
//派生类与基类之间特殊的关系
TableTennisPlayer& rt = rplayer1;
TableTennisPlayer* pt = &rplayer2;
rt.Name();
pt->Name();
//使用派生类来初始化基类
TableTennisPlayer T1(rplayer1);
//将派生类赋给基类
TableTennisPlayer T2;
T2 = rplayer2;