It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center。
6年前关闭。
看来
在
这是代码:
避免演员
您应该尝试设计程序,以便不需要强制转换。
请改用多态。
在基类中声明所有需要的方法。使用pure virtual methods。
将基础升级到派生
您无法通过投射升级实例。
如果要将
那么您必须在
我希望这有帮助。
非常感谢Tadeusz Kopec的更正。
6年前关闭。
看来
dynamic_cast
在三级继承的情况下不起作用。在
print()
方法调用时(在main()
中),应用程序因分段错误(核心转储)而崩溃。这是代码:
#include <iostream>
#include <typeinfo> //must be included to call any member functions for the typeinfo object returned by typeid()
using namespace std;
class CBase
{
public:
virtual void print()
{
cout<<"CBase::print"<<endl;
}
virtual ~CBase()
{ }
};
class CDerivedA : public CBase
{
public:
virtual void print()
{
cout<<"CDerivedA::print"<<endl;
}
virtual ~CDerivedA()
{}
};
class CDerivedB : public CDerivedA
{
public:
void print()
{
cout<<"CDerivedB::print"<<endl;
}
};
int main()
{
CBase* ptrB = new CDerivedA();
CDerivedB* ptrDB = dynamic_cast<CDerivedB*>(ptrB);
ptrDB->print();
return 1;
}
最佳答案
“指向CDerivedA的指针”(基类)不能转换为“指向CDerivedB的指针”(派生类)。注意,我不是指声明的指针类型;问题是指向的实际对象实际上是基类的实例,因此downcast无法成功。
如果向下转换失败,则dynamic_cast
返回一个null
指针,这可能是分段违反的原因(如果强制转换引用,则将引发bad_cast
异常)。
请注意,dynamic_cast
需要RTTI(运行时类型信息)才能正常工作。出于性能原因,可以在编译器中关闭RTTI(因为如果启用,则会在运行时引入一些开销)。请仔细检查您的编译器是否启用了RTTI。
编辑:关于您的最后评论-
垂降的基础
您不能向下转换基类的实例。您可以向下转换一个声明为“ pointer-to-base-class”的指针,该指针实际上指向派生类的实例。有关如何使用向下转换的示例:
class Base
{ public:
virtual void baseMethod() {cout<<"baseMethod in Base"<<endl;}
// I am omitting virtual destructors here for brevity,
// which you should _not_ do in your code!
}
class Derived : public Base
{ public:
void baseMethod() {cout<<"baseMethod in Derived"<<endl;}
virtual void derivedMethod(){cout<<"derivedMethod in Derived"<<endl;}
}
class Derived2 : public Derived
{ public:
void baseMethod() {cout<<"baseMethod in Derived2"<<endl;}
void derivedMethod(){cout<<"derivedMethod in Derived2"<<endl;}
void derived2Method(){cout<<"derived2Method in Derived2"<<endl;}
}
void someFunction(Base* pBase)
{
// pBase may actually point to an instance of Base, Derived or Derived2.
// But you can invoke only 'baseMethod' on pBase,
// since 'derivedMethod' and 'derived2Method' are not declared in Base.
pBase->baseMethod(); // ok
// ERROR: pBase->derivedMethod();
// ERROR: pBase->derived2Method();
// To invoke 'derivedMethod', you have to downcast to Derived:
Derived* pDerived = dynamic_cast<Derived*>(pBase);
if(pDerived /* != null */)
{
// Downcast successful, i.e.
// pBase actually points to an instance of Derived _or_ Derived2.
// Both have the 'derivedMethod', so you can invoke it via 'pDerived' pointer:
pDerived->derivedMethod(); // ok
// ERROR: pDerived->derived2Method();
// To call 'derived2Method', you have to downcast to Derived2.
}
else
{
// If we are here, then dynamic_cast returned null,
// i.e. the downcast was NOT successful
// and pBase actually points to an instance of Base.
}
}
避免演员
您应该尝试设计程序,以便不需要强制转换。
请改用多态。
在基类中声明所有需要的方法。使用pure virtual methods。
将基础升级到派生
您无法通过投射升级实例。
如果要将
Base
的实例升级到Derived
的实例,那么您必须在
Derived
中定义一个构造函数,该构造函数将Base作为参数,并通过new
创建一个新的Derived实例。请注意,Base
的旧实例保持原样,仅创建Derived
的新实例。class Derived : public Base
{ public:
Derived(Base& base)
: Base(base) // use copy constructor of Base
{
// initializations specific to Derived
}
// ... other methods ...
}
// Usage:
Base* pBase = new Base();
Derived* pDerived = new Derived(*pBase); // "upgrade" Base to Derived.
// The instance of Base (pointed to by pBase) still lives,
// and a new instance of Derived (pointed to by pDerived) is born.
// Do not forget to delete both pBase and pDerived!
我希望这有帮助。
非常感谢Tadeusz Kopec的更正。