use file or class for documenting classes in doxygen? - c++

This surely is a noob question, but I can't find an answer in Doxygen documentation. I'm not sure whether using:
#file
or
#class
when documenting my header files.
The reason is that if I put file, then all the comments appear in the Files tab only, but not in the Classes tab (per each).
For cpp it's ok, I just use file and it's good, but if I use both file and class in the header (file at the beginning and class right before the start of the class declaration) then I get duplicated entries for the class in the generated documentation...
What I'm doing wrong? Any suggestions? Ideas?
Regards,
Alex
Edit: I run into a new problem now. In order to avoid circular dependecies I declare my class twice in a header file (probably this is not the best way to avoid circular dependencies but it normally works for me), for instance:
#ifndef EU_SOFIA_KPI_COMMON_ABSTRACTTHREAD_DECL
#define EU_SOFIA_KPI_COMMON_ABSTRACTTHREAD_DECL
namespace eu_sofia_kpi_common
{
class KPI_CPP_API AbstractThread;
}
#define EU_SOFIA_KPI_COMMON_ABSTRACTTHREAD_DECL_END
#endif EU_SOFIA_KPI_COMMON_ABSTRACTTHREAD_DECL
#ifdef EU_SOFIA_KPI_COMMON_ABSTRACTTHREAD_DECL_END
#ifndef EU_SOFIA_KPI_COMMON_ABSTRACTTHREAD_DEF
#define EU_SOFIA_KPI_COMMON_ABSTRACTTHREAD_DEF
namespace eu_sofia_kpi_common
{
class KPI_CPP_API AbstractThread
{
public:
AbstractThread();
virtual ~AbstractThread();
///start method, derived classes must implement this method to initialize their boost::shared_ptr<boost::thread> pointer member object
virtual int start() = 0;
//stop method
virtual void stop() = 0;
protected:
///Pointer to a boost thread to be inherited and that children classes must use in the implementation of the start and stop methods
boost::shared_ptr<boost::thread> m_thread;
};
}
#endif EU_SOFIA_KPI_COMMON_ABSTRACTTHREAD_DEF
#endif EU_SOFIA_KPI_COMMON_ABSTRACTTHREAD_DECL_END
As you can see, I have a forward declaration prior my "real" declaration. Now if I use #class, Doxygen complains about inconsystency issues related with this class, although it generates the documentation for the class. My guess is that anything that is surrounded by #ifdef or #ifndef Doxygen does not seem to like it very much...

