2

I have a problem with a school assignment. I am supposed to create a system that keeps track of contenders in a sporting event. I have a base class contender and two classes that derive from that called Professional and Exerciser.
And then I have a register class that contains a Contender **contenders. And I have to create a copy-constructor for this class but I don't know how to do it.

I thought about something like this

Register::Register(const Register& original)
{
    this->kap = original.kap;
    this->currentAmount = original.currentAmount;
    for (int i = 0; i < this->currentAmount; i++)
    {
        if (Professional* pro = dynamic_cast<Professional*>(this->contenders[i]))
        {
            this->contenders[i] = new Professional(*original.contenders[i]);
        }
        if (Exerciser* pro = dynamic_cast<Exerciser*>(this->contenders[i]))
        {
            this->contenders[i] = new Exerciser(*original.contenders[i]);
        }
    }
    this->initiate(this->currentAmount);
}
Axalo
  • 2,953
  • 4
  • 25
  • 39
Rangutang
  • 21
  • 4
  • So what's the problem you're having with this code? You might want to look at the [virtual constructor idiom](http://en.wikibooks.org/wiki/More_C++_Idioms/Virtual_Constructor) (particularly the virtual copy). – Joseph Mansfield Jan 28 '15 at 15:57
  • 6
    But then the `Register` class needs to know about all the possible derived classes. Perhaps you can give the base class a `virtual Base* clone() const;` member function, which all derived classes implement as `Base* clone() const { return new Derived (*this); }` – BoBTFish Jan 28 '15 at 16:02
  • 2
    http://stackoverflow.com/questions/259853/whats-the-best-signature-for-clone-in-c – abcthomas Jan 28 '15 at 16:09
  • 1
    What type is `this->contenders`? Depending on the type you might have undefined behavior. (It should really be a vector.) – cdhowie Jan 28 '15 at 16:15
  • It tells me that "there is no instance of constructor Professional::Professional that matches the argument list argument types are:(Contender)". And we are not suppose to use vectors on this assignment I can post all of the code if you would like – Rangutang Jan 28 '15 at 16:25
  • @Rangutang Please ask that in a separate question. – David G Jan 28 '15 at 16:34

1 Answers1

1

I understand that contenders is a pointer to an array of pointers.

There are three issues :

  • you need to intialize contenders.
  • the dynamic_cast<> check should use the original object
  • Professional and Exerciser copy constructors are certainly defined as copying objects of type Professional and Exerciser respectively and not Contender.

Here a proposed correction:

Register::Register(const Register& original)
{
    kap = original.kap;
    currentAmount = original.currentAmount;
    contenders = new Contender[currentAmount];  // was missing
    for (int i = 0; i < currentAmount; i++)
    {
        if (Professional* pro = dynamic_cast<Professional*>(original.contenders[i]))
        {
            contenders[i] = new Professional(*pro);  // use the pro instead of contender
        }
        if (Exerciser* exe = dynamic_cast<Exerciser*>(original.contenders[i]))  
        {
            contenders[i] = new Exerciser(*exe);  // use exe instead of contender
        }
    }
    initiate(currentAmount);
}

Three recomendations though:

  • you don't need to use this-> to prefix all object variables. Only in case of ambiguity with local variables of the member function itself.
  • think of using vector instead of a pointer to an array
  • the clone approach proposed in the comments would be a really nice and powerful alternative to your dynamic_cast<> checks
Christophe
  • 68,716
  • 7
  • 72
  • 138