PDA

View Full Version : Problem with Inheritance and Header Files




Aquis
Aug 25, 2008, 02:55 PM
Hey, let's say I have two objects, ObjectA and ObjectB, and I therefore have the files:
ObjectA.m
ObjectA.h
ObjectB.m
ObjectB.h
I also have another file which imports all the object headers for me, Headers.h. Inside, we have:

#import "ObjectA.h"
#import "ObjectB.h"


Okay - ObjectB is a subclass of ObjectA, and in both their header files, they #import "Headers.h" (so I don't have to #import long lists of headers when I have lots of classes, etc.)

The problem is when I compile. From what I can gather, Xcode compiles ObjectA.m, is taken to ObjectA.h, then Headers.h, and then ObjectB.h - but because ObjectB is a subclass of ObjectA, and ObjectA's @interface has not yet been "read", I get the error:
error: cannot find interface declaration for 'ObjectA', superclass of 'ObjectB'

So my question is, how can I get round this problem?

Thanks!



davedelong
Aug 25, 2008, 03:33 PM
Ah, gotta love circular dependencies.

Sorry, but importing "Header.h" is causing your problem. You need to take out the declaration to ObjectA in your Header.h file, and, if necessary, add it as a forward declaration in ObjectB.h:

//ObjectB.h
@class ObjectA; //this is like a promise to the compiler that you'll import it later

@interface ObjectB : ObjectA {
...
}
...
@end

//ObjectB.m
#import "ObjectB.h"
#import "ObjectA.h"

@implementation ObjectB
...
@end

HTH,

Dave

Aquis
Aug 25, 2008, 04:15 PM
Thanks for the reply, but I'm still having problems...

I have it basically as you wrote, @class directives before the @interface (I had those anyway), and removed the #import "Headers.h" from ObjectB.h and put #import "ObjectA.h" after #import "ObjectB.h" in ObjectB.m. But I still get the same error? Plus more, under that error, I also get two more errors (exactly the same), each reading:

error: no super class declared in @interface for 'ObjectB' (when compiling "a file included from" ObjectB.m)...

davedelong
Aug 25, 2008, 04:17 PM
Is ObjectB inheriting from ObjectA? Like so:

//ObjectB.h

#import <Cocoa/Cocoa.h>

@class Object A;

@interface ObjectB : ObjectA {
...
}
...
@end

Dave

Aquis
Aug 26, 2008, 08:01 AM
Yes, here are the files I'm using (renamed and stripped of contents):

ObjectA.h
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>

@class ...; // Other, unrelated classes...


@interface ObjectA : NSObject {
...
}

...

@end

ObjectA.m
#import "ObjectA.h"

#import "..." // A few other unrelated class header files...


@implementation ObjectA

...

@end

ObjectB.h
#import <UIKit/UIKit.h>

@class ObjectA;
@class ...; // Other unrelated objects...

@interface ObjectB : ObjectA {
...
}

...

@end

ObjectB.m (with error)
#import "ObjectB.h"
error: cannot find interface decleration for 'ObjectA', superclass of 'ObjectB'
#import "ObjectA.h"
#import "..." // Other class headers...


@implementation ObjectB

...

@end

Thanks for any help!

crees!
Aug 26, 2008, 08:54 AM
I also have another file which imports all the object headers for me, Headers.h. Inside, we have:

#import "ObjectA.h"
#import "ObjectB.h"


Okay - ObjectB is a subclass of ObjectA, and in both their header files, they #import "Headers.h" (so I don't have to #import long lists of headers when I have lots of classes, etc.)

I am strongly against lumping all headers into one file. Obviously, you see the issue it's already causing. Second, not all headers will be needed in each of your classes. Third, it makes it difficult at a glance by someone reading your code what the class is about and the functionality it might take on. Fourth, it's just bad practice. Import them like normal and go from there.

crees!
Aug 26, 2008, 08:57 AM
Yes, here are the files I'm using (renamed and stripped of contents):

ObjectA.h
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>

@class ...; // Other, unrelated classes...


@interface ObjectA : NSObject {
...
}

...

@end

ObjectA.m
#import "ObjectA.h"

#import "..." // A few other unrelated class header files...


@implementation ObjectA

...

@end

ObjectB.h
#import <UIKit/UIKit.h>

@class ObjectA;
@class ...; // Other unrelated objects...

@interface ObjectB : ObjectA {
...
}

...

@end

ObjectB.m (with error)
#import "ObjectB.h"
error: cannot find interface decleration for 'ObjectA', superclass of 'ObjectB'
#import "ObjectA.h"
#import "..." // Other class headers...


@implementation ObjectB

...

@end

Thanks for any help!

You don't need to include #import ObjectA.h in ObjectB.m because it's already included in ObjectA.m. Same goes with UIKit. That is unless I'm getting my languages mixed up :p

Aquis
Aug 26, 2008, 09:39 AM
A ha! Just figured it out, can't believe I didn't see it before...

You don't need to include #import ObjectA.h in ObjectB.m because it's already included in ObjectA.m. Same goes with UIKit. That is unless I'm getting my languages mixed up

Actually, you do (I think) - but if you look at the file with the error in, ObjectB.m, you will see that it hasn't imported ObjectA.h when it makes the interface using it, so, I rearranged the order in which they go and...it worked!

@class ObjectA; //this is like a promise to the compiler that you'll import it later

If would appear that in order to inherit from an object, the @class directive doesn't work - you need to have already defined the object.

I don't particularly like Java, but at least it automatically includes all the files you ever need!

Thanks!
Aquis

lee1210
Aug 26, 2008, 10:02 AM
I don't particularly like Java, but at least it automatically includes all the files you ever need!


No it doesn't. You might have an IDE that does, but you have to import anything you want to use in a particular file.

-Lee

davedelong
Aug 26, 2008, 10:04 AM
A ha! Just figured it out, can't believe I didn't see it before...

Actually, you do (I think) - but if you look at the file with the error in, ObjectB.m, you will see that it hasn't imported ObjectA.h when it makes the interface using it, so, I rearranged the order in which they go and...it worked!

If would appear that in order to inherit from an object, the @class directive doesn't work - you need to have already defined the object.

Good catch! I'll have to remember that about using the @class and inheriting! :)

Dave

davedelong
Aug 26, 2008, 10:06 AM
No it doesn't. You might have an IDE that does, but you have to import anything you want to use in a particular file.

-Lee

Well, to be a troll, java.lang.* is automatically imported, but yes: everything else does need to be manually imported.

Aquis
Aug 26, 2008, 10:06 AM
No it doesn't. You might have an IDE that does, but you have to import anything you want to use in a particular file.

-Lee

Are you sure? Oh well - I guess that shows you how much I know of Java...I'm happy now anyway :)

lee1210
Aug 26, 2008, 10:42 AM
Well, to be a troll, java.lang.* is automatically imported, but yes: everything else does need to be manually imported.

Touché. I don't think i've ever gotten away without any imports other than the implicit java.lang.*, but it would be a bit annoying if it was not and anytime you reached for a java.lang.String or java.lang.Integer you'd have to do an import. I'm sure most IDEs would just stick java.lang.* in there for you if that was the case.

-Lee