I usually use neither, unless I want to specify an alternate include path or something like that. Normally it looks like this:
/// Tunables loader.
/** This class contains a set of functions for loading tunables from
* file. Usually you only need one QuaTunablesLoader object in your
* program. Once its work is done, you can safely destroy it.
*
* ... blah, blah, blah ...
* */
class QuaTunablesLoader {
This is actually equivalent to using #class, so the answer to your question is yes, you should use #class when documenting classes. If your header file doesn't contain anything else, you probably shouldn't document it at all, as the documentation would only say something like "this file contains the declaration of the class SomeClass" anyway. If the file contains something more, like friend functions, you should document the file too (obviously, using #file), possibly providing a reference to the class.

Related

How to include twice a header that has static variable definitions?

OpenVPN is a giant header only 'library'. I created a library based on it, which consists of a MyClass.h file that has a class MyClass that uses the headers from OpenVPN. I compile this library as libmy.
The problem is that when I try to use libmy in another project, I'm forced to include MyClass.h, which in turn includes all of the OpenVPN headers. I don't need them, since MyClass hides all OpenVPN-related things. However, since OpenVPN headers have some static variables like static int context_data_index (defined AND declared in header, here), these variables get duplicate definitions when I try to compile my new project.
Let me explain the problem better. This is MyClass.h:
class MyClass {
public:
//lots of 'methods' that hide OpenVPN-related things. Users of these methods dont even know about OpenVPN
private:
//Users of MyClass do not need to know about this unique_ptr, but I'm forced to show it in `MyClass.h`, which is why I get duplicated definitions
#ifndef DO_NOT_INCLUDE_OPENVPN_HEADERS
std::unique_ptr<OpenVPNClient> openVpnClient;
#endif
}
as you can see, the users of MyClass don't have to know anything about OpenVPN objects. I even tried to put an #ifndef clause that conditionally includes std::unique_ptr<OpenVPNClient> openVpnClient; when compiling libmy but does not include when compiling the library that uses libmy, but I got terrible undefined behaviour by doing that. I guess it's because a class must have the same number of objects with the same objects in both the libmy implementation and in my new library.
What can I do about this problem?
Try
namespace my_namespace
{
#include "something.h"
}
One solution to not requiring the users of your class to directly include the OpenVPN headers is to forward declare OpenVPNClient in your header for MyClass like this:
class OpenVPNClient;
For this to work your destructor for MyClass needs to be defined in your translation unit. This could be as simple as adding the following line to your source file for MyClass:
MyClass::~MyClass() = default;
There is more info on how to do this and why it is needed here:
Is std::unique_ptr<T> required to know the full definition of T?
An alternate solution is to use PIMPL with your class and completely hide the OpenVPNClient from the header. There is information on how to use PIMPL here:
https://en.cppreference.com/w/cpp/language/pimpl
In your question you asked about a solution where you used an #ifdef to hide the usage of the OpenVPNClient to users of your class but define it when building your class: I guess it's because a class must have the same number of objects with the same objects in both the libmy implementation and in my new library. You can't have 2 different definitions of the class. This will cause undefined behavior.

avoiding circular inclusion when having to pass back values

what is the best way to handle circular inclusions in the situation where I have a class that communicates with another class, like an API and gets callbacks from that class.
Assume I have a class
.h
class Requestor;
class Api
{
public:
Api();
void Request();
int DoStuff();
private:
Requestor *p_rq_;
};
.cpp
#include "api.h"
#include "requestor.h"
Api::Api()
{
}
void Api::Request() {
this->DoStuff();
}
void Api::ReturnRequestId( int id ) {
this->p_rq->SetLastRequestId( id );
}
and
.h
class Api;
class Requestor
{
public:
Requestor();
void MakeRequest();
void SetLastRequestId( int );
private:
Api api_;
int last_request_id_;
};
.cpp
#include "requestor.h"
#include "api.h"
Requestor::Requestor()
{
}
void Requestor::MakeRequest() {
this->api_.Request();
}
void Requestor::SetLastRequestId( int id ) {
this->last_request_id_ = id;
}
In case requestor sends a request and at some point the api gets an id and wants to pass that back to the requestor, how can I do that without including each others .h file which would lead to circular inclusion?
Assume that I cant simply have the function MakeRequest return the id as I dont want to hold that thread until api gets the id?
I am fairly new to c++ and programming, so I may miss the obvious solution. Since I need to call member functions of each other, it is my understanding that forward declaration does not work here.
Also, Api and Requestor should be separate libraries, so I can't make them one class.
You have two different issues, circular dependency between your classes and multiple inclusion of the same header file.
Multiple inclusion is not caused only by simple circular dependencies, like in your case. The usual way to make sure a header is included once and only once in a source file is to use include guards. Normally a header file looks like this:
#ifndef SOME_UNIQUE_NAME_
#define SOME_UNIQUE_NAME_
... header contents ...
#endif
This ensures that no matter how many times a header gets included in a source file (either directly or indirectly), only the first time its contents are actually included, subsequent inclusions are skipped by the preprocessor due to that macro. The macro name must be unique (for obvious reasons), and it is usually some kind of prefix followed by the header name, e.g. LIBNAME_MODULENAME_REQUESTOR_H_.
A widely used alternative, supported by most modern compilers even if not standard as far as I know, is to use a pragma directive at the beginning of the header:
#pragma once
... header contents
Your other issue is circular dependency between your classes. Here you've already found one way to go around it: your Api class holds a pointer to a Requestor object and not the object itself. This allows you to use a forward declaration in Api.h and not include the full class definition.
The Requestor class however holds an Api object, not just a pointer, so the full Api class definition must be available at the point where the api_ member is declared. So you can't use a forward declaration for the Api class in this case, you must actually include the full definition.
Use
#ifndef __filex__
#define __filex__
At the beginning of each .h and
#endif
At the end.
This way, the .h file is read only once

Combine two or more C++ namespaces into one

First of all, sorry for my English.
Ok, I'm working a program that performs a specific process. This process needs some classes and functions to be defined. All of them must be organized in blocks to access them.
My first idea was to work with namespaces (C++), to get something like this:
namespace LoadSystem
{
namespace ParseBlock1
{
class ClassA {...}
class ClassB {...}
class ClassC {...}
}
namespace ParseBlock2
{
class ClassA {...}
class ClassB {...}
class ClassC {...}
}
}
So, I was reading to get the best idea if this is good or not. I already have read that I must not use lots of nested namespaces, so, for my purpose, the minimum levels are two, as shown above.
My objective is to be able to add more and more ParseBlocks into the LoadSystem namespace. It will be stored in a single .h file, so, there will be only interfaces of the classes. Since there can be lots of classes per block, I want to split the definition of each block into other .h files to keep the main .h file small as I can.
So, I ended with an idea of defining a file block1.h and block2.h, each one with a structure like this:
namespace LoadSystem
{
namespace ParseBlock1
{
class ClassA {...}
class ClassB {...}
class ClassC {...}
}
}
and
namespace LoadSystem
{
namespace ParseBlock2
{
class ClassA {...}
class ClassB {...}
class ClassC {...}
}
}
And import them in the load_system.h file. So, every time I need to add another block, I write the needed files, and finally, I just import the new blockX.h into the main load_system.h.
Then, I must be able to access both blocks from the same namespace using LoadSystem::ParseBlock1::Class1 or LoadSystem::ParseBlock2::Class1.
I have tested this with simple integer values and it works. The namespaces combine and I can access the values without any warning (I used gcc -Wall -Werror -Wextra -pedantic).
So, is this combination of namespaces is correct or not. Maybe it works, but I maybe should not use it, I don't know.
Also, I want to know if this process, of importing a "master" header file (which imports other header files) is also correct or not (I'm using the needed #ifndef, #define and #endif macros to guard from multiple imports), I'm using something like this:
# ifndef LOAD_SYSTEM_H_
# define LOAD_SYSTEM_H_
# include "block1/block1.h"
# include "block2/block2.h"
# endif
So, please help me to know if this is correct or not.
You can always extend an existing namespace, so that part is OK.
And that part is the only that has a simple technical answer.
Regarding "master header file", it's more subjective, a matter of personal preference. I prefer that the included headers can be included on their own without any prerequisites (like including other stuff before them). If so, then all's OK for me, but if not, then users of your code will in practice have to include the big master header file in order to get any little smaller header, and that can affect build times negatively (and if they don't, but themselves include the prerequisites, then they have brittle code that can stop working when you update a header).

What kind of bad things would happen if you write the whole class in a single file in C++?

In C# or Java, classes are declared and defined at the same time. In C++, the norm is to do that separately. What if we write the whole class in one , say .cpp, file and include that in files that references to it, what kinds of bad thing technically would happen besides a lengthened compilation process?
If your implementation of MyClass is all in the header file MyClass.h then any file you needed to implement MyClass will be included whenever someone includes MyClass.h.
If you change any part of MyClass.h, even if it's trivial (such as adding a comment or even a space) then all files that include it will have to recompile, even if the interface hasn't changed.
Neither of these matters for toy projects, but as you noted, when you have a program that consists of hundreds (or thousands, etc.) of class files, the added compilation time alone makes it worthwhile to separate out implementation from interface.
For instance, if I have the following:
// MyClass.h
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include "Inventory.h"
class MyClass
{
public:
MyClass();
void processInventory(Inventory& inventory)
{
// Do something with each item in the inventory here
// that uses iostream, iomanip, sstream, and string
}
private:
// ...
};
It would more ideomatically be written as:
// MyClass.h
class Inventory;
class MyClass
{
public:
MyClass();
void processInventory(Inventory& inventory);
private:
// ...
};
// MyClass.cc
#include "MyClass.h"
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include "Inventory.h"
MyClass()::MyClass()
{
}
void MyClass()::processInventory(Inventory& inventory)
{
// Do something with each item in the inventory here
// that uses iostream, iomanip, sstream, and string
}
Notice: Including MyClass.h doesn't mean iostream, iomanip, sstream, string, or Inventory.h have to be parsed. Changing how processInventory works doesn't mean all files using MyClass.h have to be recompiled.
Notice how much easier it can be to figure out how to use MyClass now. Header files serve an important purpose: they show people how to use your class. With the modified MyClass.h it's easy to see the list of functions. If each function is defined in the header, then you can't look at just the list of functions. That makes it harder to figure out how to use the class.
You may break the one definition rule.
If you write this:
class foo
{
public:
void doit();
};
foo::doit() {}
and include that in multiple classes, you will have multiple definitions of foo::doit and your link will fail.
But if you make all your classes inline, either by defining them within the class declaration:
class foo
{
public:
void doit() {
}
};
or by explicitly making them inline:
class foo
{
public:
void doit();
};
inline void foo::doit() {}
then you can include that file as many times as you like.
The linker will see multiple definitions of the class's members when you try to combine multiple such objects. Thus, you won't be able to produce a binary from source files that include anything in more than one place.
Typically you separate the declaration and definition of a class. This allows you to use your class in different source files by simply including the declaration.
If you include a .cpp which has both declaration and definition into 2 different source files then that class will be doubly defined.
Each .cpp that the class is included into will compile fine into object files. However each class must have only 1 definition total or else you will not be able to link your object files together.
The most important thing to understand about #include contrasted with other languages importing methods, is that #include COPIES the contents of that file where the #include directive is placed. So declaring and defining a class in the same file will create three things:
Significantly increase your compile
times.
If your definitions are not inline
you will get linker errors, since
the compiler finds multiple
definitions to the same functions
That would expose the implementation
to the user, instead of only the interface.
That is why it is common practice to define large classes in separate files, and on some ocassions, really small classes with small implementations (like smart pointers) in one file(To also implicitly inline methods).
#Bill
I think it is important to underscore Bill's point:
Notice how much easier it can be to
figure out how to use MyClass now.
Header files serve an important
purpose: they show people how to use
your class.
the .h file being more or less the "public" doc to allow the understanding of how your class works in some ways conceptually--an Interface. Remember the source file should be thought of as proprietary. I remember learning a lot about how Unix worked in my early C/C++ days by reading header files. Also remember that inline function complexities should be no more than accessor's
A big reason for a class to be defined in a cpp-file is that it isn't needed publically, it is just a helper function (like e.g. a functor). Some people seem to be afraid to put the complete class in the cpp-file, while that just shows your intent of only using the class there.
Files are usually the atoms of your version control system - if you partition things sensibly into different files, then it becomes possible for a team of developers to check out only the parts they each need to work on. Put everything in one file and you can't do that.

One file doesn't recognize other file's class in C++

I have my own class inside the file "Particles.h" and the class's implementation is inside "Particles.cpp"
I want the file "Load.h" to recognize my classes inside there, so I've added the line
#include "Particles.h"
and the file doesn't recognize it and in the past everything was OK (I haven't made any changes inside that class).
What should I do?
It sounds like your include path - the list of directories that the compiler scans in order to locate files that you #include - is set incorrectly. Which compiler are you using?
Well, if you listed your error codes, it might help. Off the top of my head, do you have something in Particles.h to make sure that the file is only included once? There are two methods of doing this. The first is to use #pragma once, but I think that might be Microsoft specific. The second is to use a #define.
Example:
#ifndef PARTICLES_H
#define PARTICLES_H
class CParticleWrapper
{
...
};
#endif
Also, unless you're deriving from a class in Particles.h or using an instance of a class instead of a pointer, you can use a forward declaration of the class and skip including the header file in a header file, which will save you compile time.
#ifndef LOAD_H
#define LOAD_H
class CParticleWrapper;
class CLoader
{
CParticleWrapper * m_pParticle;
public:
CLoader(CParticleWrapper * pParticle);
...
};
#endif
Then, in the Load.cpp, you would include the particle.h file.
make sure the file "Particles.cpp" has also included "Particles.h" to start with and the files are in the same folder and they are all part of the same project. it will help if you also share the error message that you are getting from your compiler.
Dev C++,It uses GCC,
The line is:
Stone *stone[48];
and it says: "expected constructor, destructor, or type conversion before '*' token ".
It sounds like you need to include the definition of the Stone class, but it would be impossible to say without more details. Can you narrow down the error by removing unrelated code and post that?