标签: virtual-functions

Expression.Compile与Lambda的性能,直接与虚拟调用

我很好奇Expression.Compile与代码中的lambda表达式和直接方法使用的性能如何,以及直接方法调用与虚方法调用(伪代码):

var foo = new Foo();
var iFoo = (IFoo)foo;

foo.Bar();
iFoo.Bar();
(() => foo.Bar())();
(() => iFoo.Bar())();
Expression.Compile(foo, Foo.Bar)();
Expression.Compile(iFoo, IFoo.Bar)();
Expression.CompileToMethod(foo, Foo.Bar);
Expression.CompileToMethod(iFoo, IFoo.Bar);
MethodInfo.Invoke(foo, Foo.Bar);
MethodInfo.Invoke(iFoo, IFoo.Bar);
Run Code Online (Sandbox Code Playgroud)

c# performance lambda expression virtual-functions

22
推荐指数
3
解决办法
7106
查看次数

有没有理由不让会员功能虚拟?

有没有真正的理由不在 C++中使成员函数虚拟化?当然,总会存在性能参数,但由于虚函数的开销相当低,因此在大多数情况下似乎并不存在.

在另一方面,我已经被咬了好几次与遗忘做一个功能的虚拟那应该是虚拟的.这似乎是一个比表现更大的争论.那么有没有理由不默认将成员函数设为虚拟?

c++ oop virtual-functions

21
推荐指数
5
解决办法
4521
查看次数

为什么所有java方法都是隐式可覆盖的?

在C++中,我必须明确指定'virtual'关键字以使成员函数'overridable',因为当成员函数被覆盖时,会产生创建虚拟表和vpointer的开销(因此每个成员函数都隐式不能覆盖表现原因).

当子类提供具有相同名称和签名的单独实现时,它还允许隐藏成员函数(如果未覆盖).

在C#中也使用相同的技术.我想知道为什么Java摆脱了这种行为,并默认使每个方法都可以覆盖,并提供了在显式使用'final'关键字时禁用覆盖行为的能力.

c++ java virtual-functions

21
推荐指数
3
解决办法
3110
查看次数

纯虚函数在C++中的用途是什么?

我现在正在课堂上学习C++,而且我不太熟悉纯虚函数.我知道它们稍后在派生类中概述,但是如果你要在派生类中定义它,为什么要将它声明为等于0?

c++ virtual-functions pure-virtual

21
推荐指数
3
解决办法
4万
查看次数

覆盖具有不同返回类型的成员函数

考虑以下示例:

#include <iostream>

using namespace std;

class base
{
   public:
      virtual int func()
      {
         cout << "vfunc in base class\n";
         return 0;
      }
};

class derived: public base
{
   public:
      double func()
      {
         cout << "vfunc in derived class\n";
         return 0;
      }
};

