0

I want to do essentially the following:

class Base{
     void dosomestuff(Derived instanceOfDerived)
     {
         //Something
     }
};

class Derived : public Base{
     //Something
};

The Base needs a include of Derived, but to declare Derived it needs the declaration of Base first. Forward declaration does not work, because I do not want to use pointers.

Now my question: How do I accomplish that without pointers? Is that even possible? Or is the only possibility to make instanceOfDerived a pointer?

Moritz Göckel
  • 137
  • 1
  • 1
  • 8
  • Im sorry. You are completely right. I changed the example, the question is the same. – Moritz Göckel Apr 13 '15 at 08:27
  • 2
    If you want to refer to something that hasn't been defined yet, you need some kind of indirection like a pointer or reference. (Note that you can't *use* the derived class inside the definition of the base class, you can only refer to it by name; you'll need to move the function definition.) – molbdnilo Apr 13 '15 at 08:32

3 Answers3

3

You better do something like:

class Derived;
class Base{
     void dosomestuff(Derived& instanceOfDerived)
     {
         //Something
     }
};

class Derived : public Base{
     //Something
};

I would even move the body of method dosomestuff to the source cpp code where you can include derived.h as well as base.h

base.h could look like:

#ifndef BASE_H_
#define BASE_H_

class Derived;
class Base{
     void dosomestuff(const Derived& instanceOfDerived);
};

#endif

derived.h:

#ifndef DERIVED_H_
#define DERIVED_H_

#include "base.h"

class Derived : public Base{
     //Something
};

#endif

base.cpp:

#include "base.h"
#include "derived.h"

void Base::dosomestuff(const Derived &instanceOfDerived) {
    //Something
}
W.F.
  • 13,888
  • 2
  • 34
  • 81
  • What if they don't want to take a reference? – Joseph Mansfield Apr 13 '15 at 08:28
  • 1
    @JosephMansfield the interface of Derived cannot be accessable from Base in a simple way... – W.F. Apr 13 '15 at 08:29
  • So I need to use a either a pointer or a reference? There is no other way? – Moritz Göckel Apr 13 '15 at 08:33
  • Alas no, there is not. – Medinoc Apr 13 '15 at 08:37
  • @MoritzG I'm afraid so, but on the other hand it's not much of a limitation with references... – W.F. Apr 13 '15 at 08:38
  • @MoritzG - You always try to reduce creating temporary objects, if you don't pass by `*` or `&`. If this code is going in production, don't try that or else if using for learning use it, debug and see how many copy constructor calls are made. – DumbCoder Apr 13 '15 at 08:38
  • 1
    @WojciechFrohmberg, since the original function took its parameter by value, your fix should take a const-reference. Also `_BASE_` and `_DERIVED_` are [reserved names](http://stackoverflow.com/q/228783/981959), so this answer has undefined behaviour. Bad bad bad. – Jonathan Wakely Apr 13 '15 at 08:44
  • Thank you. Im just learning C++ so I just wanted to know if this would be possible. It is a good advice to use more pointers and references. Im not working on production. Im just practicing C++. Im coming from C# and Java. So I have a lot to learn :) In my projects I use the .h files. I just did not use it in the example to keep it simple. – Moritz Göckel Apr 13 '15 at 08:47
3

The original version of the question asks about having Base hold Derived as a data member. That's obviously impossible. It's the same infinite recursion problem (a Derived contains a Base subobject, so a Base would recursively contain itself, and it will be turtles all the way down.)

The revised question asks about having a member function of Base taking a by-value argument of type Derived. That's perfectly possible. You need a forward declaration of Derived, and to defer the definition of the member function until after the actual definition of Derived:

class Derived;
class Base{
     void dosomestuff(Derived instanceOfDerived); // declaration only
};

class Derived : public Base{
     //Something
};

// out-of-class definition, so making it explicitly inline
// to match the in-class definition semantics
inline void Base::dosomestuff(Derived instanceOfDerived) {
     //Something
}

Demo.

T.C.
  • 133,968
  • 17
  • 288
  • 421
0

That means your inheritance model is not make sense if you really want to do that. Remember "Make sure public inheritance models 'is a.' "http://debian.fmi.uni-sofia.bg/~mrpaff/Effective%20C++/EC/EI35_FR.HTM If you make them have inheritance relationship, that means Derived is a Base, instead of "Derived is part of Base". You can create 2 classes to do that instead of making them have inheritance relationship.

ybdesire
  • 1,593
  • 1
  • 20
  • 35