Questions tagged «virtual-functions»

在面向对象的编程中,虚函数或虚方法是一种函数或方法,其行为可以在继承类中被具有相同签名的函数覆盖。这个概念是面向对象编程(OOP)的多态性部分中非常重要的一部分。


25
为什么我们需要C ++中的虚函数?
我正在学习C ++,并且刚开始使用虚函数。 从我阅读的内容(在书中和在线上)中,虚函数是基类中的函数,您可以在派生类中重写这些函数。 但是在本书的前面,当学习基本继承时,我无需使用即可在派生类中覆盖基本函数virtual。 那我在这里想念什么?我知道虚函数还有很多,这似乎很重要,所以我想弄清楚到底是什么。我只是无法在网上找到直接的答案。

7
如果我要重写基类的虚函数,可以调用它吗?
假设我有课程,Foo并且Bar设置如下: class Foo { public: int x; virtual void printStuff() { std::cout << x << std::endl; } }; class Bar : public Foo { public: int y; void printStuff() { // I would like to call Foo.printStuff() here... std::cout << y << std::endl; } }; 如代码中所注释,我希望能够调用我要重写的基类的函数。在Java中有super.funcname()语法。这在C ++中可能吗?




13
内联虚拟功能真的是胡扯吗?
当我收到一条代码审查评论时说了虚函数不必是内联的,这是我遇到的问题。 我认为内联虚拟函数可以在直接在对象上调用函数的情况下派上用场。但是我想到的反驳是-为什么要定义虚拟然后使用对象来调用方法? 最好不要使用内联虚拟函数,因为它们几乎从未扩展过? 我用于分析的代码段: class Temp { public: virtual ~Temp() { } virtual void myVirtualFunction() const { cout<<"Temp::myVirtualFunction"<<endl; } }; class TempDerived : public Temp { public: void myVirtualFunction() const { cout<<"TempDerived::myVirtualFunction"<<endl; } }; int main(void) { TempDerived aDerivedObj; //Compiler thinks it's safe to expand the virtual functions aDerivedObj.myVirtualFunction(); //type …



12
虚拟函数和vtable如何实现?
我们都知道C ++中有什么虚函数,但是如何在深层次上实现它们呢? 是否可以在运行时修改vtable甚至直接访问vtable? 该vtable是否适用于所有类,或者仅适用于至少具有一个虚函数的类? 对于至少一个条目的函数指针,抽象类是否仅具有NULL? 拥有一个虚拟函数会减慢整个班级吗?还是仅调用虚拟函数?速度是否会受到影响(无论是否实际覆盖了虚函数),或者只要它是虚函数,速度就不会起作用。

6
为什么C#接口方法没有声明为抽象或虚拟的?
接口中的C#方法在不使用virtual关键字的情况下被声明,并且在派生类中被覆盖而未使用override关键字。 是否有一个原因?我认为这只是一种语言上的方便,显然CLR知道如何在后台进行处理(默认情况下方法不是虚拟的),但是还有其他技术原因吗? 这是派生类生成的IL: class Example : IDisposable { public void Dispose() { } } .method public hidebysig newslot virtual final instance void Dispose() cil managed { // Code size 2 (0x2) .maxstack 8 IL_0000: nop IL_0001: ret } // end of method Example::Dispose 注意,该方法virtual final在IL中声明。

9
在C ++类中使用虚拟方法的性能成本是多少?
C ++类(或其任何父类)中至少有一个虚拟方法意味着该类将具有一个虚拟表,并且每个实例将具有一个虚拟指针。 因此,内存成本非常明显。最重要的是实例上的内存开销(特别是如果实例很小,例如,如果它们仅打算包含一个整数:在这种情况下,每个实例中都有一个虚拟指针可能会使实例的大小增加一倍。)虚拟表所用的内存空间,我想它与实际方法代码所用的空间相比通常可以忽略不计。 这让我想到了一个问题:将方法虚拟化是否有可衡量的性能成本(即速度影响)?在每次调用方法时,都会在运行时在虚拟表中进行查找,因此,如果对这个方法的调用非常频繁,并且如果此方法很短,那么性能可能会受到影响吗?我猜这取决于平台,但是有人在运行一些基准测试吗? 我问的原因是,我遇到了一个错误,该错误恰好是由于程序员忘记定义虚拟方法而引起的。这不是我第一次看到这种错误。我想:我们为什么要添加虚拟关键字,而不是需要时取出时,我们绝对相信这是它的虚拟关键字没有必要?如果性能成本很低,我想我会在团队中简单推荐以下内容:只需在每个类中默认使每个方法都是虚拟的,包括析构函数,并且仅在需要时才将其删除。这听起来对您来说疯狂吗?


9
为什么C#默认将方法实现为非虚拟方法?
与Java不同,为什么C#默认将方法视为非虚函数?它是否更可能是性能问题,而不是其他可能的结果? 我想起了安德斯·海斯伯格(Anders Hejlsberg)读的一段有关现有架构所带来的优势的文章。但是,副作用呢?默认情况下使用非虚拟方法真的不错吗?

9
安全地覆盖C ++虚拟函数
我有一个带有虚函数的基类,并且我想在派生类中重写该函数。有什么方法可以使编译器检查我在派生类中声明的函数是否实际上覆盖了基类中的函数?我想添加一些宏或一些确保我不会意外声明新函数的东西,而不是覆盖旧函数。 举个例子: class parent { public: virtual void handle_event(int something) const { // boring default code } }; class child : public parent { public: virtual void handle_event(int something) { // new exciting code } }; int main() { parent *p = new child(); p->handle_event(1); } 这里parent::handle_event()称为而不是child::handle_event(),因为子方法遗漏了const声明,因此声明了一个新方法。这也可能是函数名称的错字或参数类型的细微差别。如果基类的接口发生更改,并且某些派生类未进行更新以反映更改,则也很容易发生这种情况。 有什么方法可以避免此问题,我可以以某种方式告诉编译器或其他工具为我检查吗?任何有用的编译器标志(最好是g ++)?您如何避免这些问题?

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.