int main()
{
   base *bptr = new derived;
   bptr->func();

   return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译器为上面的代码提供了一个错误,即覆盖函数存在冲突类型.为什么不能使用不同的返回类型覆盖派生类中的函数?

我相信,为了覆盖一个函数,需要在派生类中重新定义基类虚方法.要重新定义方法,方法的签名必须相同.由于返回类型不是签名的一部分,我相信即使返回类型有差异,该方法仍将被重新定义?在上述代码的情况下,func在派生类中使用不同的返回类型重新定义虚函数.但是编译器会抛出错误.我的理解是否正确?

c++ overriding virtual-functions redefinition

21
推荐指数
3
解决办法
3万
查看次数

为什么使用基类指针来派生类

class base{
    .....
    virtual void function1();
    virtual void function2();
};

class derived::public base{
    int function1();
    int function2();
};

int main()
{
    derived d;
    base *b = &d;
    int k = b->function1() // Why use this instead of the following line?
    int k = d.function1(); // With this, the need for virtual functions is gone, right?

}
Run Code Online (Sandbox Code Playgroud)

我不是CompSci工程师,我想知道这一点.如果我们可以避免基类指针,为什么要使用虚函数?

c++ oop polymorphism virtual-functions base-class

21
推荐指数
1
解决办法
2万
查看次数

在C++中vtable查找的性能损失

我正在评估将一个实时软件从C /汇编语言重写为C++ /汇编语言(由于与代码问题无关的原因,在汇编时绝对需要这样做).

中断带有3 kHz频率,对于每个中断,大约200个不同的事情将按顺序完成.处理器以300 MHz运行,为我们提供100,000个周期来完成这项工作.这已在C中用函数指针数组求解:

// Each function does a different thing, all take one parameter being a pointer
// to a struct, each struct also being different.
void (*todolist[200])(void *parameters);

// Array of pointers to structs containing each function's parameters.
void *paramlist[200];

void realtime(void)
{
  int i;
  for (i = 0; i < 200; i++)
    (*todolist[i])(paramlist[i]);
}
Run Code Online (Sandbox Code Playgroud)

速度很重要.上述200次迭代每秒完成3000次,因此实际上我们每秒进行600,000次迭代.上面的for循环每次迭代编译为五个周期,总成本为每秒3,000,000个周期,即1%的CPU负载.汇编程序优化可能会将其降低到四个指令,但是我担心由于内存访问彼此接近等原因,我们可能会得到一些额外的延迟.简而言之,我相信这五个周期非常理想.

现在进行C++重写.我们做的那200件事情彼此有关.有一个参数的子集,它们都需要和使用,并具有各自的结构.在C++实现中,它们可以被巧妙地视为从公共基类继承:

class Base
{
  virtual void Execute();
  int something_all_things_need;
}
class Derived1 : Base
{
  void Execute() { …
Run Code Online (Sandbox Code Playgroud)

c c++ virtual-functions real-time vtable

21
推荐指数
4
解决办法
6704
查看次数

Swift有动态调度和虚拟方法吗?

从C++/Java/C#背景开始我希望在Swift中看到虚拟方法,但是阅读swift文档我没有提到虚拟方法.

我错过了什么?

virtual-functions dynamic-dispatch swift

21
推荐指数
3
解决办法
8354
查看次数

保护CRTP模式免于"纯虚拟"调用中的堆栈溢出

请考虑以下标准CRTP示例:

#include <iostream>

template<class Derived>
struct Base {
    void f() { static_cast<Derived *>(this)->f(); }
    void g() { static_cast<Derived *>(this)->g(); }
};

struct Foo : public Base<Foo> {
    void f() { std::cout << 42 << std::endl; }
};

int main() {
    Foo foo;
    foo.f(); // just OK
    foo.g(); // this will stack overflow and segfault
}
Run Code Online (Sandbox Code Playgroud)

如果这是常规虚拟继承,我可以将虚拟fg方法标记为纯粹

struct Base {
    virtual void f() = 0;
    virtual void g() = 0;
};
Run Code Online (Sandbox Code Playgroud)

并获得关于Foo抽象的编译时错误.但是CRTP没有提供这样的保护.我可以以某种方式实现它吗?运行时检查也是可以接受的.我想过将this->f指针与比较static_cast<Derived …

c++ virtual-functions crtp pure-virtual

21
推荐指数
3
解决办法
1309
查看次数

为什么给纯虚函数定义是有意义的?

斯科特在Effective C++上说,第3版,pg.43要创建一个抽象类,我们只需要给它一个纯虚拟析构函数:

class AWOV {                  // AWOV = "Abstract w/o Virtuals"
public:
  virtual ~AWOV() = 0;        // declare pure virtual destructor
};
Run Code Online (Sandbox Code Playgroud)

然后,他接着说有一个转折:我们必须为纯虚析构函数提供一个定义:

AWOV::~AWOW() {}              // definition of pure virtual dtor
Run Code Online (Sandbox Code Playgroud)

我的问题是,通过指定= 0纯虚函数,我们说该函数不能对声明这个纯虚函数的类有任何定义.

为什么在这里为纯虚拟析构函数提供定义(即使它是空的)是可以的?

c++ polymorphism virtual-functions class

20
推荐指数
3
解决办法
663
查看次数