Sign in to follow this  
digitalfreak

I can't use nested class outside of the enclosing class.

Recommended Posts

digitalfreak    164
I declared class A in the definition of class B in a .h file (in the public section). then I defined class A in the corresponding .cpp file. the when I defined an object of A outside B like this B::A a, the complier says error C2079: 'a' uses undefined class 'B::A' where went wrong? the c++ primer plus book clearly says, to use an object of an nested class outside of the enclosing class, the nested class must be declared in the public section of the enclosing class and used with the scope resolution operator :: obviously I did both. but why still couldn't compile? XX.h code:
class B
{
    class A;
    //other parts of the definition of B
};

XX.cpp code:
class B::A
{
    //definition of A
};

Share this post


Link to post
Share on other sites
Fruny    1658
Quote:
Original post by digitalfreak
I declared class A in the definition of class B in a .h file (in the public section). then I defined class A in the corresponding .cpp file.
the when I defined an object of A outside B like this B::A a, the complier says
error C2079: 'a' uses undefined class 'B::A'


Can you show actual code, it'll be better than trying to describe how you coded things up.

Anyway, it says 'undefined' not 'undeclared' - put the definition for A in the header file, too.

Share this post


Link to post
Share on other sites
snk_kid    1312
If you want to use a nested class outside in other headers & source files it must be defined in the header, there is no way that its definition can be seen from a source file (unless your crazy and include that aswell). Your header should look something like:


struct foo{

struct bar;

};

struct foo::bar { /*definition*/ };


What your currently doing is is something known as opaque bridge (i think thats what its called i can't remember), where you do a forward nested class declaration but its private and you have it is a pointer member, its only defined & used in one source file but nothing else can see or use it.

Share this post


Link to post
Share on other sites
snk_kid    1312
Can some-body tell me what the name of this idiom is called again:

header file:

#include <memory>

class foo {

struct bar;
std::auto_ptr<bar> b;

public:

foo();
//...
};


source-file:

#include "foo.hpp"

struct foo::bar { /* def */ };

foo::foo(): b(new bar()){}


Was it handle-body idiom?

Share this post


Link to post
Share on other sites
Fruny    1658
Quote:
Original post by snk_kid
Can some-body tell me what the name of this idiom is called again


Pimpl idiom, or Bridge Pattern, depending on who you're talking to.

Share this post


Link to post
Share on other sites
Skizz    794
It is possible to do this:

"xx.h"

class B
{
private:
class A
{
void func_a (void);
};

// other stuff
};

"xx.cpp"

void B::A::func_a (void)
{
// code
}

But that exposes A to clients of B (it's implementation at least, it can't be direectly used though).
If you want to hide A totally from clients of B then instances of A in B need to be references / pointers and use forward declaration (a bit like what you had).

Skizz

Share this post


Link to post
Share on other sites
snk_kid    1312
Quote:
Original post by digitalfreak
but why member functions can be defined in a seperate source file?


The meaning of defintion of class & definition of function are not quite the same.

The meaning of "class defintion" are declaration of members (be it data decalartions or/and method decalartions)

The meaning of "function definition" is implementation the actual code.

forward class declaraction doesn't declare any members it just introduces a new type-name so you can only use reference/pointers to it before its been defined but its definition must evetunally available & seen in the scope its being used.

Quote:
Original post by Fruny
Quote:
Original post by snk_kid
Can some-body tell me what the name of this idiom is called again


Pimpl idiom, or Bridge Pattern, depending on who you're talking to.


Ah yes how can anyone forget a name like PimpL [smile]

[Edited by - snk_kid on November 24, 2004 10:59:11 AM]

Share this post


Link to post
Share on other sites
SiCrane    11839
Quote:
Original post by digitalfreak
Mmm, I guess it's like snk_kid said.
but why member functions can be defined in a seperate source file?

Like members, you can define the nested class in a separate source file if you choose. You just need to follow all the normal
rules for using a class that only has a forward declaration in the header/initial class declaration, like using pointers and references properly.

Header:

class A {
public:
class B;

void some_func(B *);
};

Source file:

class A::B {
public:
void some_func(void);
};

void A::some_func(A::B * a_b) {
a_b->some_func();
}

void A::B::some_func(void) {
}

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this