2

I have the following class architecture:

            Pokemon
              |
  --------------------------- ...  -------- ...
 |            |                         |
Bulbasaur     Charamander     ...     Ditto ...

I want to create a new Pokemon class from an instance of Ditto like:

new Charamander(Ditto);

To do that my idea is to use the super class constructor:

new Charamander(Pokemon);

With the Pokemon being the Ditto's super class.

But I don't know how I can access to my Ditto's super class to feed the Charamander's constructor.

Mikhail Kholodkov
  • 23,642
  • 17
  • 61
  • 78
  • 3
    Some languages _can_ be learned by guessing. C++ can't. Sounds like a [good C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) is in order. – Ron Jun 07 '18 at 09:48
  • 1
    There is no **super class** in C++, mostly because we have multiple inheritance. – Yksisarvinen Jun 07 '18 at 09:54
  • 1
    This is important to learn a tool before deciding how to use it. Here, you go the other way around: you choose how you want to use C++ before knowing what you can do with it. Not trying to be rude, but you're completely wide off the mark here. 1/ Learn C++. 2/ Throw everything away. 3/ Start over. – YSC Jun 07 '18 at 09:56
  • You might find it easier to manage and implement such conversions outside the class hierarchy, in some kind of "game rule engine". – molbdnilo Jun 07 '18 at 10:21
  • @Ron That is an intresting post. But the books quoted are a bit expensive for me. Do you know free online books that can help me answer my question? – Mac Pro Helmut Jun 07 '18 at 10:32
  • When a `Charmander` is created from a `Ditto`, does it use any properties specific to `Ditto`, or just properties common to all `Pokemon`? Can a `Charmander` be created from every other type of `Pokemon` in exactly the same way? – aschepler Jun 07 '18 at 10:58
  • I'm not quite sure what you try to achieve but if you provide a constructor `Charamander::Charamander(const Pokemon&)` then you can construct `Charamander` from/with any instance of `Pokemon` and derived classes. I'm not sure whether this thing can be called "copy constructor" but this might be the least problem... – Scheff's Cat Jun 07 '18 at 11:00
  • @Scheff So I can do `new Charamander (my_ditto);`. I finnaly found a solution by doing `new Charamander((Pokemon)my_ditto);` – Mac Pro Helmut Jun 07 '18 at 11:25
  • Yes - as you can see in my sample. In `main()`, I did `Charamander char2(ditto1);`. So, the only difference is: I made a local instance, you want one on heap instead. This is a question(/difference) of storage but not of construction. May be, you really should look for a book... ;-) – Scheff's Cat Jun 07 '18 at 11:27
  • The suggestion to google `good c++ book online` was not a joke. It brought hits with similar questions (which might have trustworthy answers). – Scheff's Cat Jun 07 '18 at 11:30

1 Answers1

2

If you want to construct an instance of a class as copy of a sibling class then I see two options:

  1. Every derived class has to provide (copy?) constructors for each sibling class.

  2. Every derived class has to provide a constructor which copies from their common super class.

The latter sounds better as it reduces the amount of code to be written (and probably causes less maintenance issues later).

Of course, the third option is whether derived classes are necessary at all.

However, I made a little sample for 2nd option:

#include <iostream>
#include <string>

class Pokemon {
  private:
    static int _idGen;
  protected:
    int _id;
  public:
    Pokemon(): _id(++_idGen) { }
    Pokemon(const Pokemon&) = default;
    virtual const char* what() const = 0;
};

int Pokemon::_idGen;

class Ditto: public Pokemon {
  public:
    Ditto(): Pokemon()
    {
      std::cout << "Ditto created. (ID: " << _id << ")\n";
    }
    Ditto(const Pokemon &other): Pokemon(other)
    {
      std::cout << "Ditto cloned from " << other.what() << " (ID: " << _id << ").\n";
    }
    virtual const char* what() const override { return "Ditto"; }
};

class Charamander: public Pokemon {
  public:
    Charamander(): Pokemon()
    {
      std::cout << "Charamander created. (ID: " << _id << ")\n";
    }
    Charamander(const Pokemon &other): Pokemon(other)
    {
      std::cout << "Charamander cloned from " << other.what() << " (ID: " << _id << ").\n";
    }
    virtual const char* what() const override { return "Charamander"; }
};

int main()
{
  Charamander char1;
  Ditto ditto1;
  Charamander char2(ditto1);
  Ditto ditto2(char1);
  return 0;
}

Output:

Charamander created. (ID: 1)
Ditto created. (ID: 2)
Charamander cloned from Ditto (ID: 2).
Ditto cloned from Charamander (ID: 1).

Live Demo on coliru

Sorry, if I mixed the Pokemon's. Not that I know everything about this stuff except that there is this comic series (and all the merchandising around it)...

Regarding a free C++ book: You may find some by google c++ book online. If you are in doubt about quality then google instead good c++ book online...

Scheff's Cat
  • 19,528
  • 6
  • 28
  • 56