C++ Primer Plus学习笔记(九)类继承

类继承介绍

基本用法

类继承意味着从基类派生出新的类,新的类包含基类的数据和方法,并增加了自己的数据和方法。

class baseplus: public base
{
	
} 

继承类特性

需要继承类特性加入派生类的构造函数、数据成员和方法。
创建派生类对象前,必须创建基类对象,通常采用初始化列表进行赋值。与此对应,派生类析构函数先执行然后基类析构函数执行。

baseplus::baseplus(int a, int b, intc):base(a,b)
{
	element = c;
}
//或者
baseplus::baseplus(int c, cosnt base & a1):base(a1)
{
	element = c;
}

除非调用基类默认构造函数,否则应该显示调用构造函数。

基类引用、指针

由于派生类也属于基类,因此基类引用、指针不需要转换,可指向基类对象、派生类对象,从而可以调用基类方法。基类引用、指针通常可以与虚函数结合使用,从而方便管理,使得调用方法根据对象类型自动确定调用方法。
虚方法使得派生类可以对基类方法重定义,前提是二者的函数形式必须相同(比如不能一个形参为int,一个没有形参)
例如:

class base
{
	public:
	virtual void test() const;//后面const表示该方法不对数据修改
}
class baseplus: public base
{
	virtual void test() const;
}

此时,基类引用、指针可以灵活动态确定调用哪一个的方法

base a(init);
baseplus b(init);
base  & a1 = a;
base &  b1 = b;
a1.test();//调用base的test方法
b1.test();//调用baseplus的test方法

这个方法的实现依赖于(1)虚函数、(2)指针或引用。 按值传递的不存在这个方法,全都转换为基类方法。

虚函数

如上所述,虚函数可以实现派生类的重定义,需要注意的是虚函数的声明需要用关键字virtual,方法的实现不需要virtual关键字
析构函数默认应设置为虚函数。
使用虚函数时,(1)空间消耗:存储地址空间;(2)要执行创建表、查询表的操作。优点是比较灵活,可以重定义方法。
编译器对非虚方法实行静态联编,对虚方法实行动态联编(运行时再确定执行哪个)

派生类方法

派生类方法可以使用基类方法,必须使用作用域解析符 :: 。

void baseplus::test() const
{
	base::test();
	...
}

访问控制 protected

对于外界来说,其功能相当于private;
对于派生类来说,其功能相当于public,可以访问private成员。

抽象基类

抽象基类可以派生出不同的类。
C++使用纯虚函数提供未实现函数,纯虚函数声明结尾为0,。
当类声明包含纯虚函数时,不能创建该类对象。包含纯虚函数的类只能用作基类。

class b
{
virtual	void test() cosnt = 0; // 纯虚函数,类a成为抽象类
}

继承与动态内存分配

派生类未使用new

根据以前知识,若类中使用new动态分配内存,则默认复制构造函数不适用。假定基类使用new动态分配内存,则基类中包含析构函数、复制构造函数和重载复制运算符,但是派生类如果没有使用new,派生类不需要定义显示析构函数、复制构造函数和赋值运算符。

派生类使用new

在此情况下,必须为派生类定义显示析构函数、复制构造函数和赋值运算符。
例如:

class baseplus:: public base
{
	private:
		char * style;
	public;
	...
};

相应的析构函数:

basplus::~baseplus()
{
	delete [] style;
}

复制构造函数:

baseplus::baseplus(const baseolus &r)
{
	style = new char[strlen(rr.style) + 1];
	strcpy(style,r.style);
}

赋值运算符:

baseplus & baseplus::operator=(const baseplus & r)
{
	if(this==&rs)
		return *this;
	base::operator=(r);//复制基类部分
	delete[]style;//删除之前style分配的内存
	label = new char[strlen(r.style)+1];
	strcpy(style,r.style);
	return *this;
}

总之,当基类和派生类都采用动态分配内存时,派生类的构造函数、复制构造函数、复制运算符都必须采用基类的三者来处理基类部分。析构函数:自动完成;构造函数,派生类的构造函数要使用基类的复制构造函数;赋值运算符,采用作用域解析运算符显示调用,如base::operator=®

猜你喜欢

转载自blog.csdn.net/yanrong1095/article/details/83512532