0

I'm looking at an example of a wrapper class in this book. The wrapper class itself is shown at the end of this post.

On page 94 of the book there is an example of an inherited class. I have a question to what is going on in the initializer list of the constructor:

class RandomBase
{
public:
  RandomBase(unsigned long Dimensionality);
  virtual RandomBase *clone() const = 0;
  virtual ~RandomBase(){};

private:
  unsigned long Dimensionality;
};

class AntiThetic : public RandomBase
{

public:
  AntiThetic(const Wrapper<RandomBase> &innerGenerator) : RandomBase(*innerGenerator),
                                                          InnerGenerator(innerGenerator) {}
  virtual RandomBase *clone() const
  {
    return new AntiThetic(*this);
  }

private:
  Wrapper<RandomBase> InnerGenerator;
};

First of all, I can't compile this. I get the error: error: invalid conversion from ‘const RandomBase*’ to ‘long unsigned int’ [-fpermissive]. Secondly, I don't understand conceptually what is going on when we call RandomBase(*innerGenerator) - I didn't know it was possible to do this with C++ (?)


Here is the wrapper class Wrapper:

#ifndef WRAPPER_H
#define WRAPPER_H

template< class T>
class Wrapper
{
public:

    Wrapper()
    { DataPtr =0;}

    Wrapper(const T& inner)
    {
        DataPtr = inner.clone();
    }

    ~Wrapper()
    {
        if (DataPtr !=0)
            delete DataPtr;
    }

    Wrapper(const Wrapper<T>& original)
    {
        if (original.DataPtr !=0)
            DataPtr = original.DataPtr->clone();
        else
            DataPtr=0;
    }

    Wrapper& operator=(const Wrapper<T>& original)
    {
        if (this != &original)
        {
            if (DataPtr!=0)
                delete DataPtr;

            DataPtr = (original.DataPtr !=0) ? original.DataPtr->clone() : 0;
        }

        return *this;
    }


    T& operator*()
    {
        return *DataPtr; 
    }

    const T& operator*() const
    {
        return *DataPtr; 
    }

    const T* const operator->() const
    {
        return DataPtr;
    }

    T* operator->()
    {
        return DataPtr;
    }


private:
    T* DataPtr;


};
#endif

Wrapper taken from here

N08
  • 1,265
  • 13
  • 23
  • The `Wrapper` dereference operator returns a *pointer*, which doesn't make much sense. Perhaps it should return a reference instead? – Some programmer dude Oct 19 '17 at 11:00
  • @ Some programmer dude: Even then, it shouldn't be convertible to unsigned long which the constructor demands. – Jodocus Oct 19 '17 at 11:02
  • @Someprogrammerdude I updated the wrapper, I found the correct implementation of it online. You are right. But even then, I'm not sure what goes on in the constructor of the derived class – N08 Oct 19 '17 at 11:07
  • Can you please elaborate on what you're unsure about? What parts of the constructor of the child class are you uncertain about? – Some programmer dude Oct 19 '17 at 11:14
  • @Someprogrammerdude What happens in this initializer list: `RandomBase(*innerGenerator), InnerGenerator(innerGenerator)`? I am technically calling the constructor of the base class? – N08 Oct 19 '17 at 11:22
  • 1
    That's about right. – Some programmer dude Oct 19 '17 at 11:28
  • @Someprogrammerdude What is a good example of when this is useful? And what can it be used for? It's the first time I see this – N08 Oct 19 '17 at 11:31
  • 1
    How else would the parent class be able to initialize itself? Unlike destructors, constructor calls aren't automatically called up the inheritance hierarchy. – Some programmer dude Oct 19 '17 at 11:38
  • 1
    https://stackoverflow.com/questions/10282787/calling-the-base-class-constructor-in-the-derived-class-constructor Maybe this could help? – t.j.saalasti Oct 19 '17 at 11:41

1 Answers1

1

The error:

invalid conversion from ‘const RandomBase*’ to ‘long unsigned int

is self-explanatory, the constructor:

RandomBase(unsigned long Dimensionality);

expects an unsigned long yet when invoked you pass a *innerGenerator.

Conceptually what is going on is that your child class AntiThetic must invoke the base class RandomBase in its constructor.

So you either need to pass the correct parameter Dimensionality or add an empty constructor.

The wrapper seems to be a template class which allows storage and retrieval of the template parameter T which in this instance would be RandomBase.

What is confusing is why compose both a wrapper of that type and also inherit from it.

You could either inherit from RandomBase (as you already are), inherit from Wrapper<RandomBase> or compose them.

Ælex
  • 14,432
  • 20
  • 88
  • 129