一、抽象类与动态类型转换
1、访问控制属性
类的定义中有public、private和protected三个关键字,其中private关键字说明类中成员为私有成员,只能在类内的函数访问;public成员为公有成员,可被任何其他类访问,protected关键字是保护属性,保护属性的数据或函数可被派生类成员访问。
class A
{
public:
int i;
protected:
int j;
private:
int k;
};
class B : public A//公有继承
{
public:
void display()
{
std::cout << i << std::endl;//ok;
std::cout << j << std::endl;//ok;
std::cout << k << std::endl;//error
}
};
int main()
{
A a;
td::cout << a.i << std::endl;//ok;
std::cout << a.j << std::endl;//error;
std::cout << a.k << std::endl;//error
return 0;
}
继承分为公有继承、私有继承和保护继承;
//基类
class A
{};
//公有继承
class B : public A
{};
//私有继承
class C : private A
{};
//保护继承
class D : protected A
{};
三种继承的区别:
//公有继承 对象访问 成员访问
public --> public Y Y
protected --> protected N Y
private --> private N N
//保护继承 对象访问 成员访问
public --> protected N Y
protected --> protected N Y
private --> protected N N
//私有继承 对象访问 成员访问
public --> private N Y
protected --> private N Y
private --> private N N
2、抽象类与纯虚函数
当类太抽象以至于无法实例化就叫做抽象类。抽象类不能实例化(创建对象)。
当基类中的函数要求子类实现它时,此函数叫做抽象函数或纯虚函数。
//基类
class Bike
{
public:
virtual string getBikeName() = 0;//抽象函数/纯虚函数;
};
class MountainBike : public Bike
{
public:
string getBikeName//子类将其实例化;
{
return "MountainBike";
}
};
包含纯虚函数(抽象函数)的类叫做抽象类。上述例子中Bike类为抽象类,不能实例化对象。
3、动态类型转换
动态类型转换使用:dynamic_cast运算符。
作用:a、沿继承层级向上、向下及侧向转换到类的指针和引用。
转指针失败时返回nullptr,转引用失败则抛出异常。
//基类
class Bike
{
public:
virtual string getBikeName() = 0;//抽象函数/纯虚函数;
};
class MountainBike : public Bike
{
public:
string getBikeName()//子类将其实例化;
{
return "MountainBike";
}
};
class RacingBike : public Bike
{
public:
string getBikeName()
{
return "RacingBike";
}
};
void print(Bike &bike)
{
std::cout << "the bike is " << Bike.getBikeName() << std::endl;
Bike* p = &bike;
MountainBike* c = dynamic_cast<MountainBike*>(p);//动态类型转换为子类;
if (c != nullptr)
{
std::cout << "the bike is" << c->getBikeName() << std::endl;
}
}
4、上转和下转
将派生类型指针赋值给基类类型指针为上转;反之为下转。
上转可不使用dynamic_cast而隐式转换;
下转必须显式执行。
上面的方法简称为:父上,子下;上转隐,下转显。
之所以有上述规则,是因为可将派生类对象截断,只使用继承来的信息,但不能将基类对象加长,无中生有变出派生类对象。
5、typeid(运行时查询类型的信息)
运算符typeid返回一个type_info对象的引用,typeid(TYPE).name()返回实现定义。
#include <iostream>
#include <typeinfo>
A a{};
auto& t = typeid(a);
if(typeid(A) == t)
{
std::cout << "t has type " << t.name() << std::endl;
}