标签: virtual-functions

替代虚拟机制实现?

C++支持通过虚拟机制进行动态绑定.但据我所知,虚拟机制是编译器的实现细节,标准只是指定了在特定场景下应该发生的行为.大多数编译器通过虚拟表和虚拟指针实现虚拟机制.是的,我知道这是如何工作的,所以我的问题不是关于虚拟指针和表的实现细节.我的问题是:

  1. 是否有任何编译器以虚拟指针和虚拟表机制以外的任何其他方式实现虚拟机制?据我所见,最多(阅读g ++,Microsoft visual studio)通过虚拟表,指针机制实现它.那么实际上还有其他任何编译器实现吗?
  2. sizeof只有一个虚函数的任何类的将是一个指针(vptr的内部尺寸this)上编译,所以考虑到虚拟PTR和TBL机制本身是编译器实现,将这个说法我在上面做永远是真的吗?

c++ virtual-functions vtable vptr

48
推荐指数
4
解决办法
4837
查看次数

使用C++中的私有函数覆盖公共虚函数

是否有任何理由使重写的C++虚函数的权限与基类不同?这样做有危险吗?

例如:

class base {
    public:
        virtual int foo(double) = 0;
}

class child : public base {
    private:
        virtual int foo(double);
}
Run Code Online (Sandbox Code Playgroud)

C++常见问题解答说,这是一个坏主意,但没有说为什么.

我已经在一些代码中看到了这个习惯用法,我相信作者试图让这个类最终,基于一个假设,即不可能覆盖私有成员函数.但是,本文显示了重写私有函数的示例.当然,C++ faq的另一部分建议不要这样做.

我的具体问题:

  1. 在派生类和基类中使用不同的虚拟方法权限是否存在任何技术问题?

  2. 有没有合理的理由这样做?

c++ overriding virtual-functions access-control

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

纯虚函数与身体的用例?

我最近才知道,在C++中,纯虚函数可以选择有一个体.

这些功能的实际用例是什么?

c++ virtual-functions

47
推荐指数
5
解决办法
2万
查看次数

为何使用虚拟功能?

可能重复:
有人可以解释C++虚拟方法吗?

我有一个关于C++虚函数的问题.

我们为什么以及何时使用虚拟功能?任何人都可以给我一个实时实现或使用虚拟功能?

c++ virtual-functions

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

在C++中使用接口的性能损失?

在C++中使用接口(抽象基类)时是否存在运行时性能损失?

c++ performance abstract-class virtual-functions

42
推荐指数
4
解决办法
1万
查看次数

模板或抽象基类?

如果我想使类适应,并且可以从外部选择不同的算法 - C++中最好的实现是什么?

我主要看到两种可能性:

  • 使用抽象基类并传递具体对象
  • 使用模板

这是一个小例子,在各种版本中实现:

版本1:抽象基类

class Brake {
public: virtual void stopCar() = 0;  
};

class BrakeWithABS : public Brake {
public: void stopCar() { ... }
};

class Car {
  Brake* _brake;
public:
  Car(Brake* brake) : _brake(brake) { brake->stopCar(); }
};
Run Code Online (Sandbox Code Playgroud)

版本2a:模板

template<class Brake>
class Car {
  Brake brake;
public:
  Car(){ brake.stopCar(); }
};
Run Code Online (Sandbox Code Playgroud)

版本2b:模板和私有继承

template<class Brake>
class Car : private Brake {
  using Brake::stopCar;
public:
  Car(){ stopCar(); }
};
Run Code Online (Sandbox Code Playgroud)

来自Java,我自然倾向于始终使用版本1,但模板版本似乎经常是首选,例如在STL代码中?如果这是真的,是因为内存效率等(没有继承,没有虚函数调用)?

我意识到版本2a和2b之间没有太大的区别,请参阅C++ …

c++ templates abstract-class design-patterns virtual-functions

37
推荐指数
4
解决办法
2万
查看次数

避免C#虚拟呼叫的开销

我有一些经过大量优化的数学函数需要1-2 nanoseconds完成.这些功能每秒被称为数亿次,因此尽管性能已经非常出色,但呼叫开销仍是一个问题.

为了保持程序的可维护性,提供这些方法的类继承了一个IMathFunction接口,以便其他对象可以直接存储特定的数学函数并在需要时使用它.

public interface IMathFunction
{
  double Calculate(double input);
  double Derivate(double input);
}

public SomeObject
{
  // Note: There are cases where this is mutable
  private readonly IMathFunction mathFunction_; 

  public double SomeWork(double input, double step)
  {
    var f = mathFunction_.Calculate(input);
    var dv = mathFunction_.Derivate(input);
    return f - (dv * step);
  }
}
Run Code Online (Sandbox Code Playgroud)

