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
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
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
Yes, however the syntax is not clear to me. Could you please give an
example?
Armin
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
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.
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();
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.
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
Yes, these 3 "levels" were my problem:
- class declartion
- class definition = member declaration
- member definition
Armin
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
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.
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).
Thx for the hint and example. Also to the other guys.
Armin