I'm wondering if it's possible to forward declare an enum that's defined within another class scope. For example, consider the following:
//A.h
class A
{
public:
enum class type: unsigned long { /*some stuff*/ }
};
Now, in another header I'd like to forward declare the 'type' enum (suppose class B below has a function that does something with A::type)
//B.h
enum A::type; //use of undefined type 'A'
class B
{
public:
UseTypeEnum(A::Type&);
};
This doesn't work either:
//B.h
class A;
enum A::type; //still use of undefined type
class B...
There's no problem if the enum is declared at global scope in A.h.
Is there any way to do this?
You can't declare nested types outside the class definition.
If you need to use them outside the class, you will have to either include the class definition, or move them into a namespace.
Related
Sometimes I use foreward declaration for nested classes:
class A;
class B
{
private:
A* object_A;
public:
B(){}
};
The question: What happens if I now use forward declaration of class B (B is declared and defined at this point) for the useage in class C? Does this cause any problems with class B, because it is defined (with implementation of methods etc.) but is used with forward declaration for class C? Does the syntax class B; in the following code-snippet overwrites somehow the previous declared, defined and implemented class B?
class B;
class C
{
private:
B* object_B;
public:
C(){}
};
Does the syntax class B; in the following code-snippet overwrites somehow the previous declared, defined and implemented class B?
Forward declarations are not about overwriting. It is just giving hint to the compiler that the type definition is implemented somewhere. For user defined pointer types, compiler does not require the definition but needs to know what is the type of the object.
For example, class A has a member of class B. In general, for the purpose of minimizing compilation dependency, we often make class A include B's pointer, and pre-declare class B in the class A's declaration. Looks like this:
//B.h
class B
{
....
};
//A.h
class B;
class A
{
B*b;
A();
...
};
//A.cpp
#include "B.h"
A::A()
{
b=new B();
...
};
But now I have a question: if the class of B is defined using typedef like this:
typedef class
{
....
}B;
The previous pre-declared method will not work in this case. How should I pre-declare the class B in A.h?
In the code typedef class { .... } B; , it is an unnamed class, with B being a type alias for the unnamed class.
It is not possible to declare an unnamed class without defining it (i.e. providing the class body); and it is not possible to declare that B is a typedef for an unnamed class.
There is no such thing as a forward declaration of a typedef. In general a typedef can declare an alias for incomplete type that is completed later, but an unnamed class cannot fill either of those roles.
Removed further advice in response to voter feedback
Note: the question used the term "pre-declare". The C++ Standard does not use the terms "pre-declare" or the more common jargon "forward-declare". In the standard's terminology, a forward declaration of a class is simply called a class declaration. This can be clarified by saying "declaration that is not a definition" if it is not clear from context already.
Is there any way to redeclare a class to define methods which where only declared this far?
Eg. something like:
class A
{
void a();
void b() {}
}
class A
{
void a() {}
}
instead of
class A
{
void a();
void b() {}
}
A::a() {}
The reason is I created a lot of code with methods defined inside the class defintion, without using headers. I do not had cyclic references up to now, but recently there is need to. I don't like to define bunches of methods by the Type::method syntax, as only very few methods have to be known before the latter definition of the class.
So I like somewhat like a backward declaration, declare or define only a few methods before for cyclic references and define the whole class later.
No, there is no way to redefine a class.
According to the C++ language standard the class definitions is:
class-specifier:
class-head { member-specification_opt }
The standard explicitly says that member specification should be complete within class definition:
Members of a class are data members, member functions (9.3), nested types, and enumerators. The member-specification in a class definition declares the full set of members of the class; no member can be added elsewhere.
Also the standard gives example of redefinition of class:
struct S { int a; };
struct S { int a; }; // error, double definition
is ill-formed because it defines S twice.
Unfortunately there is no way to declare the class again once it is Closed with }.
Only thing you can do is you can inherit and define the method.
class B : public A { a() {} } ;
I have put several instances of class b in class a but this causes an error as class a does not know what class b is.
Now I know I can solve this problem by writing my file b a c but this messes up the reachability as well as annoys me. I know I can prototype my functions so I do not have this problem but have been able to find no material on how to prototype a class.
does anyone have an example of class prototyping in c++.
as there seems to be some confusion let me show you what i want
class A
{
public:
B foo[5];
};
class B
{
public:
int foo;
char bar;
}
but this does not work as A cannot see B so i need to put something before them both, if it was a function i would put A(); then implement it later. how can i do this with a class.
You can declare all your classes and then define them in any order, like so:
// Declare my classes
class A;
class B;
class C;
// Define my classes (any order will do)
class A { ... };
class B { ... };
class C { ... };
You're looking for declarations.
class A;
class B {
A MakeA();
void ProcessA(A a);
};
class A {
B bs[1000];
};
If you forward declare a class, you can
declare functions taking and returning it or complex types made of it
declare member variables of pointer or reference to it
This basically means that in any case which doesn't end up with instances of A inside B and vice versa, you should be able to declare and define any interface between A and B.
The usual way to resolve circular dependencies is to use a forward declaration:
// Bar.h
class Foo; // declares the class Foo without defining it
class Bar {
Foo & foo; // can only be used for reference or pointer
};
// Foo.h
#include <Bar.h>
class Foo {
Bar bar; // has full declaration, can create instance
}
You can provide a full declaration and definition in another file. Using the forward declaration, you can create pointers and references to the class, but you cannot create instances of it, as this requires the full declaration.
class b;
class a {
public:
b * inst1;
};
class b{
....
};
Is this what you needed ?
Previously I've defined enumerated types that are intended to be private in the header file of the class.
private:
enum foo { a, b, c };
However, I don't want the details of the enum exposed anymore. Is defining the enum in the implementation similar to defining class invariants?
const int ClassA::bar = 3;
enum ClassA::foo { a, b, c };
I'm wondering if this the correct syntax.
C++ doesn't have forward declarations of enums, so you can't separate enum "type" from enum "implementation".
The following will be possible in C++0x:
// foo.h
class foo {
enum bar : int; // must specify base type
bar x; // can use the type itself, members still inaccessible
};
// foo.cpp
enum foo::bar : int { baz }; // specify members
No, enum ClassA::foo { a, b, c }; is not correct syntax.
If you want to move the enum out of the header and into the implementation (.cpp) file, then just do that. If you want to use the enum for parameter types of methods of the class, then you cannot move it, so just leave it private.