公司网站做好了还需,免费云服务器网站有哪些,企业管理软件排行榜前十,关键词查询优化虚函数和多态性
派生类中与基类重名的成员
如果派生类的成员与基类的成员重名#xff0c;则派生类的成员将隐藏同名的基类成员。
/*正方形类#xff0c;基类*/
class Square
{
protected:double L;
public:Square() :L{ 4 } {};Square(double a) :L{ a } {}double GetArea…虚函数和多态性
派生类中与基类重名的成员
如果派生类的成员与基类的成员重名则派生类的成员将隐藏同名的基类成员。
/*正方形类基类*/
class Square
{
protected:double L;
public:Square() :L{ 4 } {};Square(double a) :L{ a } {}double GetArea() const /*矩形面积*/{return L * L;}double GetGirth() const /*矩形周长*/{return 4 * L;}
};
/*矩形类派生类*/
class Rectangle : public Square
{
protected:double W 0;
public:Rectangle() default;Rectangle(double a, double b) : Square{ a }, W{ b } {}double GetArea() const /*矩形面积*/{//重定义从基类继承的成员函数return L * W;}double GetGirth() const /*矩形周长*/{//重定义从基类继承的成员函数return 2 * (L W);}
};int main(void)
{Rectangle Re{ 7,3 };cout Re.GetArea() endl; //调用派生类自定义的GetArea()成员函数cout Re.GetGirth() endl;//调用派生类自定义的GetGirth()成员函数return 0;
}我们可以通过作用域运算符来使用一个被隐藏的基类成员。 double GetArea() const /*矩形面积*/{if (L W)return Square::GetArea(); //调用基类版本的GetArea()函数return L * W;}虚函数
如果基类希望其派生类覆盖从基类继承的函数则基类应当将该函数声明为虚函数。
任何构造函数之外的非静态函数都可以是虚函数。关键字 virtual 只能出现在类内部的声明语句之前而不能用于类外部的函数定义。如果基类把一个函数声明成虚函数则该函数在派生类中隐式地也是虚函数。
/*正方形类基类*/
class Square
{
protected:double L;
public:Square() :L{ 4 } {};Square(double a) :L{ a } {}virtual double GetArea() const /*矩形面积*/{//虚函数return L * L;}virtual double GetGirth() const /*矩形周长*/{//虚函数return 4 * L;}
};C11新标准允许派生类显式地注明它使用某个成员函数覆盖了它继承的虚函数。 具体做法是在形参列表后面、或者在 const 成员函数的 const 关键字后面、或者在引用成员函数的引用限定符后面添加一个关键字 override。
在派生类中重新定义的虚函数其函数名函数类型函数参数个数和类型必须与基类的虚函数相同。如果虚函数使用默认实参则基类和派生类中定义的默认实参最好一致。
/*矩形类*/
class Rectangle : public Square
{
protected:double W 0;
public:Rectangle() default;Rectangle(double a, double b) : Square{ a }, W{ b } {}double GetArea() const override /*矩形面积*/{return L * W;}double GetGirth() const override /*矩形周长*/{return 2 * (L W);}
};可以通过基类的指针或引用来访问派生类中与基类同名的成员函数。
int main(void)
{Cube cube{2};cout cube.GetVolume() endl;Rectangle Re{ 3,3 };cout 矩形面积 Re.GetArea() endl;cout 矩形周长 Re.GetGirth() endl;Square * S Re;cout S-GetArea() endl; //调用派生类的GetArea()版本cout S-GetGirth() endl;//调用派生类的GetGirth()版本return 0;
}虚函数的作用是允许在派生类中重新定义与基类同名的函数并且可以通过基类指针或引用来访问基类和派生类中的同名函数。 需要说明的是当一个类带有虚函数时编译系统会为该类构造一个虚函数表它是一个指针数组存放每个虚函数的入口地址。
虚析构函数
最好把基类的析构函数声明为虚函数。 将基类的析构函数声明为虚函数时由该基类所派生的所有派生类的析构函数也都自动成为虚函数即使派生类的析构函数与基类的析构函数名字不同。 构造函数不能声明为虚函数。 这是因为在执行构造函数时类对象还未完全建立过程也无法把函数与类对象绑定。
多态性
在C中多态性表现形式之一是具有不同功能的函数可以用同一个函数名这样就可以实现用一个函数名调用不同内容的函数。 从系统实现的角度来看多态性分为两类
静态多态性编译时的多态性通过函数重载和运算符重载实现。动态多态性运行时的多态性通过虚函数实现。
静态关联与动态关联
确定调用的具体对象的过程称为关联binding即把一个函数名与一个类对象捆绑在一起建立关联。 静态关联在编译阶段将函数名与类名“绑定”。 动态关联在运行阶段将函数名与类名“绑定”。
纯虚函数和抽象基类
纯虚函数
纯虚函数pure virtual function纯虚函数是在声明虚函数时被“初始化”为 0 的函数。 声明纯虚函数的一般形式
virtual 函数类型 函数名参数列表 0;纯虚函数只有函数名字而不具备功能。 纯虚函数的作用是在基类中为其派生类保留一个函数名字以便派生类根据需要对它进行定义。
抽象基类
含有或者未经覆盖直接继承纯虚函数的类是抽象基类abstract base class。 抽象基类负责定义接口而后续的其他类可以覆盖该接口。 值得注意不能定义一个抽象基类的对象。 一个简单的抽象基类
/*形状类*/
class Shape
{
public:virtual double GetArea() 0; /*求面积*/virtual double GetGirth() 0; /*求周长*/
};派生类
/*圆形类*/
class Circular : public Shape
{
private:const static double PI;double R 0;
public:Circular() default;Circular(double r);double GetArea() const override; /*圆面积*/double GetGirth() const override; /*圆周长*/
};
const double Circular::PI 3.14;Circular::Circular(double r) : R{ r } {}
/*圆面积*/
double Circular::GetArea() const
{double S PI * R * R;return S;
}
/*圆周长*/
double Circular::GetGirth() const
{double L 2 * PI * R;return L;
}通过基类的指针或引用来访问虚函数。
int main(void)
{//Shape Re; 不能定义一个抽象基类的对象。Circular Cir{ 10 };Shape * S Cir;cout 圆面积 S-GetArea() endl;cout 圆周长 S-GetGirth() endl; return 0;
}