I just stumbled a c++ code with a calling of a class name in the upper part of the header file for example
class CFoo;
class CBar
{
....
};
My question is, what is class CFoo for?
Thanks alot!
This is called a forward declaration. It means that there IS a class named CFoo, that will be defined later in the file (or another include). This is typically used for pointer members in classes, such as:
class CFoo;
class CBar {
public:
CFoo* object;
};
It is a hint to the C++ compiler telling it not to freak out that a type name is being used without being defined, even though it hasn't seen the full definition for CFoo yet.
It's called a forward declaration.
http://en.wikipedia.org/wiki/Forward_declaration
class CFoo;
Is just a declaration that the class exists; even if you haven't seen the definition yet, you can still play with (CFoo *) or (CFoo &) - that is, pointers and references to CFoo.
Related
Is it possible to separate class declaration from its definition? Of course it is, but what if I want to have an object of this class before the actual definition of it? Consider the following example:
class ID3_Reader{
public:
// code omitted for brevity
protected:
class Mp3_File;
Mp3_File mFile;
};
It's obvious that it will not compile. I would have to define the Mp3_File class inside the ID3_Reader class. It's not a problem when I have just two classes. What if there would be like five of them? My code would become pretty messy. To avoid this problem I would have to separate the class declarations from their definitions. How can I achieve that? Remember that I need an instance of the Mp3_File class inside the ID3_Reader class.
The reason why I'm using nested classes is because I don't want some other programmer to use the Mp3_File class. I used "protected" keyword because I will create classes based on the ID3_Reader class.
You can achive this by using a pointer like the other guys answered:
class Mp3_File; // forward declaration of class Mp3_File
class ID3_Reader{
public:
// code omitted for brevity
protected:
Mp3_File *mFile;
};
Or you can declare the constructor of class Mp3_File private and declare class ID3_Reader friend of class Mp3_File:
class Mp3_File {
Mp3_File() {} // constructor is private
friend class ID3_Reader;
};
class ID3_Reader{
public:
// code omitted for brevity
protected:
Mp3_File mFile;
};
auto main() -> int {
ID3_Reader r;
Mp3_File m; // Error Mp3_File constructor is private!
return 0;
}
Thus, other people won't be able to use Mp3_File while you can use it in the scope of class ID3_Reader.
It won't compile because the compiler doesn't know how much memory that Mp3_File class will use. If you change it to a pointer
class ID3_Reader{
public:
// code omitted for brevity
protected:
class Mp3_File;
Mp3_File *mFile;
};
that compiles just fine (a pointer has a fixed size - http://ideone.com/VmmXfK).
I suggest using a pointer instead of a complete member variable and initialize/deinitialize it in the ctor/dtor.
I don't see another way of doing it without changing the "nested classes" design.
You can achieve that by using pointers. Recall that although you must have a full class to define a variable, a simple forward declaration is good to define a pointer:
class ID3_Reader{
public:
// code omitted for brevity
protected:
class Mp3_File;
Mp3_File *mFile;
};
Unfortunately, this puts you on the hook for managing the memory for the nested class, but it does hide all of the internals of the class from outside programmers.
Instead of defining mFile as an instance of Mp3_File, define it as a pointer to an Mp3_File. That way you won't need to know the definition in the header file. Or better yet - use a smart pointer. You will then need to create the real instance by using new in the class constructor and delete it in ID3_Reader's destructor.
If you wish to stay with your current syntax to access mFile from outside of the class, dereference it inside the accessor function:
Mp3_File& getMp3(){ return *mFile; };
Then - if Mp3_File has an overloaded operator() (or any other overloaded operator as a matter of fact), you won't need to dereference it every time manually.
You can make your class a class template to work around this restriction: for class templates the definition of the nested type needs to be visible at instantiation time, not while looking at the definition of the class template. You might want to use a typedef to actually name the used instantiation to avoid the need to have a trailing <>. Here is a quick demo:
template <typename = void>
class ID3_ReaderT {
public:
// code omitted for brevity
protected:
class Mp3_File;
Mp3_File mFile;
};
typedef ID3_Reader<> ID3_Reader;
template <typename T>
class ID3_ReaderT<T>::Mp3_File {
};
int main()
{
ID3_Reader reader;
}
Of course, it still means that every user of ID3_Reader needs to see the definition of the nested type. If you want to avoid that, your option is on level indirection, i.e., using a pointer as was already stated by multiple answers.
Am I missing something here?
class Foo;
class Bar {
public:
Foo foo;
};
class Foo { };
Error:
error C2079: 'Bar::foo' uses undefined class 'Foo'
When you forward-declare a class, you can make pointers and references to it, but you cannot make members of the type of forward-declared class: the full definition of Foo is needed to decide the layout of the outer class (i.e. Bar), otherwise the compiler cannot make a decision on the size and the structure of Bar.
This is allowed, though:
class Foo;
class Bar {
public:
Foo* fooPtr;
Foo& fooRef;
};
The reason the pointers and references to forward-declared classes are allowed is that the sizes of pointers and references do not depend on the structure of the class to which they point (or which they reference).
Yes you are missing something important: A question.
I assume you want to know what's wrong in the code, and why the compiler issues an error.
The compiler has to know the size of Foo in order to calculate the layout of the class Bar. The size of Foo objects is determined by their layout, to know that layout, the compiler has to know the class definition. At the point where you declare the Member variable foo, it merely knows that Foo exists, but not its size, because you have given it only a declaration, not a definition before.
I have a basic question that has bothered me for sometime.
When using a Class within a Class I can define the header of the Class I want to use in the header file. I have seen two ways of doing this and would like to know the difference between the two methods?
ex1
#include "ClassA.h"
class ClassB {
public:
ClassB();
~ClassB();
ClassA* a;
};
#endif
ex2 Here is the other way of doing it. The ClassA Header would be defined in ClassB source file.
class ClassA;
class ClassB {
public:
ClassB();
~ClassB();
ClassA* a;
};
#endif
What are the differences with these two methods?
The comlpete layout of the classA is known to the compiler when you include the class definition.
The second syntax is called Forward declaration and now classA is an Incomplete type for the compiler.
For an Incomplete type,
You can:
Declare a member to be a pointer or a reference to the incomplete type.
Declare functions or methods which accepts/return incomplete types.
Define functions or methods which accepts/return pointers/references to the incomplete type (but without using its members)
But You cannot:
Use it as a base class.
Use it to declare a member.
Define functions or methods using this type.
Use its methods or fields, in fact trying to dereference a variable with incomplete type.
So Forward Declaring the class might work faster, because the complier does not have to include the entire code in that header file but it restricts how you can use the type, since it becomes an Incomplete type.
The second method only allows you to create pointers to ClassA, as it's size is unknown. It may however compile faster as the header for the full definition for ClassA is not included.
The latter is a forward declaration. This way you can declare a pointer or reference to a class, even though you have not yet fully declared it. This can be used to resolve cyclic dependencies. What if, in your first example, A also wants to use a pointer to B. This wouldn't work, because when A is declared, B is not known yet. To solve this, you can use a forward declaration to tell the compiler that there is a class B, and you will tell it later what it looks like.
Using static class members in a class is a common practice. consider the following definition:
foo.h
class foo
{
public:
virtual ~foo();
protected:
foo();
static foo ms_oFooStaticObject;
}
foo.cpp
foo foo::ms_oFooStaticObject;
foo::foo(){}
foo::~foo(){}
void main()
{
int i;
}
while compiling the above code there is no compiler error, and you can simply run in step mode and observe the static c-tor being executed.
how can this be? is this a compiler bug?
I am using visual studio 2005 (Professional Edition) with SP1 (SP.050727-7600)
It's not a compiler bug - constructing static instances of the class being defined does not trigger recursive construction (as a non-static member of type foo would do), so it is perfectly fine.
At the point of ms_oFooStaticObject's definition (in foo.cpp), foo is a complete type and its constructor, though protected, is accessible to ms_oFooStaticObject.
#user797308: I assume you would have no problem if someone declared and defined a global variable named ms_oFooStaticObject. In other words, rather than defining foo foo::ms_oFooStaticObject; define foo ms_oFooStaticObject; (This would require the constructor was public, of course).
Plain old vanilla global variables are declared via extern <type> <global_name>; and defined using <type> <global_name>; (possibly with some initial value).
Those static members in a class are really just global variables with the class name prepended in front of their names. The class definition is declaring them. Think of the declaration of ms_oFooStaticObject inside of class foo as being analogous to extern foo ms_oFooStaticObject;. How about the definition of the variable? That's what that foo foo::ms_oFooStaticObject; statement is doing.
The comparison with globals is quite apt. There's a lot of baggage associated with globals. It is a good idea to think of the static members of a class as having the same kinds of problems as do globals in general.
Edit
Nawaz's response triggered a thought. user797308's problem might be that foo::ms_oFooStaticObject itself is protected, so how can it be defined at file scope? The answer is that because the language requires those static data members to be defined at file scope, the language of course has to allow such definitions, even for static members that have non-public visibility.
Constructor foo::foo() is executed because of static variable definition you did in foo.cpp file:
foo foo::ms_oFooStaticObject;
You are invoking the object of class foo.
Let me guess. I think you're wondering because the foo is made protected, and therefore, you think the following line must give error, as it tries to invoke the non-public constructor from outside.
foo foo::ms_oFooStaticObject; //definition lies outside the class
Well, that is not true. ms_oFooStaticObject is NOT a global object, though at first it seems it is, seeing its definition which is outside the class.
The fact is that ms_oFooStaticObject is still a member of the class, even though its definition is outside the class. And like any member, it can access not only protected members, it can access even private ones:
class A
{
A() { cout << "constructed" << endl; } //private constructor
static A a;
};
A A::a; //okay - member has access to private constructor!
A b; //error - non-member doesn't has access to private constructtor
Compile and see the error message along with line number: http://www.ideone.com/qocH0
By the way, your main() is non-standard, it should be one of these:
int main();
int main(int argc, char *argv[]);
I know the questions seems ambiguous, but I couldn't think of any other way to put it, but, Is it possible to do something like this:
#include<iostream>
class wsx;
class wsx
{
public:
wsx();
}
wsx::wsx()
{
std::cout<<"WSX";
}
?
Yes, that is possible. The following just declares wsx
class wsx;
That kind of declaration is called a forward declaration, because it's needed when two classes refer to each other:
class A;
class B { A * a; };
class A { B * b; };
One of them needs to be forward declared then.
In your example,
class wsx; // this is a class declaration
class wsx // this is a class definition
{
public:
wsx();
}
So yes, by using class wsx; it is possible to declare a class without defining it. A class declaration lets you declare pointers and references to that class, but not instances of the class. The compiler needs the class definition so it knows how much memory to allocate for an instance of the class.
This is the definition of the class
class wsx
{
public:
wsx();
}
This is the definition of the constructor
wsx::wsx()
{
std::cout<<"WSX";
}
THis is a forward declaration that says the class WILL be defined somewhere
class wsx;
Yes. But it is not possible to define a class without declaring it.
Because: Every definition is also a declaration.
You did define the class. It has no data members, but that's not necessary.
I'm not sure what you mean. The code you pasted looks correct.