C++实操 - 关于虚函数的几点说明

关于虚函数的说明如下:

1. 因为虚函数只对类的对象进行调用,所以不能将全局或静态函数声明为虚拟函数。

2. 可以使用virtual关键字在派生类中声明这是一个覆盖基类某个函数的虚函数,但这不是必须的;因为基类的虚函数被子类覆盖后,子类的函数一定是虚函数。

3. 基类中的虚拟函数必须被定义,除非它们是用 pure-specifier 声明的纯虚函数。(关于纯虚函数的更多信息,请参阅抽象类)。

4. 虚函数调用机制可以通过使用范围解析操作符(::)明确限定函数名称来指定具体调用哪个类的函数。

5. 在类的外面定义一个类的虚函数时,不能再添加virtual关键字,否则会编译报错。

6. 虚函数的访问权限只由调用的对象的声明类型来决定。

7. 虚函数调用是按照对象的声明类型是否是虚函数,而不是按照实际对象类型来判断。

第二点的例子说明:

#include <cstdio>

class A {

public:

  virtual void func(){printf("func A.\n");}

};



class B: public A {

public:

  void func(){printf("func B.\n");}

};



int main()

{

  A a;

  B b;

  A * p;



  p = &a;

  p->func();



  p = &b;

  p->func();



  return 0;

}



输出:

func A.

func B.

虽然子类没有使用virtual关键字,但还是虚函数。

第四点例子说明:

#include <cstdio>

class A {

public:

  virtual void func(){printf("func A.\n");}

};



class B: public A {

public:

  void func(){printf("func B.\n");}

};



int main()

{

  A a;

  B b;

  A * p;



  p = &a;

  p->A::func();



  p = &b;

  p->A::func();



  return 0;

}



输出:

func A.

func A.

直接指定调用,就不再和虚函数相关。

而是根据当前对象的声明类型,直接访问此类或其父类的成员函数或成员变量。还有外部访问当然需要public权限。

第五点例子:

class A{

public:

  virtual void func();



};



// virtual void A::func() 会报错

void A::func()

{



}

在类的外面定义其成员函数,不能加virtual关键字,否则编译报错。

第六点例子:

#include <cstdio>

class A {

public:

   virtual void func(){printf("func A.\n");}

};





class B: public A {

private:

  virtual void func(){printf("func B.\n");}

};





int main()

{

  A a;

  B b;

  A * p;





  p = &a;

  p->func();





  p = &b;

  p->func();





  return 0;

}



输出:

func A.

func B.

子类的虚函数是private访问权限,当调用时还是按照父类的访问规则,仍能够public访问。

第七点例子:

#include <cstdio>



class A {

public:

   void func(){printf("func A.\n");}

};



class B: public A {

public:

  virtual void func(){printf("func B.\n");}

};



class C: public B {

public:

  virtual void func(){printf("func C.\n");}

};



int main()

{

  A a;

  B b;

  C c;

  A * pa;

  B * pb;



  pa = &a;

  pa->func();



  pa = &b;

  pa->func();



  pa = &c;

  pa->func();



  pb = &b;

  pb->func();



  pb = &c;

  pb->func();



  return 0;

}



输出:

func A.

func A.

func A.

func B.

func C.

当使用没有虚函数的基类的指针时,即使其子类将此函数覆盖为虚函数,调用时则按照基类的规则而不是虚函数来调用。

相关文摘:

Because virtual functions are called only for objects of class types, you cannot declare global or static functions as virtual.

The virtual keyword can be used when declaring overriding functions in a derived class, but it is unnecessary; overrides of virtual functions are always virtual.

Virtual functions in a base class must be defined unless they are declared using the pure-specifier. (For more information about pure virtual functions, see Abstract Classes.)

The virtual function-call mechanism can be suppressed by explicitly qualifying the function name using the scope-resolution operator (::). Consider the earlier example involving the Account class. 

Remember that, when you are trying to give implementation of a virtual member function, you cannot mark virtual again outside the class definition.

参考:

Virtual Functions | Microsoft Docshttps://docs.microsoft.com/en-us/cpp/cpp/virtual-functions?view=msvc-170

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夜流冰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值