Elliot Bonneville
Elliot Bonneville

Reputation: 53291

How do I access a class from within a class defined above it?

If I have classes A and B, how can I create a reference to B inside of A? I read that you need use a pointer or a reference, but I can't find out more than that. Here's an example of what I'm talking about:

class B;

class A {
    public: 

    B * b_pointer;

    void setSelf(B * given_b_pointer) {
        b_pointer = given_b_pointer;
    };

    void printBName() {
        print (b_pointer.my_name);
    };
};

class B {
    public:

    string my_name;

    void setSelf(string my_given_name) {
        my_name = my_given_name;
    };
}

This gives me several errors. What am I doing wrong, and how can I fix it?

EDIT: The relevant error message:

error: request for member 'my_name' in '((B*)this)->A::b_pointer', which is of non-class type 'B*'.

Error message slightly edited to replace actual class names with psuedo-class names.

Upvotes: 3

Views: 209

Answers (4)

TonyK
TonyK

Reputation: 17114

The A::setSelf function compiles without errors, because it only manipulates pointers to B, not members of B. As soon as you try to access the members of B in A::printBName, the compiler complains, because it doesn't know anytihng about B yet except that it is a class.

The way around it is to define the function A::printBName outside the class, after B has been defined. So in the definition of class A:

void setSelf(B * given_b_ref) ; // No definition, just declaration

And then, after the definition of class B:

void A::printBName() { // Here's the definition
    print (b_ref.my_name);
}

Also, note that a function definition doesn't need a semicolon after the closing brace.

Upvotes: 1

Jaffa
Jaffa

Reputation: 12700

Use forward declaration or declare class B before A:

class B;
class A {
    B* ref;
    // Your stuff here
};

class B {
    // Other stuff
}

But prefer using two separate files if you want to create two classes. Thus you just have to include "B.hpp" before class A declaration.

EDIT:

If you see your error, this mean that you can't use a forward declared member as a type. Thus you can either declare the class before, or better create an interface which represents the behavior needed for that class, and declare it before.

You will then be able to declare your classes as you wish, as the interfaces don't have any members and thus can work with forward declaration, and the classes use the interfaces so don't care about any future class that may be defined :)

EDIT 2:

Your error tells us that it's not a class access that you need, you just need to correct the operator you uses:

You wrote

print (b_ref.my_name);

Instead of:

print (b_ref->my_name);

Upvotes: 0

Andres
Andres

Reputation: 5187

Try

class B 
{
   public:

   string my_name;

   void setSelf(string my_given_name) {
       my_name = my_given_name;
    };
}

class A 
{ 
    public: 

    B * b_ref;

    void setSelf(B * given_b_ref) {
        b_ref = given_b_ref;
    };

    void printBName() {
        print (b_ref->my_name);
    };
};

Upvotes: 1

Joe
Joe

Reputation: 57169

[Updated] You need to forward declare class B and you can not use any of B's members in the class until it has been declared so move the declaration of printBName to the code file.

class B; //Forward declaration

class A {
    public: 
    B * b_ref;

    ...

    void printBName(); //Need to forward declare this as well
};

class B {
    ...
};

//Now define printBName
void A::printBName(){
    print (b_ref->my_name);// use -> to dereference b_ref
}

Upvotes: 5

Related Questions