tags:

views:

138

answers:

2

Hello,

Have a class Hero. Sometimes I need a deep copy (when all members are copied by value) of this class as a kind of some derived class:

class Hero
{
    public:
        // members, w/o getters/setters
    public:
        // Constructors
        Hero();
        Hero(...)
        ~Hero();

        inline SuperHero* asSuperHero() {
             // Here should be retured SuperHero instance initialized with all members of Hero class
        }
};

class SuperHero : public Hero
{
    private:
        // Shouldn't be instantianed manually
        SuperHero();

    public:
        // This class-only specific method
        void helpAround();
};

The more obvious way is to implement SuperHero constructor which takes all members and do theirs copy manually (because there is no copy constructor in C++ for derived classes): SuperHero(member1, member2, ...) (kind of this). But when I change amount of Hero members, I alway will should change theirs copy in SuperHero constructors.

To avoid this I would implement asSuperHero() in the following way:

inline SuperHero* asSuperHero() {
     return static_cast<SuperHero *>(this);
}

Here I there is no need to copy all members etc. Is this way C++ correct, design-corrent and C++ safe?

Thanks,

+4  A: 

Why not just have the derived class's constructor use the base class's copy constructor?

eg:

class SuperHero : public Hero
{
    ...
        SuperHero(const Hero &hero) : Hero(hero) {
        }
    ...
};
Laurence Gonsalves
Haven't known about this feature. Will definitely try it! Thanks.
bjilly
@ bjilly - If the copy constructor is not called as mentioned by Laurence, the compiler will call the default constructor for the Base Class [ Hero ] instead of calling the Base Class's Copy Constrcutor. As you can change the Class Hero, add a copy constructor if you didn't have one. I believe Laurence's Answer is what you are looking for.
Narendra N
A: 

Here I there is no need to copy all members etc. Is this way C++ correct, design-corrent and C++ safe?

Let the compiler do this as much as you can. For each member, make sure they have appropriate copy-ctors/op= etc. Deep copy is required when you have pointers etc. Define appropriate copy-ctors/op=/dtors for this.

The design looks a bit off:

  • The base class should have virtual dtors/members
  • The base class should be oblivious of members like asSuperHero. This really should be implemented as a member of the derived class.
  • The motivation for having the asSuperHero member is not very clear.

But when I change amount of Hero members, I alway will should change theirs copy in SuperHero constructors.

Can you rephrase this part?

dirkgently
> Can you rephrase this part?I mean the case when I have explicit members copying in SuperHero constructor (1). When I change add/delete new members to Hero, I will always change the constructor (1): there are two points of responsibility. I want to reduce them to one.
bjilly
@bjilly: No, adding data members to the base class shouldn't require any changes to the derived class as long as the base classes _big three_ are properly implemented. Also, make the member functions `virtual` in the base class.
dirkgently