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).
Related
I am attempting to forward declare some variables used only privately in a class to limit the number of headers that I have to include when using this one.
Sadly, the class that I want to forward declare has turned out to be a typedef, and it's a 3rd party library that I can't edit (let's call it "boost::asio::strand" for the sake of argument)
This question Forward declaration of a typedef in C++ Demonstrates that the only solutions are either:
Just include the header and accept it's not possible
Forward declare what would be typedef'ed and add my own typedef
Looking at the second solution, is there any way that I can protect myself from the typedef changing in the library so that the compiler complains about the typedef rather than the usage of an undefined type when the class is removed/renamed and make it less of a maintenance headache?
I would try not to rely on the forward declaration of the original class at all if possible. I may have missed a case but I think a forward declaration is only useful for a purely private use if the type appears in a method signature somehow, or if your class contains a member that somehow points to or references the type, possibly indirectly.
I propose to to forward declare a wrapper for the class and only define that in the implementation file, when the actual class or typedef is known.
Say your class header currently looks like this:
// need header because it contains UglyTypeDef:
#include <UglyHeader.h>
class MyClass {
public:
int theMethod(int a);
private:
void uglyMethod(UglyTypeDef &utd);
int someMember;
UglyTypeDef *utdp;
std::vector<UglyTypeDef *> utds;
};
In this example we could do with a forward declaration, but we do not want to rely on the internals of UglyHeader.
I would change MyClass like this:
class MyClass {
public:
int theMethod(int a);
private:
// move the private method into the implementation file
// hide the ugly typedef
// we safely forward declare our own private wrapper
struct UglyTypeDefWrapper;
int someMember;
UglyTypeDefWrapper *utdp;
std::vector<UglyTypeDefWrapper *> utds;
};
Now in order to make this work, the implementation in the cpp file must change as well:
#include "MyClass.hpp"
#include <UglyHeader.h>
struct MyClass::UglyTypeDefWrapper {
// if possible save another level of indirection
// and store by value, otherwise use a second indirection
// by cleverly wrapping at the right level of abstraction
// this abstraction can be free in many cases
UglyTypeDef td;
};
namespace {
// we completely hide the private method in this file as
// an implementation detail and pass it whatever it needs
// this also helps the compiler to inline it,
// because it knows it cannot be referenced in
// a different compilation unit
// we need to pass all members as needed
void uglyFormerMethod(int &someMember, UglyTypeDef &utd) {
someMember += utd.whatever();
}
}
int MyClass::theMethod(int a) {
utd->td.doWhatever();
uglyFormerMethod(someMember, *utd);
for(auto utdwp: utds) {
utdwp->td.doIt();
}
}
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;
};
I'm finishing up a C++ assignment and I'm running into an issue with connecting all the classes together. The classes have basic constructors, getters, setters, etc. so I'm confident the abundance of compiler errors I'm getting are due to me mix and matching all of my Classes incorrectly...
My classes are split up into cpp and h files and I've basically used the include statements every time that class needs something from another class. A basic diagram of which class needs what is shown below:
Basically what I'm trying to figure out is if having #include "Product.h" in both CustomerOrder and Retailer is messing things up or if I'm doing this all the wrong way.
Any help would be lovely!
Thanks!
EDIT:
Here's one instance of what each class is basically doing. The Customer class holds an array of CustomerOrders and CustomerOrders holds an array of Products etc. etc..
...
class Customer
{
private:
string customerName;
string customerID;
float balance;
static const int ORDERSIZE = 2;
CustomerOrder* orderList[ORDERSIZE];
Retailer retailer;
...
and Customer Order:
...
class CustomerOrder
{
private:
static const int SHOPSIZE = 20;
Product* shoppingList[SHOPSIZE];
...
First of all, your diagram is confusing. In OOP, arrows like the one you use indicate public inheritance, but that doesn't seem to be the case here (nor that it should).
Your question cannot be answered generally. You #include another class if you need the complete type. Otherwise, a forward declaration will do. That only has an impact on compilation speed. Nevertheless, the rule is to use forward declarations if you can and #includes if you must.
Here are some cases where you can get away with a forward declaration:
1.) Pointers:
class AnotherClass; // <-- forward declaration
class Example
{
// ...
AnotherClass *another_class;
};
2.) References:
class AnotherClass; // <-- forward declaration
class Example
{
// ...
void f(AnotherClass &another_class);
};
3.) Return values:
class AnotherClass; // <-- forward declaration
class Example
{
// ...
AnotherClass Get();
};
As soon as you are actually using the object of the forward-declared class, you need to have the #include. If you forget, the compiler will remind you.
Caveat 1: Pay attention when you use forward-declared (i.e. so-called "incomplete") types in standard containers. Your compiler may allow this, but it's undefined behaviour to do so!
class Example; // forward declaration
std::vector<Example> v; // undefined behaviour!
Caveat 2: Don't attempt to forward-declare standard classes. Just do #include <vector>, #include <string> and so on and let the compiler figure out how to optimize compile time.
Edit: Actually, the linker, rather than the compiler, will remind you if you forget to include a forward-declared class you cannot forward-declare, but that's just a nitpick :)
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();
}
I'm using boost::intrusive_ptr as my reference counted smart pointer. I'm using something like this:
http://www.codeproject.com/KB/stl/boostsmartptr.aspx#intrusive_ptr%20-%20lightweight%20shared%20pointer
This seems a good idea, because it simplifies the declaration of a new Reference counted class, just inheriting from it. The problem comes with forward declarations. There are a lot of places where I want to use a pointer to a type not yet decladed in a class definiton and it is not possible, because the 2 methods that handle ref count need to know if the type inherits from CRefCounted or not.
If I try to include the dependencies before the declaration of the intrusive_ptr it is ok, but then, I get a lot of cyclic includes.
How would you handle this scenario?
I think you can solve this using templates functions for intrusive_ptr_add_ref and intrusive_ptr_release as follows:
namespace boost {
template<class T> void intrusive_ptr_add_ref(T* p) { ++(p->references) }
template<class T>void intrusive_ptr_release(T* p) {
if (--(p->references) == 0)
delete p
}
};
You'll also need to adapt the friend declarations in CRefCounted like
template class<T> friend void ::boost::intrusive_ptr_add_ref(T*);
template class<T> friend void ::boost::intrusive_ptr_release(T*);
Using these declarations, you can use intrusive_ptr on forward-declared classes like
class A;
class B {
::boost::intrusive_ptr<A> _myPtr;
};
class A : public CRefCounted {
};
This solution has the drawback (theoretically...), that you define a pair of add_ref/release functions for every subclass of CRefCounted, but I think that the compiler will choose to use inlining anyway, so this can be neglected.
I've been using a similar RefCounted base class a lot and I started wondering why do I never have this problem. And it's because I tend to hide implementation details in source files. Consider the following header file of class B:
//File: B.h
#include <boost/intrusive_ptr.hpp>
class A;
class B
{
public:
B();
~B();
boost::intrusive_ptr<A> foo();
void foo2(const boost::intrusive_ptr<A> p);
boost::intrusive_ptr<A> p;
};
It works, because even though it is using intrusive_ptr, it doesn't need to instantiate its constructor or destructor. Therefore it doesn't need to know anything about the class A.
The place where it needs to know about A is in the source file. (And also in places where foo/foo2 are called). B's constructor and destructor implicitly call intrusive_ptr< A>'s constructor/destructor, so A's definition must be available.
//File: B.cpp
#include "B.h"
#include "A.h" //Include header where A is defined.
B::B() { }
B::~B() { }
//Other member functions...
I don't know if this helps in your case, but it's something to think about. :)