【发布时间】:2014-02-14 07:42:27
【问题描述】:
我有一个非常复杂的代码结构,但重要的是:
典型设置:我有一个基类和两个派生自该基类的类,每个类都有自己的成员,并且没有标准构造函数
class BaseSolver{
...
};
class SolverA : BaseSolver{
public:
std::string a;
SolverA(TypeA objectA);
};
class SolverB : BaseSolver{
public:
int b;
SolverB(TypeB objectB);
};
现在我有一个配置 xml 文件,我可以从中读取是否必须使用 SolverA 或 SolverB。因此我有一个 IOService:
template<class T>
class IOService
{
BaseSolver* getSolver()
{
std::string variableThatIReadFromXML;
/* here I have to perform many actions before I can create a solver object
* to retrieve the data needed for the constructors */
TypeA variableIConstrucedWithDataFromXML;
TypeB anotherVariableIConstrucedWithDataFromXML;
if (variableThatIReadFromXML == "a")
return new SolverA(variableIConstrucedWithDataFromXML); // I know that this can leak memory
else if (variableThatIReadFromXML == "b")
return new SolverB(anotherVariableIConstrucedWithDataFromXML);
}
};
在我的应用程序的某个地方(为简单起见,假设它是 main.cpp):
int main(){
IOService ioService;
BaseSolver* mySolver = ioService.getSolver();
}
没问题。
但是现在,主要我必须分别访问派生类a 和b 的成员。
我该怎么做?
我想只从 IOService 中检索 Solver 的类型:
class IOService
{
decltype getSolverType()
{
std::string variableThatIReadFromXML;
/* here I have to perform many actions before I can create a solver object
* to retrieve the data needed for the constructors */
TypeA variableIConstrucedWithDataFromXML;
TypeB anotherVariableIConstrucedWithDataFromXML;
if (variableThatIReadFromXML == "a")
return new SolverA(variableIConstrucedWithDataFromXML); // I know that this can leak memory
else if (variableThatIReadFromXML == "b")
return new SolverB(anotherVariableIConstrucedWithDataFromXML);
}
TypeA getConstructorDataForSolverA()
{
/* here I have to perform many actions before I can create a solver object
* to retrieve the data needed for the constructors */
return variableIConstrucedWithDataFromXML;
}
TypeB getConstructorDataForSolverB()
{
/* here I have to perform many actions before I can create a solver object
* to retrieve the data needed for the constructors */
return anotherVariableIConstrucedWithDataFromXML;
}
};
但是我当然不能指定decltype 作为返回值。
我真的很无奈。我会很感激任何关于正确方向的提示,甚至是这个问题的解决方案。
[编辑]:派生的求解器类需要的不仅仅是来自 xml 文件的信息才能正常工作。这意味着,我必须设置更多来自网格文件的属性。所以我可以将网格文件提供给 IOService,以便 IOService 可以这样设置适当的成员:
class IOService
{
BaseSolver* getSolver(MeshType myMesh)
{
std::string variableThatIReadFromXML;
/* here I have to perform many actions before I can create a solver object
* to retrieve the data needed for the constructors */
TypeA variableIConstrucedWithDataFromXML;
TypeB anotherVariableIConstrucedWithDataFromXML;
if (variableThatIReadFromXML == "a")
{
auto solverA = new SolverA(variableIConstrucedWithDataFromXML); // I know that this can leak memory
solverA.a = mesh.a;
}
else if (variableThatIReadFromXML == "b")
{
auto solverB = new SolverB(anotherVariableIConstrucedWithDataFromXML);
solverB.b = mesh.b;
}
}
};
但是 IOService 需要知道 MeshType 类,这是我想避免的,因为我认为它破坏了封装。
所以我想在我程序的另一部分中分别设置成员a 和b(这里主要是为了简单起见)。
考虑到这一点,只有 Daniel Daranas 的回答对我来说似乎是一个解决方案。但我想避免动态转换。
所以一个重新表述的问题可能是:我应该如何改变我的设计以确保封装并避免动态转换? [/Edit]
我正在使用 clang 3.4 ob ubuntu 12.04 lts。
【问题讨论】:
-
您是在问如何将基类指针向下转换为相应的派生类指针?
-
使用虚函数怎么样? IE。使用
BaseSolver作为接口,main可以使用它来访问派生求解器的功能。
标签: c++ pointers inheritance c++11 rtti