Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模板实例化抽象基类子类的构造函数-需要其他设计模式_C++ - Fatal编程技术网

C++ 模板实例化抽象基类子类的构造函数-需要其他设计模式

C++ 模板实例化抽象基类子类的构造函数-需要其他设计模式,c++,C++,我有这样一个模板: template<typename T> struct foo { foo(T t) { //code } virtual double computation() = 0; //other members }; struct my_foo : public foo<std::string> { double computation() override { return 9.99; } }; 问题是这不起作用: my_

我有这样一个模板:

template<typename T>
struct foo {
  foo(T t) {
    //code
  }
  virtual double computation() = 0;
  //other members
};
struct my_foo : public foo<std::string> {
  double computation() override { return 9.99; }
};
问题是这不起作用:

my_foo("hello");
我必须要求用户为每个子类创建一个新的构造函数,即使它所做的只是调用超类构造函数。这看起来很傻


您能推荐更适合我的替代“设计模式”吗?

从您的示例中我可以看出,您希望用户指定类型和计算函数。由于您没有提供虚拟析构函数,我假设您不希望以多态方式使用生成的模板实例化,例如,您不希望在同一位置存储/交换不同的
foo
实现。换句话说,纯虚拟函数的唯一目的似乎是强制客户机实现
computation()

您还希望模板的构造函数可以使用,而无需客户端重新实现或显式地将其导入到他的类中。只有当
my_foo
foo
的实例而不是派生类时,才能实现这一点

在这种情况下,您可以使用基于策略的设计:

template<typename T, typename ComputationPolicy>
struct foo : ComputationPolicy {
  foo(T t) {
    //code
  }

  void bar() {
    double d = ComputationPolicy::computation(); //just use it!
  }

  //...
};

我相信它与模板没有直接关系

这只是因为:在C++中,构造函数没有继承。 尝试此示例,您将看到它不起作用:

class Parent {
public:
    Parent(int i) {
        cout << "i " << i << endl;
    };
};

class Child : public Parent {
};

int main(int argc, char** args) {
    Child child(1);
    return 0;
}
在本例中,我为Child创建了一个接受1个参数的ctor。此子ctor将调用父级的
Parent(int)
ctor

在你的问题中,你说让子类创建ctor是愚蠢的:一点也不愚蠢!您永远不会知道子级希望如何实例化其类。根据某个子类的语义,该子类只能合理地使用2个参数来构造ctor


如果您真的希望它神奇地完成,您可以做的一个最简单的方法是创建宏来“生成”子类的类声明和相应的构造函数。但是这样做很少有意义。

要求用户继承构造函数:
使用foo::foo
class Parent {
public:
    Parent(int i) {
        cout << "i " << i << endl;
    };
};

class Child : public Parent {
};

int main(int argc, char** args) {
    Child child(1);
    return 0;
}
class Child : public Parent {
public:
    Child(int i):Parent(i) {
    }
};