有人如何实施这种模式:
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
调用它将被继承的类的构造函数。
答案 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;
}