关于强转指针和重构类型的一道c++代码

请写出以下程序的运行结果,并解释导致这样运行结果的关键性原因

#include <iostream>
using std::cout;
class P
{
    public:
    virtual void print()
    {
        cout << "P";
    }
};
class Q: public P
{
    public:
    virtual void print()
    {
        cout << "Q";
    }
};
int main()
{
    P * p = new P;
    Q * q = static_cast <Q *> (p);
    q->print();
    delete p;
    cout << endl;
    q = new Q;
    p = q;
    q->print();
    p->print();
    cout << endl;
    p = new (q) P;
    q->print();
    p->print();
    cout << endl;
    p->~P();
    delete q;
    return 0;
}

1
2
3
4
//输出结果
P
QQ
PP
第一行输出,虽然强制转换了指针p的类型,但是它指向的对象(P)并没有变化,依据多态性原理,会调用p::print(),输出 P。再说明一下:static_cast由于不进行类型检查,用它进行下行转换(父→子)不安全。
第二行输出,指向同一个地址,不多说了。
第三行输出,首先要理解p =new(q) P 是什么鬼。看后面有一个p->~P(),什么时候会需要显式调用析构函数呢?这里涉及到动态内存分配的另一种用法: placement new/delete。这种new允许在一块已经分配成功的内存上重新构造对象或对象数组。placement new不用担心内存分配失败,因为它根本不分配内存,它做的唯一一件事情就是调用对象的构造函数。以上述代码为例。这个代码其实完成了两个任务。1、将指针q指向的Q类型对象重构为P类型(已经分配了堆内存空间)2、让指针p指向该对象。所以最终输出是PP。注意:千万不要对 p 使用delete.这是因为placement new构造起来的对象或数组大小并不一定等于原来分配的内存大小,使用delete会造成内存泄漏或者之后释放内存时出现运行时错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值