【问题标题】:Virtual function keyword虚函数关键字
【发布时间】:2011-10-26 14:52:06
【问题描述】:

考虑到我想调用适合我的对象的乐趣'类型。看看cmets。

#include <cstdio>
struct A{
    int a;
    A():a(5){}
    virtual int fun(){return a+1;}
};
struct B: public A{
    virtual int fun(){return a+5;} //I put virtual here
//  int fun(){return a+5;} // Any difference if I put virtual before or not?
};
int main(){
    B obj;
    printf("%d\n", static_cast<A>(obj).fun()); // A::fun() called. Why?
    printf("%d\n", static_cast<A&>(obj).fun()); // B::fun() called. As expected
    printf("%d\n", static_cast<A*>(&obj)->fun()); // B::fun() called. As expected
    printf("%d\n", static_cast<A>(B()).fun()); // A::fun() again. Why?
//  printf("%d\n", static_cast<A&>(B()).fun()); //invalid_cast error. Why? 
    printf("%d\n", static_cast<A*>(&B())->fun()); //It works! B::fun() call
    return 0;
}

【问题讨论】:

  • 最后的&amp;B() 是编译器扩展,它不是有效的 C++。尝试找到将编译器置于一致模式的设置。
  • @Luc Compiler 警告我我取了临时地址,我认为没关系
  • 你认为好的与否与什么是有效的 C++ 无关 :) 请注意,如果编译器确实警告过你,那么它是一个符合标准的编译器。您可以忽略我之前的评论(我强烈建议您编写有效的 C++)。
  • 您可以临时参考非成本参考。倒数第二个可以是printf("%d\n", static_cast&lt;A const &amp;&gt;(B()).fun()); /* if you make fun() const */
  • @Luc 我想如果有什么东西放在内存中我可以/应该使用它:D

标签: c++ function inheritance virtual


【解决方案1】:

如果基类中的对应函数是虚函数,则派生类中的覆盖函数被隐式声明为“虚函数”。只需确保您获得完全相同的签名,否则您可能会无意中隐藏原始函数并声明一个新函数!

在 C++0x 中,随意使用 override 说明符。

你的两个“为什么?”问题是因为切片;你正在制作A 类型的新的、复制切片的对象。请注意,在B x; static_cast&lt;A&gt;(x); 中,演员表与A(x) 相同。

【讨论】:

  • 谢谢,看看最后两个printfs,为什么最后一个没问题(带指针和static_cast),但是之前的转换无效(转换到引用)。
  • 您不能对临时对象进行非常量引用。改为转换为 const 引用。
  • const_cast&lt;A&amp;&gt;(static_cast&lt;const A&amp;&gt;(B())).fun() 有效。有没有其他方法可以调用 const 对象的非常量函数?
  • @all 使用 C++0x 你可以做到to_value(B()).fun(),假设template&lt;typename T&gt; T&amp; to_lvalue(T&amp;&amp; t) { return t; }。
【解决方案2】:

在派生类中被覆盖的成员函数之前保留 virtual 关键字是可选的。运行时多态性仅适用于指针或引用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-30
    • 2019-08-21
    • 2015-05-22
    • 2019-05-31
    • 1970-01-01
    • 1970-01-01
    • 2011-06-21
    相关资源
    最近更新 更多