是否可以通过下转换从基础对象创建派生对象
Is it possible to creat a derived object from a base object through downcast?
基类
class Base
{
public:
Base()=default;
virtual void f(){cout << "base classn";}
virtual ~Base(){}
};
派生类
class Derive : public Base
{
public:
Derive()=default;
void f() override {cout << "derived classn";}
};
主要功能
int main()
{
Base* bsd = new Base;
Derive* dru = new Derive;
if(Derive* drd=dynamic_cast<Derive*>(bsd)){
drd->f();
cout << "downcast successfuln";
}else{
cout << "downcast failedn";
}
if(Base* bsu=dynamic_cast<Base*>(dru)){
bsu->f();
cout << "upcast successfuln";
}else{
cout << "upcast failedn";
}
delete bsd;
delete dru;
}
事实证明,上行传输效果良好,而下行传输失败。这样看来是有道理的。如果派生类包含未在基类中声明的成员对象,并且没有默认构造函数,那么在下转换过程中会发生什么?
此外,通过dynamic_cast
创建的目标指针*drd(*bsd)
指向与要投射的指针*bsu(*dru)
相同的对象。所以删除一次就足够了。我们不会有一个悬着的指针,对吧?
Casting不会以任何方式创建任何新对象或更改对象。强制转换会更改对现有对象的解释,因此,如果一个对象不是Derive
,则无法通过强制转换使其成为Derive
。
请注意,Derive
也是Base
,因为继承会创建"是"关系。这就是upcasting工作的原因:它所做的只是告诉编译器,它应该将指向的对象视为Base
,即使该对象实际上是Derive
。
它在你的程序中没有什么不同,所以这里有一个演员阵容的例子:
class Derive : public Base
{
public:
Derive()=default;
void f() override {cout << "derived classn";}
void added() {cout << "hello" << endl; }
};
dru->added(); // Works
Base* bsu=dynamic_cast<Base*>(dru);
bsu->added(); // Does not compile
从本质上讲,强制转换对编译器"隐藏"添加的接口,命令它将Derive
对象视为Base
。当然,重写将继续被正确调用,因为重写成员函数是Base
接口的一部分。
我不确定你的问题是否正确,但是的,如果析构函数是virtual
,你可以使用基指针安全地删除派生类。
"悬空指针"是不同的:在删除了bsd
和dru
之后,你就不能再使用这些指针了,它们已经变成了悬空指针,因为它们指向的是你不再拥有的已删除内存。
class CBase
{
public:
CBase(void);
virtual ~CBase(void);
virtual void identify()
{
std::cout << "base class" << std::endl;
}
};
class CDerieved : public CBase
{
public:
CDerieved(void);
virtual ~CDerieved(void);
virtual void identify()
{
std::cout << "Derieved class" << std::endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
CDerieved* pderieved = new CDerieved;
pderieved->identify();
CBase* pb = static_cast<CBase*>(pderieved);
pb->identify();
CDerieved* pd1 = dynamic_cast<CDerieved*>(pb);
pd1->identify();
return 0;
}
以上代码将成功。
但请记住,如果你发现需要向下转换,那么设计需要修改。
相关文章:
- 如何为模板化对象创建模板向量?VS正在投掷C3203
- 具有包含其他对象的类的对象创建顺序
- 为什么我们再次从结构对象创建结构变量?
- 将对象创建为全局/静态对象会崩溃,而本地对象不会崩溃
- 如何创建一个对象创建函数,该函数将由与其关联的名称调用?
- 如何为自定义模板对象创建专门的函数模板
- 对象创建错误的C++矢量
- 如何为Python Swigged C++对象创建和分配回调函数
- 在 C++ 中为 C 样式对象创建一个透明包装类
- 此类模板的对象创建如何工作?
- C++ 中的对象创建类型有什么区别?
- 未知大小的数组作为类成员,用于在运行时(对象创建时间)创建数组的对象
- 如何仅通过父类对象限制对象创建
- 在正确性或良好的代码结构方面,这种动态对象创建看起来如何
- 无法将类对象创建为另一个类的成员
- 如何从现有基类对象创建派生类对象
- 在 DTor 之前删除的静态对象创建的线程?
- C++:定义多个构造函数时的对象创建/销毁序列
- 从对象创建矢量包装器,该对象只允许使用索引访问向量
- 是否可以为CPP中的对象创建一组指针