I have this code in a library:
class Parent
{
//some data and functions
};
void myfunc(Parent& ref);
and I want to do this code in my application:
class Child : public Parent
{
// some other data and functions
void dostuff()
{
myfunc(*this);
}
};
Is it safe to pass *this? (no slicing, no copying, ...) Is it better to call myfunc like this:
myfunc( * ((Parent*)this) )
Note that I don't have control on what happens inside myfunc, in some cases I don't even know what happens inside there.
I used passing-parent-by-pointer many times and I am used to it, but have never used passing-parent-by-reference before.
The parent class can hold reference to both the parent and child objects.
So, a parent class object can refer to its child class object, as the child class object includes the parent's methods and properties. Thinking vice versa, since a parent class object does not have all the methods and properties needed by a child class, a child class object cannot refer to a parent class object.
When an object (or built-in type) is passed by reference to a function, the underlying object is not copied. The function is given the memory address of the object itself. This saves both memory and CPU cycles as no new memory is allocated and no (expensive) copy constructors are being called.
Because Java is statically typed at compile time you get certain guarantees from the compiler but you are forced to follow rules in exchange or the code won't compile. Here, the relevant guarantee is that every instance of a subtype (e.g. Child ) can be used as an instance of its supertype (e.g. Parent ).
myfunc(*this)
is fine, so long as myfunc
is declared to take a reference -- which it is.
This will not copy the object. It will pass a reference to the original object. Furthermore, it will not slice the object. The reference will be of type Base&
, but the object to which it refers will be unchanged.
Just so you know, if you were then to call polymorphic (eg, virtual
) methods on this Base&
, polymorphism will still work right and do what you'd expect -- just like if you were to call through a pointer. In other words:
Base& b = *derived;
b.SomeVirtualFoo();
...will have the same effect as:
Base* b = derived;
b->SomeVirtualFoo();
No the first version is correct:
myfunc(*this);
The second version will probably work in this case but I am not convinced it will work in all cases if multiple inheritance is involved (as you are using a C-Style cast). I have to pull out my standard to look at the exact behavior of C-Style cast.
If it worked passing by pointer the same technique will work if you convert to using references.
Now that I have read the standard I see the C-Cast will do the correct thing (as a static_cast<> can be used to cast up the class hierarchy from child to parent).
4 The conversions performed by
— a const_cast (5.2.11),
— a static_cast (5.2.9),
— a static_cast followed by a const_cast,
— a reinterpret_cast (5.2.10), or
— a reinterpret_cast followed by a const_cast,can be performed using the cast notation of explicit type conversion. The same semantic restrictions and be- haviors apply, with the exception that in performing a static_cast in the following situations the conversion is valid even if the base class is inaccessible:
— a pointer to an object of derived class type or an lvalue or rvalue of derived class type may be explicitly converted to a pointer or reference to an unambiguous base class type, respectively;
— a pointer to member of derived class type may be explicitly converted to a pointer to member of an unambiguous non-virtual base class type;
— a pointer to an object of an unambiguous non-virtual base class type, a glvalue of an unambiguous non-virtual base class type, or a pointer to member of an unambiguous non-virtual base class type may be explicitly converted to a pointer, a reference, or a pointer to member of a derived class type, respectively.If a conversion can be interpreted in more than one of the ways listed above, the interpretation that appears first in the list is used, even if a cast resulting from that interpretation is ill-formed. If a conversion can be interpreted in more than one way as a static_cast followed by a const_cast, the conversion is ill-formed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With