Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass pointer of derived class to reference to pointer of base class?

Tags:

c++

Here is the sample code.

class BaseClass {
};

class DerivedClass : public BaseClass {
};

int Foo(BaseClass*& ptr) {
}

DerivedClass* ptr_to_derived;

//following will not work
Foo(ptr_to_derived);

I fail to compile code above, and the error message is "can't convert DerivedClass* to BaseClass*&". So How can I pass ptr_to_derived to Foo?

like image 848
hexiecs Avatar asked Oct 28 '25 16:10

hexiecs


2 Answers

The error message is quite clear:

error: invalid initialization of non-const reference of type ‘BaseClass*&’ from an rvalue of type ‘BaseClass*

Because Foo takes a pointer by non-const reference you can't pass it an rvalue. The implicit conversion from DerivedClass to BaseClass that happens when you pass it to Foo gets you the rvalue that the error is complaining about.

You can create a base pointer from the derived one and pass that:

DerivedClass* ptr_to_derived;
BaseClass* ptr_derived_base = ptr_to_derived;

Foo(ptr_derived_base);
like image 101
Hatted Rooster Avatar answered Oct 31 '25 05:10

Hatted Rooster


The problem is that Foo might modify the passed pointer-to-base. For example:

class OtherDerivedClass : public BaseClass {
};

OtherDerivedClass* ptr_to_other_derived = ...;

void Foo(BaseClass*& ptr)
{
    ptr = ptr_to_other_derived;
}

What do you think should happen if you could call this Foo with ptr_to_derived? Should ptr_to_derived now point not to a DerivedClass but to an OtherDerivedClass object? That's wrong on every level.

Solution 1: Don't allow Foo to modify the pointer. Either pass by value:

void Foo(BaseClass* ptr)

or by const-ref:

void Foo(const BaseClass*& ptr)

Solution 2: Create a pointer-to-base variable that Foo can modify.

BaseClass* ptr_to_base = ptr_to_derived;
foo(ptr_to_base);

This will of course leave ptr_to_derived unmodified. C++ does not let you pass a temporary expression (which is what the conversion from DerivedClass* to BaseClass* would return) because, again, Foo says it will modify that pointer and the changed temporary would just be discarded. That's usually a mistake. You could of course still decide to not care about the change to ptr_to_base that Foo might make.

like image 29
Max Langhof Avatar answered Oct 31 '25 07:10

Max Langhof



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!