I am developing a library and a would like to provide my users a public interface separate from the real implementation that is hidden in a namespace. This way, I could change only the class HiddenQueue without changing myQueue that will be exposed to users only.
If I put the C++ code of HiddenQueue in the myQueue.cpp file the compiler complains saying _innerQueue has incomplete type. I thought that the linker was able to resolve this. What I am doing wrong here?
// myQueue.h
namespace inner{
class HiddenQueue;
};
class myQueue{
public:
myQueue();
);
private:
inner::HiddenQueue _innerQueue;
};
///////////////////////////
// myQueue.cpp
namespace inner{
class HiddenQueue{};
};
The compiler needs to know the exact memory layout of an object by looking at the header file it's defined in.
Your code says that class MyQueue has a member of type InnerQueue, which will be part of the memory layout of MyQueue objects. Therefore, to deduce the memory layout of MyQueue it needs to know the memory layout of InnerQueue. Which it does not, because you say "oh well, it's defined elsewhere".
What you are trying to do is closely related to "the PIMPL idiom"/"compiler firewall" technique.
To solve the problem, you must either include HiddenQueue.h in your header or declare _innerqueue as a pointer:
class myQueue {
public:
myQueue();
private:
inner::HiddenQueue* _pinnerQueue;
};
Using a pointer is possible because a pointer has a known memory size (dependent on your target architecture), therefore the compiler doesn't need to see the full declaration of HiddenQueue.
To be able to make a member of a class, you need to have a definition for it and not only a declaration. (A declaration is enough for a pointer or a reference to the class).
You need to provide pointer to _innetQueue rather then the object itself:
std::auto_ptr<inner::HiddenQueue> _innerQueue;
Search form pimpl ideom or d-pointer
Related
I got this syntax I don't really understand:
class USphereComponent* ProxSphere;
I think this means create a class, but is this class a pointer?
But the result is just creating an object called ProxSphere from an existing class USphereComponent.
What does this syntax actually mean, and what is its usage?
class Someotherclass; // That has not been defined yet
class HelloWorld
{
Someotherclass* my_pointer;
};
Or an alternative:
class HelloWorld
{
class Someotherclass* my_pointer;
};
The first one is obviously the correct one if you have multiple pointers (or references) to such class that has not been defined yet.
Is the second better? (I don't know) if you only need to do it once, otherwise doing
class HelloWorld
{
class Someotherclass* my_pointer;
class Someotherclass* my_pointer2;
class Someotherclass* my_pointer3;
void func(class Someotherclass* my_pointer, class Someotherclass& my_ref);
};
may not be the best.
Jts's answer is correct. I'd like to add a use case for it:
This is mostly used when you have a circular class dependency.
Like:
class A { B* binst; };
class B { A* ainst; };
That wouldn't compile since B isn't previously known.
Therefore you would first declare class B.
class B;
class A { B* binst; };
class B { A* ainst; };
Or as mentioned, you can use syntactic sugar:
class A { class B* binst; };
class B { A* ainst; };
Such a dependency might be a code smell. It also might be ok or even necessary. If you have it, you should carefully think if you can't do it in some other yet convenient way.
That particular syntax is called a "forward declaration". It is used to declare a type that has not been defined yet.
This is basically telling the compiler "There exists a class type named USphereComponent that you haven't seen yet that will come up later in the code. Please don't yell at me if you see pointers of that type". This allows you to declare pointer and reference for that forward-declared type.
Writing:
class USphereComponent* ProxSphere;
Is really just the equivalent of writing this:
class USphereComponent;
USphereComponent* ProxSphere;
The only difference with the second syntax, is that you only need to forward-declare the type once when you do it like this class USphereComponent;, otherwise you need to use the first syntax and add the class keyword before each usage of USphereComponent.
There are two main reasons why you may want to use a forward declaration:
This is probably the most common usage of forward-declaration in Unreal Engine. In header (.h) files, forward-declaration allows you to use pointer of classes for which you did not #include the corresponding header file. In our particular example that means that forward-declaring USphereComponent means that we don't need a #include "SphereComponent.h" statement (if we're just trying to pass a USphereComponent around that is).
Typically when that happens, the #include statement is simply done in the .cpp file. There are mainly two advantages of reducing the number of includes in your header files:
Compilation times are faster. Mind you, this mostly has significant impact on a codebase as big as Unreal's.
This reduces the number of public dependencies of you module (by making them "private" since your includes are now in your .cpp). This makes your module easier to be depended upon and also makes its interface cleaner.
Like other answers have said, forward-declaration can be used to break circular dependencies when you have two types that depends on each other in the same file:
class B;
class A
{
B* foo;
};
class B
{
A* bar;
};
From what i've read, i should use forward declarations whenever I can. I have classes like this ( where every fields are pointers because of forward declarations ) :
class A
{
// ...
A* a;
B* b;
C* c;
D* d;
E* e;
};
But there is problems with that.
1- This implies to call new and delete ( or at least new with smart pointers ) for every fields in constructor, while stack allocated fields don't need this.
2- I've read that stack allocation was faster than heap allocation.
3- Also that means that almost every fields on every classes should be pointers.
Am I doing the right way doing like my example class? Or am I missing something with forward declarations?
The example you've shown is an overkill. The suggestion to use forward declarations doesn't mean your code design is driven by forward declaration practices. Forward declarations are just implementation detail, the design prevails.
First decide whether you need aggregation or composition, then whether the forward declaration is appropriate.
Do prefer forward declaration over #include when the forward-declared type is part of your method signature, i.e. a parameter's type.
#include "OtherClass.h" // 'bad' practice
class OtherClass; // this is better than #include
....
class MyClass
{
void method(OtherClass *ptr);
}
It's not an absolute rule anyway as it's not always possible/convenient to use forward decls instead of includes.
The implication is inverse - you're not supposed to use pointers just in order to use forward declarations, but you're suppose to use forward declarations after you've taken a design decision (such as using pointers instead of objects as members) when you can.
So if it makes more sense to use objects, do so, and include the files you need. Don't use pointers just so you can forward-declare the classes.
If you are using pointers as members, prefer forward declaration than exposing complete class definition. Don't use pointers just to meet some rule blindly.
Technically spoken, you can (and should!) use a forward declaration, if the interface of your class doesn't depend on a fully qualified type. The compiler has to reserve enough space for members and add management functions at compile time - just using pointers or references in your class does not introduce dependencies on types.
BTW: Forward declaration isn't that new: In some C standard libraries, FILE is a typedef for a forward declared struct, which makes sense since FILE is always used for pointers in the whole public file API.
Use pointers or references for objects that the class doesn't own. But for objects that are owned by this class don't use forward declarations as a reason for choosing pointers.
If you really want to minimize compile time dependencies consider the PIMPL idom rather than turning all your members into pointers:
MyClass.h:
#include <memory>
class MyClassImpl;
class MyClass {
public:
MyClass();
~MyClass();
void doThing();
private:
std::unique_ptr<MyClassImpl> pimpl_;
};
MyClass.cpp
#include "MyClass.h"
#include "MyClassImpl.h"
MyClass::MyClass() { } // in .cpp so unique_ptr constructor has complete type
MyClass::~MyClass() { } // in .cpp so unique_ptr destructor has complete type
void MyClass::doThing(){
pimpl_->doThing();
}
MyClassImpl.h:
#include "A.h"
#include "B.h"
class MyClassImpl {
private:
A a_;
B b_;
public:
void doThing();
};
MyClassImpl.cpp:
#include "MyClassImpl.h"
void MyClassImpl::doThing() {
// Do stuff with a_, b_, etc...
}
This might not address performance concerns as you still have dynamic memory allocation but you would have to measure it to see.
In addition to the good answers already given: In cases where your class doesn't create an object but uses it privately (for instance some utility class), references can be used instead of pointers.
class UtilityClass; // forward declaration (even interfaces make sense here)
class MyClass {
public:
/// takes an UtilityClass for implementing some of its functions
MyClass(UtilityClass& u): util(u) {}
private:
UtilityClass& util;
// ...more details
};
These are cases, where forward declaration doesn't mean that objects have to be created on heap (as for your problems #1 and #2).
I'm writing a small C++ program and need to keep all the code in a single file. In it, I have a class definition. I would like to put the class definition AFTER the main() function. When attempting to do this, the compiler in visual studio complains as it seems class definitions must come before the main() function.
This there a way that I can place the class definition AFTER the main() function? Perhaps with some sort of macro or precompiler trick? It's fine if the code gets compiled with the class def before main, but in the raw source, I need the class def after main.
int main(){
someClass object;
//remainder of code
}
class someClass{
//class code
}
This will work but it is truly horrible. If I could downvote my own answer, I would. Please don't do this in production.
Assume the file is test.cc
#if defined(guard)
int main(){
someClass object;
}
#endif
#if !defined(guard)
class someClass
{
};
#define guard
#include "test.cc"
#endif
You need to first provide full declaration before you can use your class.
You could forward declare the class, but until you provide full declaration, you can only use name of class as pointer (can't allocated objects on stack) and can't call methods.
class someClass;
int main() {
someClass* sc;
// can't allocated sc on heap (new someClass) or call any mehtods (sc->someMethod())
}
class someClass {
// ...
};
I have a class definition. I would like to put the class definition
AFTER the main() function.
Don`t try to do it.
Generally any sane compiler would not allow it, but even if it allows though some insane non standard compiler option, or weird hacks, it would be a horrible code that will stink though out its life time.
C++ is flexible enough but you need to understand and honor its grammar. You cannot instantiate an incomplete or absent class/structure, because the compiler needs to know the size of the object its instantiating and without a Class Declaration it would not be possible,
Put your someClass declaration in a header file, and then #include that header file at the top of your program.
You can't do this.
Further, to arrive at this constraint, something has gone wrong in your requirements.
I would try to guess the reason: it's an autogenerated text and its parts are generated by different mechanisms, which call sequence can't be reordered. If so, I could suggest to use a base class, which definition could be placed before main and derive your someClass from that baseClass. This way you can call any required method from baseClass.
I have been going through the code of a project and have encountered the statement
class foo;
.
.
.
.
foo* f1;
in various places. The class has not been declared in any of the headers included either. Can anybody tell me what that means.
It is a forward declaration. It can be used for classes, structs and functions, and it tells compiler that this is defined elsewhere or later.
For classes, there are (at least) two use cases.
1. Full definition not needed
After forward declaration, compiler does not know size or members of class, only name. That is enough for pointers to the class (and references which are basically syntactic sugar around pointers). But often pointer is enough, and then you can avoid including entire header file in another. This helps compilation speed, by avoiding need to recompile everything when one header changes.
myfuncs.h
class MyClass; // forward declaration
void helpMyClass(MyClass &needy);
// here this would give compiler error about incomplete type:
//void badHelp(MyClass needy); // value needs definition
myfuncs.cpp:
#include "myclass.h" // entire MyClass definition
void helpMyClass(MyClass &needy) {
needy.helpMe(false); // needs full definition
}
Important use case for this is the so called PIMPL idiom, also well covered here at SO under pimpl-idiom tag.
2. Two classes need to refer to each others
class node; // forward declarion
class collection {
node *frist; // pointer enabled by forward declaration
}
class node {
collection *owner; // already defined above so works too
}
In this case forward declaration is required to make this work nicely. Just saying in case you see it in the wild, there's the ugly way of using void pointer and casts, sometimes used when novice programmer does not know how this should be done.
I think you're referring to a forward declaration. It tells the compiler that a class named foo will be defined later. Until then it is an "incomplete type", meaning that pointers and references to the class can be defined. Instances of the class cannot be created until it is fully defined.
Your declaration is incorrect? I'm not sure.. I do know that you can't have "any" space "name".. Perhaps you missed an underscore?
I believe you meant:
class foo any_name();
In that case, it's forward declaring a function called any_name that returns a class instance of foo.
Example:
#include <iostream>
class foo any_name(); //The forward declaration..
class foo //the foo class implementation.
{
public:
foo(){std::cout<<"hey";}
};
class foo any_name() //The implementation of the function..
{
std::cout<<"any_name";
//return {}; //Can be used to return a constructed instance of foo.
};
int main()
{
any_name();
}
It is possible to declare a class without defining it (forward declaration) as long as it is defined later on within the translation unit. In the case of functions, one can declare a function without defining it within the translation unit, and the linker will link it to its definition in a different translation unit. Is it possible to do the same with class declarations?
(if this is not possible, is there any use to a forwardly declared class without a definition in the current TL, or is that always an error?)
something like this, except this doesn't compile:
mymain.cpp:
class myclass; // declare without defining
myclass::myclass();
void myclass::barf();
int main() {
myclass *m = new myclass();
m->barf();
return 0;
}
myclass.cpp:
#include <iostream>
class myclass { // define the implementation
public:
myclass();
void barf();
};
myclass::myclass() { } //empty constructor
void myclass::barf() {
std::cout << "barfing\n";
}
It is possible to forward-declare a class, but only pointers and references to forward-declared classes can be used. You can't use an actual object of a forward-declared class because the compiler doesn't know enough about it; in particular it doesn't know how large the object is or what its members are. Trying to forward-declare member functions (as you have done) won't work because the syntax of the forward declaration doesn't allow you to specify whether the functions are virtual or non-virtual (or perhaps inherited from some base class).
It is not often useful to forward-declare a class in a source file, but it can be useful in a header file. In particular it's common to forward-declare a class in a library's public header file and use pointers to that type as opaque handles. The class definition remains private to the library but user code can pass around pointers to objects of that class without ever knowing what the class's implementation looks like. This works particularly well when the pointers are smart pointers.
You can, but only if you use exclusively pointers or references to that class. But you can't use code referring to that class' members (variables or methods). You can only use it to declare pointer variables to that class.
I would suggest you create a myclass.h header file with myclass' full declaration, and include that header in mymain.cpp.
You can only do that through hacks.
The declare before use rule doesn't hold within a class (see here).
Otherwise you can do that by declaring your function as a template function, whose template parameter is of myclass (in your example).
The only non-hack way is to define the class (ie. by including the header file its defined in).