在C ++中从base调用潜在子元素的构造函数

时间:2014-07-17 21:02:01

标签: c++ oop inheritance override

有人如何实施这种模式:

  class Base {//doesn't know anything about potential descendant-classes, like Child
  public:
      Base * foo( void) {
        //some code
          return ( Base *) new !Child-constructor!();
      }
  };

  class Child : public Base { };

//—————————————————————————————————————————————————
  #include <iostream>
  #include <typeinfo>

  using namespace std;

  int main( void) {
      Base * base_p = Child().f();

      cout << typeid( *base_p).name(); //expected to get "Child"

  return 0;
  }

我无法为这种类型的构造找到正确的语法(调用&#34;潜在的&#34;子构造函数)。

UPD :我忘了提及(没有认为可能存在误解),Child类在Base的定义中不得知道。所以我希望foo调用它将被继承的类的构造函数。

3 个答案:

答案 0 :(得分:1)

  

&#34; ...在Base的定义中不得知道Child类。所以我想让foo调用它继承的类的构造函数。&#34;

恕我直言,最简单的方法是提供templated factory function Base

class Base {
public:
    template<class Derived>
    static std::unique_ptr<Base> foo( void) {
      //some code
      return std::unique_ptr<Base>(new Derived());
    }
};

class Child : public Base {
public:
    Child() {}
    virtual ~Child() {}
};

int main() {
    std::unique_ptr<Base> p = Base::foo<Child>();
    return 0;
}

检查可编辑的样本here please

答案 1 :(得分:0)

这个设计很糟糕,顺便说一句。

 //terriblecode.hpp

 struct Base
 {
    Base * foo(void);
 };

 struct Child : public Base{};

 //terriblecode.cpp
 Base* Base::foo() {return (Base*) new Child();}

除了foo的定义之外,还不需要定义孩子。将您的声明与成员函数的定义分开,这很容易做到。

答案 2 :(得分:0)

只需要确保在第一次使用之前让编译器知道你的派生类:

class Child; // forward declaration

class Base {
public:
  Base * foo( void);
};

class Child : public Base { };

// the function needs to be defined after the "Child" is known
Base * Base::foo( void) {
  //some code
    return new Child; // will be automatically type-cast to base class
}

//—————————————————————————————————————————————————
#include <iostream>
#include <typeinfo>

using namespace std;

int main( void) {
  Base * base_p = Child().f();

  cout << typeid( *base_p).name(); //expected to get "Child"

  return 0;
}

但是,我建议采用不同的模式:

class Child; // forward declaration

class Base {
public:
  static Base * foo( void); // static "factory" method
};

class Child : public Base { };

// the function needs to be defined after the "Child" is known
Base * Base::foo( void) {
  //some code
    return new Child; // will be automatically type-cast to base class
}

//—————————————————————————————————————————————————
#include <iostream>
#include <typeinfo>

using namespace std;

int main( void) {
  Base * base_p = Base::f(); // use scope resolution, not object's method

  cout << typeid( *base_p).name(); //expected to get "Child"

  return 0;
}