我在某些C++代码中遇到了一个棘手的问题,最容易用代码描述.我的课程类似于:
class MyVarBase
{
}
class MyVar : public MyVarBase
{
int Foo();
}
class MyBase
{
public:
MyBase(MyVarBase* v) : m_var(v) {}
virtual MyVarBase* GetVar() { return m_var; }
private:
MyVarBase* m_var;
}
Run Code Online (Sandbox Code Playgroud)
我还有一个MyBase的子类需要有一个MyVar类型的成员,因为它需要调用Foo.将Foo函数移动到MyVarBase不是一种选择.这样做是否有意义:
class MyClass : public MyBase
{
public:
MyClass(MyVar* v) : MyBase(v), m_var(v) {}
MyVar* GetVar() { return m_var; }
private:
MyVar* m_var;
}
Run Code Online (Sandbox Code Playgroud)
这似乎工作,但看起来非常糟糕,我不确定它是否会导致内存泄漏或打破复制构造函数.我的其他选择可能是在MyClass中将MyVar变量命名为其他东西,但是它等于基础中的m_var指针,或者在MyVar类型上对MyBase进行临时处理.
所有这些选项似乎并不理想,所以我想知道是否有其他人遇到过这样的情况,以及是否有一个很好的方法让它工作.
Joh*_*itb 13
执行此操作的正确方法是仅在基类中使用变量.由于派生类知道它必须是动态类型MyVar,这是完全合理的:
class MyClass : public MyBase
{
public:
MyClass(MyVar* v) : MyBase(v) {}
MyVar* GetVar() { return static_cast<MyVar*>(MyBase::GetVar()); }
}
Run Code Online (Sandbox Code Playgroud)
由于MyVar是从MyVarBase派生的,因此GetVar如果GetVar是虚拟的,那么不同的返回类型仍然可以工作(就像这里的情况一样).请注意,使用该方法时,必须没有MyBase可以将指针重置为不同的函数.
请注意,static_cast在这种情况下,这是正确的演员.使用dynamic_cast建议,由一个评论者,会告诉读者和GetVar的用户MyBase::GetVar()可能会返回一个指向对象的类型不是MyVar的.但这并不能反映我们的意图,因为您只能通过MyVar.结果是软件开发中最重要的事情.你可以做的是断言它是非空的.它将在运行时中止,并在项目的调试版本中显示错误消息:
MyVar* GetVar() {
assert(dynamic_cast<MyVar*>(MyBase::GetVar()) != 0);
return static_cast<MyVar*>(MyBase::GetVar());
}
Run Code Online (Sandbox Code Playgroud)