Defining derivated class problem

This is a discussion on Defining derivated class problem within the C++ Programming forums, part of the General Programming Boards category; I try to define a derived class that I would like to use in another derived class, but defining the ...

  1. #1
    Registered User mikahell's Avatar
    Join Date
    Jun 2006
    Posts
    114

    Defining derivated class problem

    I try to define a derived class that I would like to use in another derived class, but defining the first one after the second... It works when not bothering with inheritence:

    Code:
    class class1;  //Declaration
    
    class class2
    {
    private:
        class1 *ptr;
    ......
    };
    
    class class1 {...}; //Definition
    But as soon as they inherit from a base class, I can't seem to find the good declaration syntax:

    Code:
    class base
    {
    public:
        base() {}
        ~base() {}
        virtual void uselessFunction() = 0; //Just to make it a base class :)
    };
    
    class class1 : public base;  //Declaration... doesn't work :(
    
    class class2 : public base
    {
    private:
        class1 *ptr;
    public:
        void uselessFunction() {}
    };
    
    class class1 : public base
    {
    public:
        void uselessFunction() {}
    };
    I know that my code sample might really seem useless... But I just wanted to keep it simple there... I need to have a "class1" pointer in "class2", and I want to be able to use its "base" methods. I know I can't use the other "class2" methods since the class is defined after, but its base methods should be accessible, isn't it?? I'm using VS 2003... Is there a solution for defining the "class1" with its "public base" specifier?

    Thanks!

  2. #2
    Registered User
    Join Date
    Jan 2005
    Posts
    7,340
    Code:
    class class1;
    That's all you need for the forward declaration.

  3. #3
    Registered User mikahell's Avatar
    Join Date
    Jun 2006
    Posts
    114
    Well... It doesn't work for me... Maybe I wasn't clear enough... Let's say in "class2", I want to use my "undefined class1 pointer" to call a method from the "base" class. If I only define class1 as "class class1;" before class2, then the compiler will complain on the following method

    Code:
    class2::someMethod(void)
    {
        ptr->uselessFunction(); //Remember, "ptr" is a pointer on "class1" here, not "class1:public base" :(
    }
    I get the error "using undefined type 'class1'... Maybe to make it right, I could convert the pointer to a (base*) pointer and use the virtual function, but I doubt it would give the expected result...

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,340
    This should have nothing to do with the base class. If you use the class1 pointer at all, you have to define it before you use it.

    add class2::someMethod after you define class1. Like this:
    Code:
    class base
    {
    public:
        base() {}
        virtual ~base() {}
        virtual void uselessFunction() = 0; //Just to make it a base class :)
    };
    
    class class1;
    
    class class2 : public base
    {
    private:
        class1 *ptr;
    public:
        void someMethod();
        void uselessFunction() {}
    };
    
    class class1 : public base
    {
    public:
        void uselessFunction() {}
    };
    
    void class2::someMethod()
    {
        ptr->uselessFunction();
    }
    Last edited by Daved; 08-22-2007 at 03:44 PM.

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    To expand on what Daved says:

    The class1 forward declaration allows you to declare a pointer to an yet-unknown structure/class - but you can't use any of it's content until you've told the compiler what it is and where it is (and which class it inherits). For the compiler to be able to figure out what "uselessFunction()" is, and how it's called, it needs to know what class1 looks like.

    So, Daved's solution is the right one - declare both classes then declare any functions/methods. (Since I'm fairly new to C++, I actually took your code and tried a similar thing to what Daved suggested before posting a reply here, Daved probably KNEW that already!)


    --
    Mats

  6. #6
    Registered User mikahell's Avatar
    Join Date
    Jun 2006
    Posts
    114
    Defining both classes methods afterwards.... Oops, forgot to try this solution :P Logically this should solve my problem, thanks to you both!

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by mikahell View Post
    Defining both classes methods afterwards.... Oops, forgot to try this solution :P Logically this should solve my problem, thanks to you both!
    I'd like to add that this would make no difference to the methods of the classes - it may seem like if you declare a method inside the actual classs declaration, it makes something more efficient for the compiler or some such - it's not - it keeps the method easy to find (as long as there's not TOO much of it), but that's the ONLY consequence of having the declaration there.

    --
    Mats

  8. #8
    Registered User
    Join Date
    Jan 2005
    Posts
    7,340
    >> that's the ONLY consequence of having the declaration there.
    Putting the function definition inside the class definition also has the effect of marking the function as inline. While many optimizing compilers make their own decisions about what to inline, they do take into consideration the programmers suggestions.

    Many people like to have some one line functions (like get and set methods) declared inline in the class definition. However, if you're going to be using a variable of a class that you forward declared, it is best to just make the function definition outside of the class definition.

    Also note that normally these things are broken up in header and source files. For example:
    Code:
    // base.h
    #ifndef BASE_H
    #define BASE_H
    
    class base
    {
    public:
        base() {}
        virtual ~base() {}
        virtual void uselessFunction() = 0; //Just to make it a base class :)
    };
    
    #endif
    Code:
    // class2.h
    #ifndef CLASS2_H
    #define CLASS2_H
    
    #include "base.h"
    
    class class1;
    
    class class2 : public base
    {
    private:
        class1 *ptr;
    public:
        void someMethod();
        void uselessFunction() {}
    };
    
    #endif
    Code:
    // class1.h
    #ifndef CLASS1_H
    #define CLASS1_H
    
    #include "base.h"
    
    class class1 : public base
    {
    public:
        void uselessFunction() {}
    };
    
    #endif
    Code:
    // class2.cpp
    
    #include "class2.h"
    
    void class2::someMethod()
    {
        ptr->uselessFunction();
    }
    Of course you'd probably also have a class1.cpp and a maybe a base.cpp for implementations of the member functions of those classes.
    Last edited by Daved; 08-22-2007 at 03:44 PM.

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Daved View Post
    >> that's the ONLY consequence of having the declaration there.
    Putting the function definition inside the class definition also has the effect of marking the function as inline. While many optimizing compilers make their own decisions about what to inline, they do take into consideration the programmers suggestions.
    Ah, good point - I didn't know that inline was implicit on method declarations inside the class declaration. But as you say, the compiler usually makes better decisions than the average programmer on what should and shouldn't be inlined - and it certainly only takes SOME consideration to what the programmer says with regards to inline.

    --
    Mats

  10. #10
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Also, don't forget to make your base class destructor virtual!

    Code:
    // base.h
    #ifndef BASE_H
    #define BASE_H
    
    class base
    {
    public:
        base() {}
        virtual ~base() {}
        virtual void uselessFunction() = 0; //Just to make it a base class :)
    };
    
    #endif

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Class Membership Problem
    By josephjah in forum C++ Programming
    Replies: 5
    Last Post: 05-27-2007, 01:48 PM
  2. Inheritance using Stack Class Problem
    By dld333 in forum C++ Programming
    Replies: 17
    Last Post: 12-06-2005, 10:14 PM
  3. Replies: 3
    Last Post: 10-31-2005, 11:05 AM
  4. static class problem.
    By Sebastiani in forum C++ Programming
    Replies: 3
    Last Post: 10-16-2002, 03:27 PM
  5. Difficulty superclassing EDIT window class
    By cDir in forum Windows Programming
    Replies: 7
    Last Post: 02-21-2002, 04:06 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21