C++ 正确的继承/类结构

C++ 正确的继承/类结构,c++,C++,我想写一个线性规划求解库。因此,使用了几个解算器,如cplex或gurobi。我已经为它们中的每一个提供了一个接口(所有接口都包含相同的函数,将它们包装到解算器特定的代码中) 现在我想要一个类'LinearProgram',它可以通过LinearProgram(“cplex”)实例化,然后调用cplex解算器 我的第一个想法是使用一个超级类“solver”,它是所有solver接口的基类,包含作为虚拟声明的各个函数。但是我得到了一个不能实例化的抽象类。 因此,在LinearProgram中,我希

我想写一个线性规划求解库。因此,使用了几个解算器,如cplex或gurobi。我已经为它们中的每一个提供了一个接口(所有接口都包含相同的函数,将它们包装到解算器特定的代码中)

现在我想要一个类'LinearProgram',它可以通过LinearProgram(“cplex”)实例化,然后调用cplex解算器

我的第一个想法是使用一个超级类“solver”,它是所有solver接口的基类,包含作为虚拟声明的各个函数。但是我得到了一个不能实例化的抽象类。 因此,在LinearProgram中,我希望有一个变量解算器,它根据构造函数中给定的字符串进行实例化

我确信一个合适的解决方案是显而易见的,但我现在所能想到的并不是令人满意的


感谢您的帮助。

这说明了您所描述的内容:

class Solver {
...abstract base
};

class SolverFactory {
public:
    Solver* NewSolverWithName(const std::string& pSolverName);
};

class LinearProgram {
public:
    LinearProgram(const std::string& pSolverName) :
      d_solver(SolverFactory::NewSolverWithName(pSolverName)) {
    }
private:
    some_auto_pointer<Solver> d_solver;
};

class cplex_Solver : public Solver {
...
    static std::string Name();
};

Solver* SolverFactory::NewSolverWithName(const std::string& pSolverName) {
    if (pSolverName == cplex_Solver::Name()) {
      return new cplex_Solver();
    }
    ...
}
类求解器{
…抽象基础
};
类求解工厂{
公众:
解算器*NewSolverWithName(const std::string和pSolverName);
};
类线性规划{
公众:
LinearProgram(常量标准::字符串和pSolverName):
d_解算器(SolverFactory::NewSolverWithName(pSolverName)){
}
私人:
一些自动指针d_解算器;
};
类cplex_解算器:公共解算器{
...
静态std::string Name();
};
解算器*SolverFactory::NewSolverWithName(常量std::string和pSolverName){
if(pSolverName==cplex_Solver::Name()){
返回新的cplex_解算器();
}
...
}

这是两种不同设计模式组合的工作

第一个是模式,第二个是模式

继续使用当前拥有的基类,并创建一个派生类,该派生类只将调用转发给指向基类的嵌入式指针。派生类现在可以通过值自由传递

基类还可以包含一个静态成员函数,该函数返回指向基类的指针。这个静态成员函数允许您通过使用字符串名称来查找派生类来实例化它。这为在运行时选择算法提供了一种方便的方法

但是那些知道自己想要哪个派生类(哪个策略)的人可以创建一个带有“new”的派生类,并将其填充到信封类的实例中


如果您决定只对基类使用
shared\u ptr
,您可以选择取消信封类。

使用您的解算器超类思想,仅实例化子类,并且不按值使用超类(仅使用指针和引用)。我不会将工厂类分开。我会在
Solver
类中使用静态工厂方法。@Omnifarious实际上,解决给定问题的更好方法取决于很多事情。但在某些情况下是正确的+1。如果以生产代码的形式编写,我会做很多不同的事情。感谢您的回复。这似乎是解决我问题的好办法。但我还有一个关于实现的简短问题:我有'solver'基类和'CplexSolver'etc解算器类。我添加了一个静态函数
static solver*NewSolverWithName(const std::string&pSolverName){if(pSolverName==CplexSolver::Name()){return new CplexSolver();}}}
,但是我总是会收到错误消息:src/solver/solver.hpp:In statischer Elementfunktion»static solver*solver::NewSolverWithName(const string&)«:src/solver/solver.hpp:44:22:错误:»CplexSolver«未声明src/solver/solver.hpp:45:15:错误:在»CplexSolver«src/solver/solver.hpp:45:15:错误:»int*«无法在返回语句src/solver/solver.hpp:45:15:错误:预期»;«before»CplexSolver«src/solver/solver.hpp:45:27:错误:»CplexSolver«未在此范围内声明感谢您的帮助,并对您的错误表示抱歉highlighting@user1801173这是循环依赖关系——将
solver::NewSolverWithName
的定义移动到solver.cpp。