Declaring class object inside a class header C++ - 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.

Related

How to do Google test for function which are not a part of class?

Am performing Google test, Here am facing one challenge.
In my project some of the functions are not included in the header file, they are directly included in the source file. I can access the functions which are in header file by creating obj of the class but am not able to access which are only in source file.
Please guide me how to access these function.
Thanks in advance!.
Kiran JP
Declare them extern in your test code.
Example. Let's say you have a source file like this:
// Function declared and defined in .cpp file
void myFunction() {
// implementation
}
Then you could go ahead and do the following in your test code:
extern void myFunction();
TEST(MyTest) {
myFunction();
}
Unless the function was explicitly declared with internal linkage. Either by declaring it static or by declaring/defining it inside an anonymous namespace in C++11 or above.
You will need to add the declaration of those functions to a header file, either to your existing header files, or to a new header file.
For example, say you have this function in your class.cc file without any declaration in class.h file:
int SomeFunction(int a, int b){
//...
}
You should add the following line to a header file. Let's call it header.h:
// header.h
int SomeFunction(int a, int b);
Then modify your test file to include header.h:
#include "header.h"
TEST(SomeFunction, Test1) {
int c = SomeFunction(1,2);
}

Is it safe to separate your templated class' declaration and definitions on different header files?

I'm trying to create a library for a school work, and I've been wondering if it is safe to declare a templated class on the main header file containing the class definition and method declarations, but then separating the method definitions in a different header file?
Because I have been able to do this in my example below, but I don't know if it will cause me some problems in the long run.
main program
// main.cpp
#include <iostream>
#include "declaration.hpp"
int main()
{
card<int> a(5);
std::cout<<a.getID()<<'\n';
return 0;
}
main header file
in this header file, only the class definition and the declaration of the method getID() is written but not it's definition, and by the end of the class I included the other header file that contains the method definitions.
// declaration.hpp
#ifndef DEC_HPP
#define DEC_HPP
#include <iostream>
template<typename T>
class card
{
public:
T id;
card(const int id) : id(id) {}
T getID();
};
#include "definition.hpp"
#endif
method definitions
This header file contains the method definition of getID() from the main header.
I also included the "declaration.hpp" in this header, and this is the part where I'm not so sure of, because I included both files together with each other.
// definitions.hpp
#ifndef DEF_HPP
#define DEF_HPP
#include <iostream>
#include "declaration.hpp"
template<typename T>
T card<T>::getID()
{
return id;
}
#endif
I have compiled this program and it's working on my machine, but I just wanted to know if this way of isolating my code will cause me some errors in the future, I don't want to put my templated class definitions in a cpp files because I find it hard to maintain.
This is indeed a better approach because it makes your code look simple and better. Moreover, it is the main reason why header file is used.
Your main header file will simply tell that what functions/classes are you using and without even viewing your code, anyone can guess if you are working correctly or not.
There wont be any safety issues at all.

Including multiple headers for achieving polymorphism

I have an interface ver as
// ver.h
class ver
{
public:
virtual void func()=0;
};
Then ver1 and ver2 implement this interface. ver1 and ver2 differ in the sense they include header test\header.h and test2\header.h. Now test\header.h and test2\header.h are not under my control and are mostly similar except for a function pointer which is the reason for having ver1 and ver2
// test\header.h
#ifndef header
#define header
typedef void
(*FuncPoint)(
struct_type_a
);
#endif
and
// test2\header.h
#ifndef header
#define header
typedef void
(*FuncPoint)(
struct_type_b
);
#endif
Now the implementations
//ver1.h
#include "test\header.h"
class ver1:public ver
{
public:
FuncPoint f;
};
and
//ver2.h
#include "test2\header.h"
class ver2:public ver
{
public:
FuncPoint f;
};
and ver1.cpp and ver2.cpp will be using the respective f
Now the polymorphic behavior comes into play here
//something.cpp
#include "ver.h"
#include "ver1.h"
#include "ver2.h"
ver* somefunc()
{
if (some_condition)
return new ver1();
else
return new ver2();
}
Since something.cpp includes both ver1.h and ver2.h, first test\header1.h gets included and because of the include guards, test\header2.h is not included and hence there is no FuncPoint defined for class ver2 and something.cpp fails to compile.
On the other hand ver1.cpp and ver2.cpp gets compiled successfully since there is only one header.h included.
I could do a #undef header after including ver1.h in something.cpp but that would give redefinition error for other things which are same in test\header.h1 and tes\header2.h.
A simple fix would be to not have FuncPoint f as global variables instead of member variables, this way i won't have to include test\header.h in ver1.h but instead in ver1.cpp.
Is there some other better way to fix this?
EDIT:
I could forward declare struct_type_a and struct_type_b in something.cpp and avoid including ver1.h and ver2.h in something.cpp. But class ver1 and ver2 use other things(to declare members) from test\header.h as well(which are same in both versions).
Don't include header.h in ver1.h or ver2.h but in the respective .cpp files: FuncPoint is a pointer so you can use forward declarations. Since ver1.h and ver2.h will both be included you will need to rename it however where exposed (in the .cpp files you will be able to use the original FuncPoint too, since you include only one definition of it there):
//ver1.h
#include "ver.h"
struct struct_type_a;
typedef void (*FuncPoint_a)(struct_type_a);
class ver1 : public ver
{
public:
FuncPoint_a f;
static ver1 *create();
};
Also the creation of the polymorphic objects must be demanded to methods implemented in the .cpp files, in the create() static method.
Following your code it would become:
//something.cpp
#include "ver.h"
#include "ver1.h"
#include "ver2.h"
ver* somefunc()
{
if (some_condition)
return ver1::create();
else
return ver2::create();
}
In this way the two colliding headers will never be included in the same file.
I've added the inclusion of ver.h in ver1.h (and ver2.h) because this is the source using it. Including it in something.cpp only is not correct (ver1 and ver2 need it) - but not related to the current problem.

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.

Static array in header file - 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.