Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Forward declaration of managed class: howto?

1 view
Skip to first unread message

Armin Zingler

unread,
Sep 24, 2008, 7:52:36 AM9/24/08
to
Hi,

I'm using VC++ 2008 Express. I have this managed class:

ref class C1
{
private:
UINT i;

public:
C1()
{
//code
};

void MyMethod()
{
//code
};
}

How am I to forward declare this class and it's public members? What do I
have to put in the header file? I'd like to include the header file in
another class, create an instance of C1 and access it's public members.
However, if I only write

ref class C1;

it complains when trying to create an instance (using gcnew keyword) because
it doesn't find the appropriate constructor. Now, if I do add it in the
forward declaration this way

ref class C1
{
C1();
};

then it works but it complains at the definition of the class: error
C2011...class redefinition. But the first should only be the declaration,
not the definition. So, how to declare only but not define in the header
file? I've searched for "forward declaration" a lot but didn't find anything
satisfying. All I found was forward declaring the class but without
mentioning it's members.


Armin

Igor Tandetnik

unread,
Sep 24, 2008, 7:59:29 AM9/24/08
to
"Armin Zingler" <az.n...@freenet.de> wrote in message
news:ueAUVwjH...@TK2MSFTNGP06.phx.gbl

> I'm using VC++ 2008 Express. I have this managed class:
>
> How am I to forward declare this class and it's public members?

There ain't no such thing as "forward declare class memebers", public or
otherwise. You can forward-declare a class name, or you can provide a
definition of the class which declares its members. The actual
implementation for member functions could be elsewhere.

> Now, if I do add
> it in the forward declaration this way
>
> ref class C1
> {
> C1();
> };
>
> then it works but it complains at the definition of the class: error
> C2011...class redefinition. But the first should only be the
> declaration, not the definition.

It's a definition of the class, which contains the declaration for its
constructor.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925


David Wilkinson

unread,
Sep 24, 2008, 8:13:29 AM9/24/08
to

Armin:

You have to do

#include "C1.h"

if you are actually going to use the class C1.

That said, it is the C++/CLI habit of putting everything in the header file that
is causing you to have to do this. If you move the actual code of your main form
to its .cpp file, then you could do forward declaration as you desire.

--
David Wilkinson
Visual C++ MVP

Armin Zingler

unread,
Sep 24, 2008, 8:48:06 AM9/24/08
to
"David Wilkinson" <no-r...@effisols.com> schrieb

Yes, however the syntax is not clear to me. Could you please give an
example?


Armin

Armin Zingler

unread,
Sep 24, 2008, 8:48:06 AM9/24/08
to
"Igor Tandetnik" <itand...@mvps.org> schrieb

> "Armin Zingler" <az.n...@freenet.de> wrote in message
> news:ueAUVwjH...@TK2MSFTNGP06.phx.gbl
> > I'm using VC++ 2008 Express. I have this managed class:
> >
> > How am I to forward declare this class and it's public members?
>
> There ain't no such thing as "forward declare class memebers",
> public or otherwise. You can forward-declare a class name, or you
> can provide a definition of the class which declares its members.
> The actual implementation for member functions could be elsewhere.

Yes, but how? If you call the declaration definition and the definition
implemenatation, I don't know which one is what.

> > Now, if I do add
> > it in the forward declaration this way
> >
> > ref class C1
> > {
> > C1();
> > };
> >
> > then it works but it complains at the definition of the class:
> > error C2011...class redefinition. But the first should only be the
> > declaration, not the definition.
>
> It's a definition of the class, which contains the declaration for
> its constructor.

Ok, but how does the implementation look like then? Without getting C2011
again.

I must add that I usually write my classes, and that's it (in VB.Net or C#).
Didn't know the C++ compiler still needs so much support from me.


Armin

Igor Tandetnik

unread,
Sep 24, 2008, 9:08:57 AM9/24/08
to
"Armin Zingler" <az.n...@freenet.de> wrote in message
news:%23DW2fPk...@TK2MSFTNGP03.phx.gbl

> "Igor Tandetnik" <itand...@mvps.org> schrieb
>> "Armin Zingler" <az.n...@freenet.de> wrote in message
>> news:ueAUVwjH...@TK2MSFTNGP06.phx.gbl
>>> I'm using VC++ 2008 Express. I have this managed class:
>>>
>>> How am I to forward declare this class and it's public members?
>>
>> There ain't no such thing as "forward declare class memebers",
>> public or otherwise. You can forward-declare a class name, or you
>> can provide a definition of the class which declares its members.
>> The actual implementation for member functions could be elsewhere.
>
> Yes, but how? If you call the declaration definition and the
> definition implemenatation, I don't know which one is what.

This is a declaration of the class (also known as forward declaration):

class C;

This is a definition of the class, that contains declarations of its
members:

class C {
int member;

C();
void method1();
void method2();
};

These are defintions of class' member functions:

C::C() { ... }
void C::method1() { ... }

Typically, you would put class definition in a .h file, and method
definitions in a .cpp file. You would #include this .h file (but not the
.cpp file, of course) everywhere you need to use the class.

David Wilkinson

unread,
Sep 24, 2008, 9:16:13 AM9/24/08
to
Armin Zingler wrote:
> Yes, however the syntax is not clear to me. Could you please give an
> example?

Armin:

Actually, this group is for standard C++. For C++/CLI you should be using

microsoft.public.dotnet.languages.vc

But, IMHO, you should not be trying to learn C++/CLI unless you already know
standard C++. In native C++ the standard pattern is

