C++类简单学习(四)

1.类继承:公有继承(class RatedPlayer : public TableTennisPlayer)
使用公有派生,基类的公有成员将成为派生类的公有成员;基类的私有部分也将成为派生类的一部分,但只能通过基类的公有和保护方法访问。
派生类需要有自己的构造函数,必须给新成员以及继承的成员提供数据。派生类构造函数必须使用基类构造函数:
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;
}
派生类对象可以访问基类的公有接口,基类指针可以在不进行显式类型转换的情况下指向派生类对象,基类引用可以在不进行显式类型转换的情况下引用派生类对象。这样的话可以用派生类给基类对象赋值或者初始化,只需先转化为基类指针或引用,然后通过隐式复制构造函数或者隐式赋值运算符即可。
RatedPlayer rplayer1(1140, “Mallory”, “Duck”, true);
TableTennisPlayer & rt = rplayer1;
TableTennisPlayer * pt = &rplayer1;
rt.Name();
pt->Name();
该基类指针或者基类引用只能用于调用基类方法,不能调用派生类方法。
同时,不能把基类对象和地址赋给派生类引用和指针。这样做可能造成基类对象访问派生类函数,没有意义。
2.多态:方法的行为取决于调用该方法的对象–多态
两种实现机制:
1)在派生类中重新定义基类方法
2)使用虚方法
在函数前加上关键字virtual,表明这种方法为虚方法。没有关键词virtual,程序将根据引用类型或者指针类型选择方法;有了这个关键字,程序将根据引用或者指针指向的对象的类型选择方法。如果要实现多态,通常将基类与派生类的函数都加上virtual,另外在基类的析构函数前加上virtual,将其转变为虚析构函数也是一种惯例。虚析构函数可以保证正确的析构函数序列被调用。自动判断该析构派生类对象还是基类对象。常见的应用场景,指向基类的指针数组。
3.编译器对非虚方法使用静态联编,虚方法使用动态联编,在运行时再决定调用哪个函数。
4.虚函数的一些注意事项:
1)构造函数不能是虚函数。
2)析构函数应当是虚函数。(良好的编程习惯)
3)友元函数不能是虚函数。
**4)重载, 重写,重定义的关系:
(1)成员函数重载特征:
a 相同的范围(在同一个类中)
b 函数名字相同
c 参数不同
d virtual关键字可有可无
(2)重写(覆盖)是指派生类函数覆盖基类函数,特征是:
a 不同的范围,分别位于基类和派生类中
b 函数的名字相同
c 参数相同
d 基类函数必须有virtual关键字
(3)重定义(隐藏)是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
a 如果派生类的函数和基类的函数同名,但是参数不同,此时,不管有无virtual,基类的函数被隐藏。
b 如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有vitual关键字,此时,基类的函数被隐藏。**
转载出处:http://www.cnblogs.com/weizhixiang/articles/5760286.html
3.访问控制:protected
private和protected之间的区别只有在基类派生的类中才会表现出来,派生类的成员可以直接访问基类的保护成员,但不能直接访问基类的私有成员。因此,对于外部世界来说,保护成员的行为与私有成员相似;但对于派生类来说,保护成员的行为与公有成员相似。一般来说,数据成员设置为private,函数如果有需要可以设置为protected。
4.抽象基类(abstract base class, ABC)。抽象基类必须至少包含一个纯虚函数,这样的类不能创建对象,只能用作基类。纯虚函数的特点:声明的结尾处为=0;在实现文件定不定义该函数都可以。总之,ABC描述的是至少使用一个纯虚函数的接口,从ABC派生出的类将根据派生类的具体特征,使用常规虚函数来实现这种接口。
5.一个输入输出数据格式的常用技巧:
声明文件:
class ABC
{

protected:
struct Formatting
{
std::ios_base::fmtflags flag;
std::streamsize pr;
};
Formatting SetFormat() const;
void Restore(Formatting& f) const;

}
实现文件:
ABC::Formatting ABC::SetFormat() const
{
//set up ###.## format
Formatting f;
f.flag = cout.setf(ios_base::fixed, ios_base::floatfield);
f.pr = cout.precision(2);
return f;
}

void ABC::Restore(Formatting& f) const
{
cout.setf(f.flag, ios_base::floatfield);
cout.precision(f.pr);
}
6.当基类和派生类都采用动态内存分配时,派生类的析构函数、复制构造函数、赋值运算符都必须使用相应的基类方法来处理基类元素。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值