由于消费代码使用它,这种接口与直接呼叫相比造成了巨大的开销.一个直接调用需要1-2ns,而虚拟接口调用需要8-9ns.显然,接口的存在及其随后的虚拟呼叫转换是这种情况的瓶颈.

如果可能的话,我想保留可维护性和性能.有没有办法在实例化对象时将虚函数解析为直接调用,以便所有后续调用都能够避免开销?我认为这将涉及用IL创建委托,但我不知道从哪里开始.

c# virtual-functions micro-optimization

36
推荐指数
2
解决办法
1673
查看次数

你能用C++缓存虚函数查找吗?

假设我在抽象基类指针mypointer-> foo()上有一个虚函数调用foo().当我的应用程序启动时,根据文件的内容,它选择实例化一个特定的具体类,并将mypointer分配给该实例.对于应用程序的其余部分,mypointer将始终指向该具体类型的对象.我无法知道这个具体类型是什么(它可以由动态加载的库中的工厂实例化).我只知道在第一次生成具体类型的实例后,类型将保持不变.指针可能并不总是指向同一个对象,但该对象将始终具有相同的具体类型.请注意,类型在技术上是在'运行时'确定的,因为它基于文件的内容,但是在'启动'(加载文件)之后,类型是固定的.

但是,在C++中,每次在应用程序的整个持续时间内调用foo时,我都会支付虚函数查找成本.编译器无法优化查找,因为它无法知道具体类型在运行时不会发生变化(即使它是有史以来最令人惊奇的编译器,也无法推测动态加载的行为库).在JIT编译语言(如Java或.NET)中,JIT可以检测到反复使用相同类型并执行内联缓存.我基本上是在寻找一种方法来手动为C++中的特定指针执行此操作.

在C++中是否有任何方法可以缓存此查找?我意识到解决方案可能非常糟糕.我愿意接受ABI /编译器特定的黑客攻击,如果有可能编写发现ABI /编译器相关方面的配置测试,那么即使不是真正可移植的,它也"实际上是可移植的".

更新:对反对者:如果这不值得优化,那么我怀疑现代JIT会做到这一点.您是否认为Sun和MS的工程师正在浪费时间实施内联缓存,并没有对其进行基准测试以确保有所改进?

c++ optimization abstract-class caching virtual-functions

35
推荐指数
3
解决办法
6011
查看次数

我应该默认虚拟析构函数吗?

我有一个声明如下的抽象类:

class my_type {
public:
    virtual ~my_type() = default;
    virtual void do_something() = 0;
};
Run Code Online (Sandbox Code Playgroud)

使用default关键字声明这样的析构函数是一种良好的做法吗?有没有更好的办法?

另外,是= 0一种现代(C++ 11)指定无默认实现的方式,还是有更好的方法?

c++ destructor virtual-functions c++11

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

检测是否已在派生类中重新定义C++虚函数的方法

简而言之:从指向派生类实例的C++基类指针,如何在运行时确定是否已重新实现非纯虚函数(在基类中具有实现)派生类?

上下文: 我正在编写一个C++库来解决某些类别的数学方程.该库提供了一个Equation具有多个虚函数的类,库用户将其用作他们希望解决的特定等式的基类.该库还提供了一个Solver类,它接受Equation *一个构造函数参数.然后用户按以下方式编写代码:

class MyEquation : public Equation
{ ... } // equation definition here

int main()
{
  MyEquation myEqn;
  Solver solver(&myEqn);
  solver.Solve();
}
Run Code Online (Sandbox Code Playgroud)

如果虚拟函数的某些组合Equation未在导出的方程类中重新定义,Solver则可以省略由对象运行的算法的某些计算上昂贵的部分.因此,我想知道,在构造函数中Solver,哪些函数已被重新定义,而是将运行默认实现Equation.

  • 我想让这对图书馆的用户透明,所以我不是在寻找一个解决方案,例如,用户在派生方程的构造函数中设置一些标志,指定哪些函数已被重新定义.

  • 一种可能的解决方案是在虚拟函数的默认实现中Equation设置类中的私有标志Equation; Solver然后,类的构造函数可以清除此标志,运行虚函数,并检查标志值以查看是否Equation已调用实现.我想避免这种情况,因为每次执行虚函数时只需设置标志就会使算法减慢很多(这些虚函数的执行对程序的运行时间有很大帮助,而默认实现只返回一个常数).

c++ virtual-functions

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