需要有关初始化过程中动态绑定的帮助

时间:2015-02-28 18:33:46

标签: c++ inheritance constructor initialization

我有以下代码:

class A {
  public:
    A();
    virtual int Compute() = 0;

    int inited_val;
};

class B: A {
  public:
    B(int data): mydata(data) {};
    int Compute();
    int mydata;
};

A::A() {
  inited_val = Compute();
};

int B::Compute() {
  return mydata; // long computation...
}

int main() {
  B b(42);
  return 0;
}

这不起作用,因为在基类的构造函数中不可能B::Compute(它会调用不存在的A::Compute)。

如何确保从派生类中的inited_val函数填充Compute?我可以从B构造一个对象并在之后填充它或使用在构造函数之后直接调用的init函数,但这似乎容易出错(我可能会忘记这样做)。 (想象一下Compute函数成本很高,并且只使用派生类中可用的数据。)

我找到了如何在http://isocpp.org/wiki/faq/strange-inheritance#calling-virtuals-from-ctor-idiom上解决此问题的建议,并尝试使用create函数实现该方法,但我不清楚如何在没有显式依赖的情况下编写A::createB

A* A::Create() {
  A* p = ???;
  inited_val = p->Compute();
  return p;
}

2 个答案:

答案 0 :(得分:0)

考虑使用CRTP

template<class T> class Wrapper : public T
{
public:
  template<class... Types>
  Wrapper(Types&&... Args)
    : T(std::forward<Types>(Args)...)
  {
    inited_val = Compute();
  }
};  


int main() 
{
  Wrapper<B> b(42);
  return 0;
}

答案 1 :(得分:0)

您可以像这样实施Create

template <class T>
static std::unique_ptr<typename std::enable_if<std::is_base_of<A, T>::value, T>::type> Create()
{
    auto t = std::make_unique<T>();
    inited_val = t->Compute();
    return t;
}

你可以像这样使用它

auto b = Create<B>();