query regarding copy constructors

J

jimjim

Hello all,

class Base {
public:
virtual void f(){ } };

void userCode(Base base) { }

class Derived : public Base{
int i; };

int main() {
Derived derived;
Base base = derived;
userCode(derived);
return 0; }

How is the Base base = derived possible. Is there a copy constructor
Base::Base( const Derived &) povided by default? The same question applies
to the userCode(derived) invokation, where an object of Derived type is
copied to a Base.

TIA
 
E

Earl Purple

jimjim said:
class Base {
public:
virtual void f(){ } };

void userCode(Base base) { }

class Derived : public Base{
int i; };

int main() {
Derived derived;
Base base = derived;
userCode(derived);
return 0; }

How is the Base base = derived possible. Is there a copy constructor
Base::Base( const Derived &) povided by default? The same question applies
to the userCode(derived) invokation, where an object of Derived type is
copied to a Base.

TIA

It is permitted because const Derived& can be implicitly converted to
const Base&. Making a copy this way is called "slicing" and is not
recommended. You can avoid this problem by disabling your
copy-constructor (declaring it private without a definition). The same
should be done for assignment. Another way to do this is to inherit
(usually privately) from a class that has these features disabled.

If you do want to allow safe copy-construction in a hierarchy, then
offer a clone() method.
 
J

jimjim

It is permitted because const Derived& can be implicitly converted to
const Base&. Making a copy this way is called "slicing" and is not
recommended.

1. Does the term "slicing" mean that part of the member data of a Derived
type will be lost after copied to a Base type?
2. The opposite, ie. conversion of const Base& to const Derived& is not
allowed. Why is this?
 
M

Mark P

jimjim said:
1. Does the term "slicing" mean that part of the member data of a Derived
type will be lost after copied to a Base type?

Typically, yes. There's nothing magical going on here though. When you
write Base base = derived, you're calling the copy constructor of class
Base, Base(const Base& b). The constructed object "base" will be built
exactly as specified in the implementation of this copy ctor. By
default, that would be a memberwise copy of the data of b; if you've
defined your own copy ctor it will do whatever you've defined it to do.
Either way, if the derived object has additional members the base copy
ctor can't know about them so they get "sliced" off.
2. The opposite, ie. conversion of const Base& to const Derived& is not
allowed. Why is this?

A Derived "IS A" Base, the converse is not true in general. You can
explicitly cast the reverse conversion but it won't happen by default
because it's unsafe in general.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top