Problem with Inheritance and Header Files

Discussion in 'Mac Programming' started by Aquis, Aug 25, 2008.

  1. macrumors member

    Joined:
    Aug 7, 2007
    Location:
    Staffordshire, UK
    #1
    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:
    Code:
    #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!
     
  2. macrumors member

    davedelong

    Joined:
    Sep 9, 2007
    Location:
    Right here.
    #2
    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:

    Code:
    //ObjectB.h
    @class ObjectA;  //this is like a promise to the compiler that you'll import it later
    
    @interface ObjectB : ObjectA {
    ...
    }
    ...
    @end
    Code:
    //ObjectB.m
    #import "ObjectB.h"
    #import "ObjectA.h"
    
    @implementation ObjectB
    ...
    @end
    HTH,

    Dave
     
  3. thread starter macrumors member

    Joined:
    Aug 7, 2007
    Location:
    Staffordshire, UK
    #3
    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)...
     
  4. macrumors member

    davedelong

    Joined:
    Sep 9, 2007
    Location:
    Right here.
    #4
    Is ObjectB inheriting from ObjectA? Like so:

    Code:
    //ObjectB.h
    
    #import <Cocoa/Cocoa.h>
    
    @class Object A;
    
    @interface ObjectB : ObjectA {
    ...
    }
    ...
    @end
    Dave
     
  5. thread starter macrumors member

    Joined:
    Aug 7, 2007
    Location:
    Staffordshire, UK
    #5
    Yes, here are the files I'm using (renamed and stripped of contents):

    ObjectA.h
    Code:
    #import <UIKit/UIKit.h>
    #import <CoreLocation/CoreLocation.h>
    
    @class ...; // Other, unrelated classes...
    
    
    @interface ObjectA : NSObject {
    	...
    }
    
    ...
    
    @end
    ObjectA.m
    Code:
    #import "ObjectA.h"
    
    #import "..." // A few other unrelated class header files...
    
    
    @implementation ObjectA
    
    ...
    
    @end
    ObjectB.h
    Code:
    #import <UIKit/UIKit.h>
    
    @class ObjectA;
    @class ...; // Other unrelated objects...
    
    @interface ObjectB : ObjectA {
    	...
    }
    
    ...
    
    @end
    ObjectB.m (with error)
    Code:
    #import "ObjectB.h"
    [COLOR="Red"][B]error: cannot find interface decleration for 'ObjectA', superclass of 'ObjectB'[/B][/COLOR]
    #import "ObjectA.h"
    #import "..." // Other class headers...
    
    
    @implementation ObjectB
    
    ...
    
    @end
    Thanks for any help!
     
  6. macrumors 68000

    crees!

    Joined:
    Jun 14, 2003
    Location:
    MD/VA/DC
    #6
    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.
     
  7. macrumors 68000

    crees!

    Joined:
    Jun 14, 2003
    Location:
    MD/VA/DC
    #7
    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
     
  8. thread starter macrumors member

    Joined:
    Aug 7, 2007
    Location:
    Staffordshire, UK
    #8
    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.

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

    Thanks!
    Aquis
     
  9. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #9
    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
     
  10. macrumors member

    davedelong

    Joined:
    Sep 9, 2007
    Location:
    Right here.
    #10
    Good catch! I'll have to remember that about using the @class and inheriting! :)

    Dave
     
  11. macrumors member

    davedelong

    Joined:
    Sep 9, 2007
    Location:
    Right here.
    #11
    Well, to be a troll, java.lang.* is automatically imported, but yes: everything else does need to be manually imported.
     
  12. thread starter macrumors member

    Joined:
    Aug 7, 2007
    Location:
    Staffordshire, UK
    #12
    Are you sure? Oh well - I guess that shows you how much I know of Java...I'm happy now anyway :)
     
  13. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #13
    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
     

Share This Page