I have a silly problem. I want to make a class (let's call it Classone) that has an object that's an instance of Classtwo as an attribute. So far so good, but when Classtwo has an attribute that's an instance of Classone, I get a compilationerror. I would appreciate if someone could help me out with this problem. Example code follows:

classone.hh

#ifndef CLASSONE_H
#define CLASSONE_H

#include "classtwo.hh"

class Classone{

  Classtwo ct;

public:
  Classone();
};
#endif

classtwo.hh

#ifndef CLASSTWO_H
#define CLASSTWO_H

#include "classone.hh"

class Classtwo{

  Classone co;

public:
  Classtwo();
};
#endif

classone.cc

#include "classone.hh"

Classone::Classone(){}

classtwo.cc

#include "classtwo.hh"

Classtwo::Classtwo() {}

ok, so this code doesn't do much good, but I hope y'all get the idea.
This problem is causing much frustration so I'm hoping on help quickly.

Recommended Answers

All 11 Replies

Yeah, that's a toughie. You have two basic options, someone else may know of another.

1) use a forward declaration for one of them, and then use that class as a POINTER (because the compiler knows that such a class exists, but not how big it is or anything like that):

class Classone; // forward

class Classtwo
{
<blah blah blah>
    Classone* m_pClassOne;
};

2) Are they similar enough to have a common superclass? Then you can declare a pointer to the superclass. This only works if one class can call member functions that belong to the superclass:

class super
{
public:
    CallMe();
};

class Classone : public super
{
<blah blah blah>
    super* m_pClasstwo;
}

class Classtwo : public super
{
<blah blah blah>
    super* m_pClassone;
}

Thank you for helping. The pointer-fix works ok, even though it's not exactly what I was hoping for.

Now a related question.
1. I've heard that using pointers makes it much more difficult for the compiler to optimize code. Will the forward declaration and pointer solution be comparatively slow, and is there any way around it?

"Comparatively slow"?

You have a CPU capable of adding two registers together in 1 trillionth of a second, and you want to know if a pointer dereference will slow you down?

Dude!

Depending on the processor (Arm? x86?) and the compiler and it's optimizer, referencing something through a pointer will generally take an extra instruction or two over NOT referencing through a pointer. And, there may be some cases where the compiler would have known something more about a specific routine (like its local or inlinable) if you didn't refer to it by pointer. However, unless you are doing this in a very large loop, why spend time saving a millisecond?

My advice: make the code clean looking and readable and make it WORK. Then, if it is slow, figure out what to do next. Most programs wait an intermitible time for disk drives and human input.

The classes will be used in the inner workings of a search through a state tree for a game AI, so in this case I'd say that the pointer referencing is unwanted. I realize that the overhead caused by this usually doesn't affect performance notably.

(And isn't it closer to one addition in one billionth of a second ;-)

Anyway, thank you for your help this far.

>1. I've heard that using pointers makes it much more difficult for the compiler to optimize code.
You heard wrong. If a compiler fails to optimize pointers properly, it's extremely unlikely that all other compilers do as well.

>so in this case I'd say that the pointer referencing is unwanted
If performance is this much of an issue, you need to be using inline assembly.

>If performance is this much of an issue, you need to be using inline assembly.
I am, in some cases, but mostly I'm relying on my old faithful GNU-compiler to do the optimization for me. Thank you for your piece of advice all the same.

I have a silly problem. I want to make a class (let's call it Classone) that has an object that's an instance of Classtwo as an attribute. So far so good, but when Classtwo has an attribute that's an instance of Classone, I get a compilationerror. I would appreciate if someone could help me out with this problem. Example code follows:

classone.hh

#ifndef CLASSONE_H
#define CLASSONE_H

#include "classtwo.hh"

class Classone{

  Classtwo ct;

public:
  Classone();
};
#endif

classtwo.hh

#ifndef CLASSTWO_H
#define CLASSTWO_H

#include "classone.hh"

class Classtwo{

  Classone co;

public:
  Classtwo();
};
#endif

classone.cc

#include "classone.hh"

Classone::Classone(){}

classtwo.cc

#include "classtwo.hh"

Classtwo::Classtwo() {}

ok, so this code doesn't do much good, but I hope y'all get the idea.
This problem is causing much frustration so I'm hoping on help quickly.

u can do this way:
classtwo; //forward declaration
classone
{
public:
classone(classtwo* ptrclasstwo){m_ptrclasstwo = ptrclasstwo;}
classtwo* m_ptrclasstwo;
};

classtwo
{
public
classtwo(){m_ptrclassone = new classone(this);}
classone* m_ptrclassone;
};

this way u can access from classone the classtwo's members using m_ptrclasstwo, and as well as u can access classone's members using the member variable m_ptrclassone. i think this will serve ur purpose.

Thank you for helping. The pointer-fix works ok, even though it's not exactly what I was hoping for.

Now a related question.
1. I've heard that using pointers makes it much more difficult for the compiler to optimize code. Will the forward declaration and pointer solution be comparatively slow, and is there any way around it?

I think you should use both solutions : make a forward declaration and use pointer dereferencing. If you don't use pointers, compiler allocates the objects on the stack, which is much slower than working with heap objects due to constant rearanging of the stack frame, besides it takes space in your code ("TEXT") segment. Pointer dereferencing is simply a register-register operation, or if the compiler decides not to optimize it, memory-register operation. Ever since 80486, both memory-register and register-register operations take one CPU cycle to complete (add one cycle penalty for indexed operations) versus 4-cycle PUSH/POP stack operations (a little less on Pentium CPUs). Even an optimizing compiler which would use EBP-based indexing to reach objects on the stack, is a subject to a two-cycle penalty for accessing objects out of +/- 128 bytes from the current ESP.

Bottom line : use pointers and do not be afraid. Especially with classes, where additional processing (virtual method tables etc) adds a lot of overhead to the dereferencing itself.

Just to agitate things up a little. The problem can aslo be solved by use of const or non-const reference members and is similar to the pointer version.

class classone
{
public:
  classone(const classtwo& classtworef)
    :m_classtworef(classtworef)
  {
    //reference members can only be initialized in member initialization list
  }
  const classtwo& m_classtworef;
};

class classtwo
{
public:
classtwo(const classone& classoneref)
: m_classoneref(classoneref)
{
  //reference members can only be initialized in member initialization list
}
const classone& m_classoneref;
};

>If performance is this much of an issue, you need to be using inline assembly.
I am, in some cases, but mostly I'm relying on my old faithful GNU-compiler to do the optimization for me. Thank you for your piece of advice all the same.

if you're that concerned about performance you should use a better compiler. The GNU compiler is not known for turning out highly optimised code.

Or you can use a void pointer in the header and cast that in the implementation code.
Dirty, not safe at all, but it works.

Circular references are almost always a sign of bad design btw...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.