用于特定于类的属性或外部结构的C ++虚拟方法

时间:2010-06-08 17:37:36

标签: c++ attributes virtual getter

我有一组类,它们都是从一个公共基类派生而来的。我想以多态方式使用这些类。接口定义了一组getter方法,它们的返回值在给定的派生类中是常量,但从一个派生类到另一个派生类不等。 e.g:

enum AVal
{
  A_VAL_ONE,
  A_VAL_TWO,
  A_VAL_THREE
};

enum BVal
{
  B_VAL_ONE,
  B_VAL_TWO,
  B_VAL_THREE
};

class Base
{
  //...
  virtual AVal getAVal() const = 0;
  virtual BVal getBVal() const = 0;
  //...
};

class One : public Base
{
  //...
  AVal getAVal() const { return A_VAL_ONE };
  BVal getBVal() const { return B_VAL_ONE };
  //...
};

class Two : public Base
{
  //...
  AVal getAVal() const { return A_VAL_TWO };
  BVal getBVal() const { return B_VAL_TWO };
  //...
};

这是一种常见的做事方式吗?如果性能是一个重要的考虑因素,我最好将属性拉出到外部结构中,例如:

struct Vals
{
  AVal a_val;
  VBal b_val;
};

在每个实例中存储Vals*,并按如下方式重写Base

class Base
{
  //...
  public:
    AVal getAVal() const { return _vals->a_val; };
    BVal getBVal() const { return _vals->b_val; };
  //...
  private:
    Vals* _vals;
};

额外的取消引用是否与vtable查找基本相同?这种情况的惯用语是什么?这些解决方案的两个 哑吗?非常感谢任何见解

4 个答案:

答案 0 :(得分:1)

第一种方法看起来更清晰,并强制您覆盖这些方法(无论如何,在第一个孩子)。我认为虚拟呼叫的开销往往低于人们的预期。只有在您分析代码并且虚拟呼叫花费大量时间时,我才会尝试像您的第二种方法那样进行优化。

话虽如此,你想解决什么问题?有时像这样的类ID很有用,但有时候不同的接口抽象可以完成同样的事情,而根本没有这样的接口。

答案 1 :(得分:1)

我个人会实现一种GetTypeStats(),它返回一个(引用)结构,它包含所有派生的特定信息,或者像你在D3D中找到的QueryInterface。您还应该考虑此方案中的静态多态性。但是,如果您的类必须是运行时多态的,那么您无法真正消除虚函数调用。

答案 2 :(得分:0)

如果所有不同的是值并且它们在编译时被修复,那么你可以使它们成为模板参数:

template< AVal aval, BVal bval>
class Derived : public Base
{
  AVal getAVal() const { return aval };
  BVal getBVal() const { return bval };
};

typedef Derived<A_VAL_ONE, B_VAL_ONE> One;
typedef Derived<A_VAL_TWO, B_VAL_TWO> Two;

答案 3 :(得分:0)

当程序员想要避免使用dynamic_cast时,这是为多态类型做穷人的dynamic_cast的常用方法。在这些情况下,这是一种微观优化。与所有微优化一样,您需要在继续之前使用基于 need 的合理判断。如果分析器告诉您这样做而不是dynamic_cast没有性能提升,那么使用dynamic_cast可能会好得多。