Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How come a pointer to a derived class cannot be passed to a function expecting a reference to a pointer to the base class?

Tags:

c++

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;
}
like image 650
Julien Lebot Avatar asked Aug 25 '11 07:08

Julien Lebot


People also ask

Why can't a derived pointer reference a base object?

similarly a derived object is a base class object (as it's a sub class), so it can be pointed to by a base class pointer. However, a base class object is not a derived class object so it can't be assigned to a derived class pointer.

Is derived class pointer Cannot point to base class?

The actual reason is - a derived class has all information about a base class and also some extra bit of information. Now a pointer to a derived class will require more space and that is not sufficient in base class. So the a pointer to a derived class cannot point to it.

Can a pointer be a derived class?

Explanation: A base class pointer can point to a derived class object, but we can only access base class member or virtual functions using the base class pointer because object slicing happens when a derived class object is assigned to a base class object.

Can pointers reference objects of different base types?

A pointer reference is polymorphic, since it can reference objects of different dynamic type.


1 Answers

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.

like image 109
Raymond Chen Avatar answered Oct 25 '22 15:10

Raymond Chen