C ++虚拟与否?

时间:2011-12-05 15:36:28

标签: c++ inheritance virtual

为什么要在具有两个以上级别的继承层次结构中声明非虚函数?有人可以给我一个例子吗?

我知道差异是什么,发生了什么,但我无法理解为什么以及何时想要这样做。

5 个答案:

答案 0 :(得分:6)

从语义的角度来看:这样就无法覆盖。

从实际角度来看:如果没有虚函数,则不需要vptr,因此每个实例占用的内存略少。另外,正如@Billy在评论中所说,这意味着不会间接调用成员函数。

答案 1 :(得分:2)

这样做的主要原因是,当你创建一个虚拟方法时,你会告诉子类“继续并在这里修改行为”。执行此操作时,您将限制更改基类的能力。基本上,根据基类的实现细节,子类最终很容易结束,当一个人试图改变基类时,打破一个不可知的大量代码。

需要将类设计为继承自己的类,并在设计中采取措施进行未来验证。您不希望对子类之间没有变化的方法进行这样的努力和考虑。

答案 2 :(得分:2)

第一个问题是为什么你想要一个继承层次结构 超过两个级别?最常见的继承层次结构会 当然是一个抽象的基类和一个级别的类 从中衍生出来。 (至少在使用派生来实现时 OO继承 - 用于C ++派生并不罕见 其他的东西。)

有两种频繁的模式,其中更深层次的继承层次结构 确实发生了。第一种情况发生在扩展接口时;在实践中, 这与从单一来源之间没有太大区别 抽象基础,从类派生是错误的 无论如何提供实施。第二个是哪里的 可以使用模板方法模式自定义实现。和 在这种情况下,您真的想呈现实现 其中的函数final:只应继承此类的任何人 实现用于定义自定义的新虚函数; 否则,你可能无法保证所有必要的不变量。

答案 3 :(得分:1)

您希望阻止派生类覆盖它,因为......

  1. 虚函数将类的一部分暴露给您可能不希望公开的派生类 - 如果派生类重写此方法,则更改调用函数的方式和时间可能会破坏派生类。
  2. 表现/内联。如果事情真的对性能至关重要,那么基类中的虚拟getter函数就会很糟糕。
  3. 您正在从(基类)构造函数中调用该函数,因此重写该函数毫无意义。 (当从基类构造函数调用时,将始终调用函数的基类版本。)

答案 4 :(得分:0)

/ *我们考虑为什么不需要在多级中声明所有函数     继承为虚拟,因为有一些功能/动作必须是     仅由BASE CLASS执行。     希望你通过这个简单的例子来理解     在这里家长可以看到有孩子的报告卡,可以在上面签名。     而Big_brother只能阅读报告但不能签名,     同样small_brother也不能签名但可以阅读;     * /

#include<cstring>
#include<iostream>
using namespace std;

class parent
{
private:
    int signeture;
protected:
    int read;
public:
    parent():read(0),signeture(0){}
    void sign()
    {
    signeture=1;
    cout<<"\nparent sign";
    }
    virtual void readReport()
    {
    cout<<"\nDAD can also read"<<read;
    }
};


class big_brother:public parent
{
public:
void readReport()
{
    read=3;
    cout<<"\nbig brother card"<<read;
}
//some other function which only Big_brother can performed are 
//declared here asnon_virtual

};



class small_brother:public big_brother
{
public:
void readReport()
{
    read=4;
    cout<<"\n small brothers card"<<read;

}
};
int main()
{
parent x;
big_brother y;
small_brother z;
x.readReport();
y.readReport();
z.readReport();
cout<<"only parent can sign";
x.sign();

return 0;
}