Static array in header file - C++ - c++

How can I create a static array in my header file? I looked at some examples on stackoverflow but can't get them to work.
Thanks!
#ifndef DRUMKITLIBRARY_H_
#define DRUMKITLIBRARY_H_
class DrumKitLibrary
{
public:
static const char* const list[] = {"zip", "zam", "bam"};
};
#endif /* DRUMKITLIBRARY_H_ */

Your compiler error is occurring because that's not how you initialize static data (well, static const integral types can be initialized that way, but that's it). You only declare your static data in the class definition, you define it outside of the class. However, you still have a possible issue.
The problem with defining static data in your header file is that every file which includes that header gets its own copy of the array. You are better served by declaring it in the header and defining it in an implementation file.
// A.h
class A {
public:
static const char *f[];
};
// A.cpp
#include "A.h"
const char *A::f[] = { "one", "two" };

You don't.
You declare it in a header and define it in the source.

Related

C++ Global variable declaration

What I want to do is just to define a variable in a header file and use it on two different cpp files without redefinition that variable each time I include that header
Here is how I tried :
Variables.h
#ifndef VARIABLES_H // header guards
#define VARIABLES_H
static bool bShouldRegister;
#endif
(I also tried extern but nothing changed)
And in a cpp file I give it a value ::bShouldRegister = true or bShouldRegister = true;
In my another cpp file I check it's value by creating a thread and check its value in a loop (and yes my thread function works well)
while (true)
{
if (::bShouldRegister) // Or if (bShouldRegister)
{
MessageBox(NULL,"Value Changed","Done",MB_OK|MB_ICONINFORMATION);
}
Sleep(100);
}
And yes, that MessageBox never appears (bShouldRegister never gets true :/)
You should use extern otherwise you will have separated bShouldRegister variables in each translation unit with probably different values.
Put this in a header file (.h):
extern bool bShouldRegister;
Put this in one of implementation files (.cpp):
bool bShouldRegister;
Another way which is simpler is to use inline keyword. Put you variable in a header file as below:
inline bool bShouldRegister;
If you can use C++17, consider using an inline variable:
// in a header file
inline bool bShouldRegister = true;
See How do inline variables work? for more information.
A more C++-like way would be using a class member, syntactically indicated by the static keyword. Class member variables have implicit external linkage.
#ifndef VARIABLES_H
#define VARIABLES_H
class RegUtil {
public:
static bool bShouldRegister;
};
#endif
in one of your cpp files (maybe variables.cpp), you have to define this class member:
#include "variables.h"
bool RegUtil::bShouldRegister;
You need to define the variable in one of the modules:
bool bShouldRegister;
Then declare it extern (not static!) in the header:
extern bool bShouldRegister;
Here you need to define bool bShouldRegister in one class. Your header file should like this.
#ifndef VARIABLES_H // header guards
#define VARIABLES_H
class abc{
public:
bool bShouldRegister;
abc();
#endif
Now initialize bShouldRegister variable in cpp file in constructor of abc class and then use this variable in your second cpp file using object of class. You will get your message box.

Declaring class object inside a class header C++

I'm trying to declare a class object inside a header but I can't get it working. I currently have 2 header files and 2 cpp files that defines what each function does. The classes are called Heltal and Array, and both of them are in their own header file (heltal.h and array.h).
I'm trying to declare the Heltal class object inside the private part of the Array class, but whatever I do I can't find a way to declare it. I've tried including the heltal.h header to the array.h header but then it starts complaining about being redefined.
Declaring it in the array.cpp however works just fine but I would like to have it defined in the header instead.
Here's what the files look like at the moment:
heltal.h
class Heltal {
public:
Heltal();
Heltal(int tal);
~Heltal();
void set(int tal);
bool operator < (const Heltal &heltal) const
{
return (heltal < heltal.heltal);
}
bool operator > (const Heltal &heltal) const
{
return (heltal > heltal.heltal);
}
private:
int heltal;
};
array.h
#include <vector>
class Array {
public:
Array();
Array(int in);
~Array();
int Random(int min, int max);
private:
Heltal h;
int size;
};
Both headers are included in the main.cpp
You started along the right path when you included Heltal.h inside Array.h.
Add the include guards to your headers, this will help you avoid duplicate inclusions:
#ifndef HELTAL_H
#define HELTAL_H
class Heltal {
...
};
#endif
Now you can safely include Heltal.h at the top of Array.h, and your problem will be solved.
When compile a c/cpp file, the included file would be expand in the c/cpp file first.
and some class should be in a right order.
e.g.
Heltal MUST before Array, so your include order should ensure this.
You do need to include heltal.h inside array.h, but both files will need include guards:
#ifndef array_h_guard
#define array_h_guard
// contents of array.h go here
#endif // array_h_guard
and similarly for heltal.h. This will prevent the multiple inclusion.
Note that you could simply only include heltal.h from array.h, which also fixes the immediate issue, but the include guards are safer.

forward declaration and cyclic header inclusion in C++

I have two classes
RequestManager.h
#ifndef REQUESTMANAGER_H
#define REQUESTMANAGER_H
#include "RequestClient.h"
class RequestManager
{
public:
void AddReqeustItem(RequestClient *req);
private:
std::list<RequestClient*> m_reqClientContainer;
};
#endif
RequestClient.h
#ifndef REQUESTCLIENT_H
#define REQUESTCLIENT_H
class RequestManager; // Forward declaration to avoid cyclic inclusion.
class RequestClient {
public:
void CreateRequest(RequestManager* pManager)
{
// ... I am creating a request.
pManager->AddReqeustItem(req);
};
#endif
In the code above I am getting error undefined RequestManager in Request client class. What is the problem and how can I solve it?
You cannot use a type with only a forward declaration. Forward declaration are used to say to compiler that type exists but compiler does not know the content of the type.
My advice:
In header file, I would only define class and function members. So forward declaration is possible if only pointer are used.
In body file, write the code your member function and include the header files
put the member function definition in a source file which #includes both headers.
Or, if you still want it to be inline (or if it's templated), then put the definition of the member function body further in the header, after all relevant code is defined. In the case of a single header file (which does make sense here):
class B; // forward decl
class A {
void use(B*);
};
class B {
void use(A*);
};
void A::use(B*b) { /* ... */ }
void B::use(A*a) { /* ... */ }
Note the splitting of the code into files (several headers and one source) is only a convenience for the programmer (making it much simpler to maintain and use by other parts of the code), but from the point of view of the compiler this doesn't matter: it sees only one big file of code (after pre-processing). So, it's up to you how you split the above layout into headers and source file.
You use the method RequestManager::AddReqeustItem(), but there's only a forward declaration of RequestManager. With just a forward declaration the compiler doesn't even know which methods of RequestManager exist. So, to fix this problem, you must provide the definition of RequestManager, which is usually in the header file.
Move the method definition of CreateRequest() into the cpp file and include RequestManager.h there
RequestManager.cpp:
#include "RequestManager.h"
...
void CreateRequest(RequestManager* pManager)
{
// ... I am creating a request.
pManger->AddReqeustItem( req);
}

is it possible to define the static member function of a class in .cpp file instead of its header file?

i am having a function which should be run only once for all instance of the class.i thought to use the static function calling method. all the web example shows that static function define in the Header file(inside the class) itself. my function is big one i cant define that in header file what should i do? for that.
Like you do for normal functions:
FooBar.h
#ifndef FOOBAR_H
#define FOOBAR_H
class FooBar
{
public:
static void test();
};
#endif
FooBar.cpp
#include "FooBar.h"
void FooBar::test()
{
}
If using linux
static pthread_once_t semaphore = PTHREAD_ONCE_INIT;
pthread_once( & semaphore, FooBar::test() );
So you can be sure to go once in your function

C header file won't compile with C, but will with C++

I have the following chunk of a header file BKE_mesh.h:
/* Connectivity data */
typedef struct IndexNode {
struct IndexNode *next, *prev;
int index;
} IndexNode;
void create_vert_face_map(ListBase **map, IndexNode **mem, const struct MFace *mface,
const int totvert, const int totface);
void create_vert_edge_map(ListBase **map, IndexNode **mem, const struct MEdge *medge,
const int totvert, const int totedge);
Note that the header file was prepared for the possibility of being used in a C++ file, as it had:
#ifdef __cplusplus
extern "C" {
#endif
at the top of the file, and the needed finish at the bottom. But the class implementing it was written in C.
Next, whenever I try to #include the header file, I get an odd error. If the file has a .cpp extension, it compiles just fine, no complaints whatsoever. However, if I do:
#include "BKE_mesh.h"
inside of a file with a .c extension, I get the following errors:
expected ')' before '*' token
for the two last functions, in specific, the variable:
ListBase **map
in both classes. (Note that earlier in the header file, it declared, but not defined ListBase).
So, my question is: why is this valid C++ code, but not C code?
Thank you.
In C++ you can refer to struct names directly but in C you need to prepend the keyword struct.
void create_vert_face_map(struct ListBase **map, ... );
You could get around this by adding a typedef. Then you wouldn't have to modify the function declaration.
typedef struct ListBase ListBase;
Try running just the pre-processor for each case.
Comparing the result may show different header files.
If so, it may hint on the "C"-problem.