为什么不能将指向派生类的指针传递给期望引用指向基类的指针的函数?

Jul*_*bot 12 c++

很抱歉很长的标题,但我确实想要具体.我希望以下代码可以工作,但它没有,我无法弄清楚原因:/

#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;
}
Run Code Online (Sandbox Code Playgroud)

Ray*_*hen 44

想象一下它是合法的.然后你可以写这样的代码:

class Animal : public UniquePointer
{
};

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

void Foo()
{
    Building* b = nullptr;
    Transmogrify(b);
    b->SetBuildingType(0); // crash
}
Run Code Online (Sandbox Code Playgroud)

注意到您违反了类型系统(将Animal放在建筑物应该的位置)而不需要强制转换或引发编译器错误.


wil*_*ilx 6

我不认为它可以按照你设计的方式工作.相反,请尝试以下方法:

template <typename T>
void SafeDispose(T * & p)
{
    if (p != NULL)
    {
        p->Dispose();
        p = NULL;
    }
}

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

protected:
    UniquePointer() { }
    UniquePointer(const UniquePointer&) { }
    virtual ~UniquePointer() { }
};
Run Code Online (Sandbox Code Playgroud)