Jump to content

How to use an object in several other classes

- - - - -

This topic has been archived. This means that you cannot reply to this topic.
9 replies to this topic

#1
ThemePark

ThemePark

    Programmer

  • Members
  • PipPipPipPip
  • 124 posts
I swear, headers and dependencies are doing my head in.

I must admit that I'm completely new to C++, but I'm used to Java and somewhat C, so I don't consider myself to be completely in the middle of nowhere.

Anyway, the problem is that I have an class that I would like to use in several classes, some places as a return type, other places to create an object of that type. But I keep getting new errors every time I fix an old one, and I've been looking on the internet on how to fix this and that error, and have finally given up, and decided to come here and beg for help.

My class is as simple as it gets. Since I want to fix this problem first, the class contains no attributes or functions. All I have is this:

Image.h:
class Image

{

};

Now, what I want to do is to be able to use this in more than just one class. Hence, I #include Image.h everywhere I need to use the Image object. But I get a "redefinition of 'class Image'" error.

Fair enough, I read up on it, and find out that I need to add some defines (I don't recall what they're called). So I change my header like this:

Image.h:
#ifndef IMAGE_H

#define IMAGE_H

class Image

{

};

#endif

Now I get the error "'Image' does not name a type". Again I read up on this error, and find out that I need to add a forward declaration of my class. From what I can figure out, this is because once IMAGE_H has been defined, it skips that entire section in the other files that have included Image.h, and so those other files do not know that the class exists. So I change my code like this:

Image.h:
class Image;

#ifndef IMAGE_H

#define IMAGE_H

class Image

{

};

#endif

Now I think everything is good. But no. Now I get the error "variable 'Image img has initializer but incomplete type". This error occurs in one of those files where I try to assign an Image object by using a method to return one.

Then I think that maybe I just need to move the defines to after the class, i.e. inside the curly brackets. Like this:

Image.h:
class Image;

class Image

{

#ifndef IMAGE_H

#define IMAGE_H

#endif

};

Then of course, I get the redefinition error. And this is where I throw in the towel. I have looked in books, and online, I have found examples that use headers, that use objects, but I have not been able to find an example that use the same object in multiple classes. And the books and sites I have seen that use headers, do it this way. So I'm at a loss for what I'm doing wrong here.

#2
Lance

Lance

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 276 posts
Hehe, you are misled.

In you case, no forward declaration is required.

Just
#ifndef _IMAGE_H_
#define _IMAGE_H_

class Image
{
};

#endif


But make sure in every *.h or *.cpp that uses Image, do
#include "image.h"
before you use it.

That's it.

#3
Lance

Lance

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 276 posts
If however, what you mean is you want to use a COMMON object of Image in multiple *.cpp files as suggested in you title, one of the way is

#ifndef _IMAGE_H_
#define _IMAGE_H_

class Image
{
};

extern Image gImageCommon;

#endif

And create an image.cpp with the following lines
// file: Image.cpp
//


#include "image.h"

Image gImageCommon;  // actually define the object that's going to be used by all


Note there's drawback to this approach, but I will stop short of pointing it out for now.

#4
ThemePark

ThemePark

    Programmer

  • Members
  • PipPipPipPip
  • 124 posts
I forgot to mention something, which I think is actually rather important.

Since I will be using the Image object in many headers, some of these headers will include each other, but not in the sense that two headers will include each other, just that one of them will include the other, and both of them will also include "Image.h".

I figure that is why I'm getting the "Image does not name a type" error, and why I need to use forward declaration.

#5
Lance

Lance

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 276 posts
What you were doing is not forward declaration.

I'll give you an example



class LinkNode;  // this is forward declaration


class LinkList{

     // ...other stuff

      LinkNode * header; 

};



class LinkNode{

    int data;

    LinkNode * next;

};



When you have 2 classes that refer to each other, you may use forward declaration to resolve it.

#6
ThemePark

ThemePark

    Programmer

  • Members
  • PipPipPipPip
  • 124 posts
But this is forward declaration, right?

class Image;

#ifndef IMAGE_H

#define IMAGE_H

class Image

{

};

#endif

If I do that, like I said before, I get the "variable 'Image img has initializer but incomplete type" error, which I assume is also because I want to use the Image class in other headers, where of some of them include others.

#7
Lance

Lance

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 276 posts
OK. I can tell you you need to use forward declaration to fix your problem but you are not doing it in the right way.

It is hard to explain it to you. But if you paste the two header file that are mutual dependant and are causing your problem, I should be able to fix it in a couple of minutes, and hope that would teach you how and when to do forward declaration.

#8
ThemePark

ThemePark

    Programmer

  • Members
  • PipPipPipPip
  • 124 posts
Okay, this is the minimum I've boiled it down to, while still getting the "Image does not name a type" error.

Images.h:
#include "Image.h"

#include "BMP.h"


class Images

{

    static Image loadImage(char* imageName);

};

BMP.h:
#include "Image.h"


Image loadBMP(char* imageName);

Image.h
#ifndef IMAGE_H

#define IMAGE_H


class Image

{

};


#endif


#9
Lance

Lance

    Programming Professional

  • Members
  • PipPipPipPipPip
  • 276 posts
In your case, forward declaration is not neccessary

Put include guard to the other 2 head files.

#10
ThemePark

ThemePark

    Programmer

  • Members
  • PipPipPipPip
  • 124 posts
I think I see my mistake now, and it is unfortunately a rookie mistake based on a stupid assumption I've made.

I am used to coding in Java, and the tutorials I have seen use two colons to define a function in a class like Image::Image for the constructor. But being used to Java, I figured that I could also write it closer to Java style, which makes more sense to me. Therefore I have written for instance the constructor like:

#include "Image.h"

class Image

  Image()

  {

  }

}

So I guess now, that it is not possible to use this code style. If it is, I'll have to keep looking, I guess.