如何来到一个指向一个派生类的指针不能传递到一个函数,期望一个指向基类的指针?

如何来到一个指向一个派生类的指针不能传递到一个函数,期望一个指向基类的指针?

问题描述:

对不起,长标题,但我确实想要具体。
我希望下面的代码可以工作,但它不,我不知道为什么:/

Sorry for the long title but I did want to be specific. I expected the following code to work but it doesn't and I can't figure out why :/

#include <cstdio>
#include <cassert>

class UniquePointer
{
public:
    void Dispose()
    {
        delete this;
    }

    friend void SafeDispose(UniquePointer*& p)
    {
        if (p != NULL)
        {
            p->Dispose();
            p = NULL;
        }
    }
protected:
    UniquePointer() { }
    UniquePointer(const UniquePointer&) { }
    virtual ~UniquePointer() { }
};

class Building : public UniquePointer
{
public:
    Building()
    : mType(0)
    {}
    void SetBuildingType(int type) { mType = type; }
    int GetBuildingType() const { return mType; }
protected:
    virtual ~Building() { }
    int mType;
};

void Foo()
{
    Building* b = new Building();
    b->SetBuildingType(5);
    int a = b->GetBuildingType();
    SafeDispose(b);     // error C2664: 'SafeDispose' : cannot convert parameter 1 from 'Building *' to 'UniquePointer *&'
    b->Dispose();
}

int main(int argc, char* argv[])
{
    Foo();
    return 0;
}


然后你可以这样编写代码:

Imagine it were legal. Then you could write code like this:

class Animal : public UniquePointer
{
};

void Transmogrify(UniquePointer*& p)
{
    p = new Animal();
}

void Foo()
{
    Building* b = nullptr;
    Transmogrify(b);
    b->SetBuildingType(0); // crash
}

观察到你违反了类型系统其中一个建筑应该是),而不需要强制转换或提出编译器错误。

Observe that you have violated the type system (you put an Animal where a Building should be) without requiring a cast or raising a compiler error.