I am working with a c++ library that is not written by me.
Some header files include other classes, but still have sort of "duplicate" empty definition of the class. What is the purpose of this behaviour?
#include "OtherClass.h"
class OtherClass;
class ThisClass {
// definitions here
};
This is a forward declaration of the class which is a declaration without a complete definition of the identifier. This helps reducing the compile time and also the circular dependencies.
In your scenario you only should include or forward declare the class, but not both.
Related
For every pointer p1 of class class1, are there any risks we should consider by using a forward declaration of class1 instead of including class1 header file?
I can see only the advantage: The header file will have less size.
Forward declarations outside the control of the provider of the class are problematic! I’m working on a code base where a lot of forward declarations are used. While things are initially great the existence of forward declarations become a legacy:
Classes can’t be moved from one namespace to a different one. Without the forward declarations the name in the original namespace could be made an alias (typedef or using alias).
Classes can’t be turned into specialisations of class templates as is, e.g., useful when generalising a successful class.
Class templates cannot be forward declared by users as only the first declaration of a class template can provide default arguments.
Assuming the forward declarations are provided via a header under the control of the class provider/implementer (e.g., the implemented providing something akin to <iosfwd>) these problems are not relevant as there is a central place where the declarations can be changed. However, having users decide to declare entities becomes a legacy causing significant cost.
The approach to provision of declarations outlined above seems to have caused some confusion. I'll try to clarify. In my mind the unit of implementation is a component (which is based on John Lakos's notation of a component). A component defines one or more closely related classes and/or functions. The implementation of a component consists of multiple files:
A header file declaring all relevant entities which also defines entities which must be defined when using the component, i.e., user-accessible classes, enumerations, etc. are defined.
A header file only declaring relevant entities provided by the component (multiple related components may share one such header file; <iosfwd> is an example of such a header shared across multiple components).
An implementation file defining all entities [which are meant to be ODR-used] which are only declared in by the headers above.
At least one file with a test driver testing all entities defined by the component.
Users of a component which in some contexts only need to know about names in the component would include the declaration-only header. In no case would a user provide a declaration of a name in a component: all declaration of a name in a component are the responsibility of the provider/implementer of the component.
I can see only the advantage: The header file will have less size.
That's not exactly the point.
Let's assume you have a class declaration in a header file like
namespace MyNamespace {
class Baz;
}
class Foo {
public:
void bar(const MyNamespace::Baz & x);
};
and the definition in a separate translation unit as
#include "Baz.hpp"
void Foo::bar(const MyNamespace::Baz & x) {
// actually do something with Baz
}
and in contrast having everything included in the header file (and necessarily all dependent sources will be recompiled when Baz.hpp will be changed)
#include "Baz.hpp"
class Foo {
public:
void bar(const MyNamespace::Baz & x);
};
with the declaration, the 1st version might help to compile the code a little bit faster.
Especially if you have your own headers and class declarations, and if any of these are likely to be changed, you only want to recompile your translation units in the codebase, and not every source file that includes your type dependent header.
Note that forward declarations can be only used with references and pointers. Also header inlined code which dereferences to the forwarded type members cannot be used.
I've recently run into the idea of forward declarations within C++. I have read that by using forward declarations, compile times can be quickened by avoiding unnecessary declarations and recursive #includes. However, this has got me wondering, why exactly does anyone use #includes then?
Are there situations where plain forward declarations just aren't reasonable? Such as if you have a library header file, it would just make more sense to have a single #include then naming each class/function prototype?
I've read many posts on stack overflow explaining the differences between each path, but why exactly use #includes?
The main reason for including headers, rather than using forward declarations throughout your code, is enforcing consistency with minimal duplication.
Consider a header used in several cpp files. When a class or a variable changes in the header, you would need to find and change all references in all files. Otherwise, the code would continue compiling, but it would fail to link.
In addition, forward declarations have their limits: they let you declare pointer to classes or call functions, but they do not allow creating instances or accessing their members.
It is simply that forward declarations you have in mind cannot replace declarations in headers.
One obvious example is the declaration of class:
Assuming I have a Foo class and is going to contains Bar:
This will work
// FOO.H
class Bar;
class Foo {
private:
Bar* bar;
};
But this won't:
// FOO.H
class Bar;
class Foo {
private:
Bar bar;
};
There is a lot of cases that compiler needs to know the "full" declaration (which we usually put in headers) in order to do its work, instead of just a forward declaration containing the name of class etc (which allow you to mostly create pointer/reference to such class).
I am new to C++. I have some doubts regarding multiple definitions error in C++.
Let's say I have 3 files in a program. One header file and 2 .cpp files. I have included the header file in both the .cpp files.
I have declared a class in the header file and I have defined the class in each of the .cpp files in exactly the same way. So will this type of implementation cause multiple definitions error? If so, is it because it has two copies of class definitions and the compiler doesn't know which one to take during linkage of two .o files?
Can we solve this problem by using extern in header file and defining the class in only one of the files?If we can solve the issue by using this method,do we have to include the .cpp(with class definition) into other .cpp file(with no class definition)?
I have declared and defined a class in header file. Is this case the same as above (mentioned in 1)?
I have declared a class in the header file and I have defined the class in each of the .cpp files but the definitions (function bodies)differs. So will this type of implementation causes multiple definitions error? If so, how can we solve this problem where the functions bodies differs in the .cpp files?
1) You solve this by 'defining the class' in only one cpp file. Why would you want to define it in two files?
2) Don't define things in header files, only declare them. There are exceptions to this rule, for instance inline functions. Also classes themselves can defined more than once (by this I mean declaring the methods and data members of the class, (i.e. writing class XYZ { ... };) but each definition must be identical. The simplest way to achieve this is to define a class once in a header file. Then each definition resulting from including that header file in multiple places will necessarily be identical.
3) This one is even sillier, it's one thing to define somethiing twice, but define it twice and differently each time makes even less sense.
I guess the issue is why you think it might sometimes be necessary to define things more than once. Don't do that.
You should also make it clear what you mean by 'define the class'. I've taken that to mean define the methods and static members of the class. But if you have something else in mind that might be a source of confusion. As usual the best way to avoid this kind of terminology confusion is to post some code.
To answer all of these questions, you only need to look at the purpose of declarations and definitions.
Declarations of a class simply state that the class exists and in which context. For a class, a simple forward declaration (e.g. class Banana;) allows you to use pointers or references to that class, but that's it.
Definitions state exactly what the class is. That is, which members it has and from what base classes it is derived. You need this available whenever you access members of the class, or need to know the size of its instances. This means the class definition needs to be put in a header file, so that it can be included wherever in all files which use the class. This is OK, because the standard says that a class can be defined in multiple translation units, as long as all definitions are identical.
A class definition typically looks something like this:
class Banana
{
public:
Banana(){}
void eat();
private:
//....
};
However, please note that this class definition only means the definition of the class itself, not the non-inline member functions. Such as void eat() in the above example. These need to be defined in the .cpp file, because they may not be defined in multiple translation units.
So in short:
This is not right, only define it in the header file and define non-inline member functions in the matching .cpp file. You should never define the same function or type in more than one file.
This is OK, as long as you define the member functions separately in the .cpp file.
No, see 1.
1) You can't have two definitions of the same class in your project. And I have no idea how you plan to use it. If you want to make instances of one class with different behavior, use virtual function like:
class A {
public:
virtual int foo() = 0;
}
class B : public A {
public:
virtual int foo() { return 1; }
}
class C : public A {
public:
virtual int foo() { return 2; }
}
2) You may define class in header file (java-style), but it's not the best idea because compiler will consume more resources to build other files, include this header. Let compiler work fast - define classes in .cpp files.
3) See p.1
There's no problem with defining a class in several places. That's exactly what happens when you put the definition in a header and #include that header in more than one source file. However, note that defining a class means writing out what the class contains, not defining its members. This is a class definition:
class C {
void f(); // member function declaration
void g() { } // member function declaration with inline definition
int i; // member declaration
static int j; // member declaration
};
like most things, you can't define it more than once in a single source file. However, it can appear in as many source files as you like, provided only that it's the same everywhere.
This class definition declares two members that must be defined somewhere, typically like this:
void C::f() {
std::cout << "In C::f\n";
}
int C::j = 3;
These definitions can appear only once in the entire program; usually each is defined once in a source file.
I am writing a class
In the class, I use boost::graph::adjacent_list as a private member.
but I don't want my header file include boost header file, because any other file include my header file will need to include boost header file.
Is there a way can avoid include boost header file in my own header file.
I have tried forward declaration, but fails.
You can't do this directly, but you can probably solve the underlying problem of not propagating an implementation detail (boost) by pimpling your class. This essentially means that you forward declare a pointer to your implementation details, which are then fully implemented just in a source file.
If your header file is definition only, and is fully implemented in a cpp file (i.e. the header file doesn't do anything with boost::graph::adjacent_list then in your header, you can
Forward declare a bgalWrapper struct.
Have a pointer to that struct instead of boost::graph::adjacent_list
In the CPP file that implements the header file, declare the new
bgalWrapper struct (which only has a boost::graph::adjacent_list member)
Create an instance of the struct in the classes ctor (and - obviously
clean up in the dtor).
Now each class can have a reference to the boost item without the header needing to know about boost.
There's probably a name (and wikipage) for this pattern, but it's years since I programmed C++ seriously.
Hope this helps.
Update What I've described is a partial implementation of the PIMPL Idiom
Thanks Mark B
I didn't test it, but can't you define the list as a pointer variable? Then the forward declaration should succeed. You'll have to nest the namespaces though:
using namespace boost::graph;
class adjacent_list;
class MyClass {
private adjacent_list<foo, bar> m_list;
}
Or perhaps:
namespace boost {
namespace graph {
class adjacent_list;
}
}
class MyClass {
private adjacent_list<foo, bar> m_list;
}
Then in your implementation file, just use it as a pointer:
#include <boost/graph/adj_list_serialize.hpp>
MyClass::MyClass() {
m_list = new adjacency_list<foo, bar>();
}
I'm building an application that should use one class from 1.h in 2.h it is defined like:
<classname> *p;
now i can use p in 2.cpp. But I would also like to use it in 3.cpp. I could not include the 2.h in 3.cpp. Is there a way to make it visible in 3.cpp?
Thanks for the help.
A more descriptive example of your problem with some code would be valuable.
In general attempt to do the following:
Each header should contain only the its own class with the same name.
If a class is using another class, and you can forwardly declare it in that header, do.
You cannot forwardly declare if the class has an instance of another class or if it derives from it.
Compilation units (cpp) files should include all the headers they need. Ideally include its own header first.
You need to provide more info but I think I got it
Your trying to use a class in a header that was defined I. A another header, but for some reason you can't include the header it was defined into the header your working on. The solution is to create a "temporary" definition instead of an include.
Eg:
U need myClassA in 1.h but it was defined in 2.h and some error doesn't let you include 2.h into 1.h to solve it you.simply
Write:
class myClassA;
on top of 1.h so you can reference it, but no implementation (because it is implemented in 2.cpp)
A simple rule is one class, one header file.
Given:
A.h:
class A
{
};
B.h:
#include "A.h"
class B
{
A obj;
};
C.h:
#include "A.h"
class C
{
A obj;
};
I hope this answers the question. Otherwise, edit your question with more details and example of what you are trying to accomplish.