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

Started by
8 comments, last by SiCrane 19 years, 5 months ago
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
};

Advertisement
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.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
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.
Mmm, I guess it's like snk_kid said.
but why member functions can be defined in a seperate source file?
Quote:Original post by digitalfreak
Mmm, I guess it's like snk_kid said.


yes
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
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?
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.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
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
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]
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) {}

This topic is closed to new replies.

Advertisement