//A.h

class A // class definition
{
public:
int DoSomething();
};

//A.cpp

#include "A.h"

int A::DoSomethng() // method implementation
{
return 1;
}

// B.h

class A; // forward declaration

class B
{
private:
A* m_pA;
public:
B();
~B()
int DoSomething()
};

// B.cpp

#include "A.h"
#include "B.h"

B::B()
{
m_pA = new A;
}

B::~B()
{
delete m_pA;
}

int B::DoSomething()
{
return m_pA->DoSomething();

Connor...@gmail.com

unread,
Sep 24, 2008, 10:13:58 AM9/24/08
to
On Sep 24, 3:48 pm, "Armin Zingler" <az.nos...@freenet.de> wrote:
> [skipped]

> Yes, but how? If you call the declaration definition and the definition
> implemenatation, I don't know which one is what.
> [skipped]
> Armin

Hi, Armin!

Class declaration looks like:
class SomeClass;

Class definition:
class SomeClass
{
SomeMethod();
}

Class may be declared several times,
but must be defined only once.

Class declaration doesn't give any information about
class except it's name.

Armin Zingler

unread,
Sep 24, 2008, 10:38:07 AM9/24/08
to
"David Wilkinson" <no-r...@effisols.com> schrieb

> Armin Zingler wrote:
> > Yes, however the syntax is not clear to me. Could you please give
> > an example?
>
> Armin:
>
> Actually, this group is for standard C++. For C++/CLI you should be
> using
>
> microsoft.public.dotnet.languages.vc

Ok, will keep that in mind.

> But, IMHO, you should not be trying to learn C++/CLI unless you
> already know standard C++. In native C++ the standard pattern is

Ok

> [Code]

Thanks. Got that. However, my problem was that declaring the members is
equal to defining the class. It's not possible to declare the class and all
it's members at one location, typcially in the header file, then do the
definition/implementation in the CPP file. Something like (which does not
work):

// C.h
ref class C {C();}

// C.cpp
ref class C
{
private:
int member;
public:
C() {/*whatever*/};
}

// D.cpp
#include "C.h"
...
C^ bla = gcnew C();

Would be more intuitive to me. Well, can't change that anyway.


Armin

Armin Zingler

unread,
Sep 24, 2008, 10:38:07 AM9/24/08
to
<Connor...@gmail.com> schrieb

Yes, these 3 "levels" were my problem:
- class declartion
- class definition = member declaration
- member definition


Armin

Armin Zingler

unread,
Sep 24, 2008, 10:38:08 AM9/24/08
to
"Igor Tandetnik" <itand...@mvps.org> schrieb


Thanks for clarification! Now it's clear. Though, what I don't like is
splitting one class into two or three parts. Everytime I change anything, I
have to change it twice. In addition, the class' member function definitions
seem to stand "nowhere", i.e. not encapsulated by anything like "class C
{...}". And, the private members (fields) are not where I expect them.
I want to declare them at the same location where I implement (=define) the
member functions. What if "int member" is private? Then I don't need it in
the header file because another class can not acces it anyway. Well, I'll
have to live with it.

Maybe adding an interface will make things simpler. Will have to try...


Thanks again.

Armin

David Wilkinson

unread,
Sep 24, 2008, 11:04:05 AM9/24/08
to
Armin Zingler wrote:
> Thanks. Got that. However, my problem was that declaring the members is
> equal to defining the class. It's not possible to declare the class and all
> it's members at one location, typcially in the header file, then do the
> definition/implementation in the CPP file. Something like (which does not
> work):
>
> // C.h
> ref class C {C();}
>
> // C.cpp
> ref class C
> {
> private:
> int member;
> public:
> C() {/*whatever*/};
> }
>
> // D.cpp
> #include "C.h"
> ...
> C^ bla = gcnew C();
>
>
>
> Would be more intuitive to me. Well, can't change that anyway.

Armin:

When the object is created, the compiler has to know how big it is. Therefore it
needs to see the entire class definition. So the entire class definition has to
be in the header file, including the private member variables.

David Wilkinson

unread,
Sep 24, 2008, 11:09:51 AM9/24/08
to
Armin Zingler wrote:
> Thanks for clarification! Now it's clear. Though, what I don't like is
> splitting one class into two or three parts. Everytime I change anything, I
> have to change it twice. In addition, the class' member function
> definitions
> seem to stand "nowhere", i.e. not encapsulated by anything like "class C
> {...}". And, the private members (fields) are not where I expect them.
> I want to declare them at the same location where I implement (=define) the
> member functions. What if "int member" is private? Then I don't need it in
> the header file because another class can not acces it anyway. Well, I'll
> have to live with it.
>
> Maybe adding an interface will make things simpler. Will have to try...

Armin:

The method (member function) definitions may appear to be "nowhere", but they
are scoped with the class name (and namespace name if any).

As I explained in my other answer, the private members must be in the class
definition so that the compiler knows how big the object is.

There are two way to hide this information from clients of the class:

1. Abstract Base Class (interface)

2. Pointer to Implementation (PIMPL).

Armin Zingler

unread,
Oct 14, 2008, 2:25:45 PM10/14/08
to
"David Wilkinson" <no-r...@effisols.com> schrieb

> Armin Zingler wrote:
> > Yes, however the syntax is not clear to me. Could you please give
> > an example?
>
> Armin:
>
> Actually, this group is for standard C++. For C++/CLI you should be
> using
>
> microsoft.public.dotnet.languages.vc


Thx for the hint and example. Also to the other guys.


Armin

0 new messages