Defning a namespace class in a header file - c++

I have a similar problem to this but not the exact.
Assuming we have 2 header files and a main.cpp.
In the first header file we have :
namespace Logic
{
class GameManager;
}
In the second header:
#include "first_header.h"
class Logic::GameManager
{
public :
void init();
void run():
};
And in the main.cpp i have :
#include "first_header.h"
int main()
{
Logic::GameManager gm;
gm.init();
gm.run();
}
I get this error until i include the second header in main.cpp :
'gm' uses undefined class 'Logic::GameManager'
-Is this way of using namespaces and classes correct ?
-Is there a better way to do this?
Thanks.

Re-open the namespace to define the class.
namespace Logic {
class GameManager
{
public :
void init();
void run():
};
}
And include the second header, not the first, from main.cpp. The compiler cannot find the class definition unless it is directly #include'd.

Related

multiple definition of global with gmock-global in unit testing

I am trying to mock global function using https://github.com/apriorit/gmock-global library.
Note: this description contains example of the real scenario not the exact real scenario. Also I am not allowed to make any changes to global.hpp.
My example dir structure looks like below
--src
------global.hpp
------classA.hpp
------classB.hpp
------main.cpp
--ut
------classATests.cpp
------classBTests.cpp
------main.cpp
The ut/main.cpp tests testcases in classATests.cpp and classBTests.cpp.
global.hpp contains a global function
int giveIndex()
{
return 1;
}
classA.hpp calls giveIndex() global function
#include "global.hpp"
class A
{
public:
int checkIndex() { return giveIndex(); };
}
classB.hpp calls giveIndex() global function
#include "global.hpp"
class B
{
public:
int checkIndex() { return giveIndex(); };
}
classATests.cpp contains
#include <memory>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <gmock-global/gmock-global.h>
#include "src/classA.hpp"
MOCK_GLOBAL_FUNC0(giveIndex, int(void));
using namespace ::testing
struct classATests : public ::testing::Test
{
void Setup() override
{
sut_ = std::make_shared<A>();
}
std::shared_ptr<A> sut_;
};
TEST_F(classATests , checkIndex)
{
EXPECT_GLOBAL_CALL(giveIndex, giveIndex()).WillOnce(Return(1));
sut_->checkIndex();
}
classBTests.cpp contains
#include <memory>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <gmock-global/gmock-global.h>
#include "src/classB.hpp"
MOCK_GLOBAL_FUNC0(giveIndex, int(void));
using namespace ::testing
struct classBTests : public ::testing::Test
{
void Setup() override
{
sut_ = std::make_shared<B>();
}
std::shared_ptr<B> sut_;
};
TEST_F(classBTests , checkIndex)
{
EXPECT_GLOBAL_CALL(giveIndex, giveIndex()).WillOnce(Return(1));
sut_->checkIndex();
}
The issue now is when i compile and run UT for both classATests.cpp and classBTests.cpp i get errors saying
... multiple definition of 'giveIndex' ;
and
... multiple definitions of gmock_globalmock_giveIndex_instance
Is there any way to avoid this issue ? classA tests and classB tests need to be in 2 different files like it is now.
Functions defined in header files should be defined inline
inline int giveIndex()
{
return 1;
}
otherwise you will get multiple definition errors if you include the header file more than once.
The alternative would be to only declare the function in your header file
int giveIndex();
and then define it (but not inline) in one of your cpp files.
This is the normal way to organise C++ code. gmock has nothing to do with this.

C++ - 'class' type redefinition

I made a smaller reproducible version of the code that gave me these errosr: 'MyNamespace::MySecondClass': 'class' type redefinition, 'print': is not a member of 'MyNamespace::MySecondClass'. Is there any way of working around this problem?
// MyClass.h
#pragma once
namespace MyNamespace {
class MySecondClass {};
}
// MyClass.cpp
#include "MyClass.h"
#include <iostream>
using namespace std;
class MyNamespace::MySecondClass
{
public:
void print(const char* msg)
{
cout << msg << endl;
}
};
The problem is that in MyClass.h you define a class MySecondClass as an empty class. When you the define your class in MyClass.cpp you give a different definition, which contains some new members. This infringes the One Definition Rule (ODR).
Solution 1
remove {} in the header. This will tell the compiler that you declare that such a class exists but that it will be defined later. Your code would compile. Unfortunately if you’d include the header in other cpp, these could make only a very very limited use of MySecondClass.
Solution 2
define in the header the class with all its members (but without providing the implementation of the member functions:the signature is sufficient). This would allow the class to be used in whichever cpp that
would include it:
// MyClass.h
#pragma once
namespace MyNamespace {
class MySecondClass {
public:
void print(const char* msg);
};
}
You’d then define the members of the class in its cpp in the appropriate namespace:
// MyClass.cpp
#include <iostream>
#include "MyClass.h"
using namespace std;
namespace MyNamespace {
// member functions
void MySecondClass::print(const char* msg)
{
cout << msg << endl;
}
}
Remark: the include sequence in the cpp should first include the standard library headers, then only your own headers. It makes no difference in your simple example, but better get used the good practices immediately.

expected class-name before '{' token - with header files and cpp files

Like many people asking this question, I am very new to C++ and I can't wrap my head around this error:
Dollar.h:4:31: error: expected class-name before '{' token
class Dollar: public Currency {
These are my files
main.cpp
#include <iostream>
#include "Dollar.h"
using namespace std;
int main() {
Dollar * d = new Dollar();
d->printStatement();
return 0;
}
Currency.cpp
#include <iostream>
#include "Currency.h"
using namespace std;
class Currency {
public:
virtual void printStatement() {
cout << "I am parent";
}
};
Currency.h
#ifndef CURRENCY_H
#define CURRENCY_H
class Currency {
public:
virtual void printStatement();
};
#endif
Dollar.cpp
#include <iostream>
using namespace std;
void printStatement() {
cout << "I am dollar";
}
Dollar.h
#ifndef DOLLAR_H
#ifndef DOLLAR_H
class Dollar : public Currency {
public:
void printStatement();
};
#endif
Thank you so much for your time and any help is much appreciated.
The error says that the name of a class was expected between : public and { here:
class Dollar : public Currency {
^^^^^^^^
Currency is not a name of a class, because you haven't defined such class. Yes, you have defined such class in files Currency.cpp and Currency.h, but not in the file Dollar.h where that error occurs.
Solution: The class Currency has to be defined first before it can be used as a base class. Like so:
// class is defined first
class Currency {
public:
virtual void printStatement();
};
// now Currency is a class and it can be used as a base
class Dollar : public Currency {
public:
void printStatement();
};
Since a class must be defined in all source files where it is used, and the definition must be identical across all source files, it is often useful to define the class in a separate "header" file, such as you have done. In such case you can simply include that header in stead of writing the definition repeatedly in each source file:
#include "Currency.h"
Currency.cpp contains two definitions for the class Currency. Once in the header that is included, and then second time after that. You may not have multiple definitions for the same class in a single source file.
Solution: Remove the class definition from Currency.cpp. Instead only define the member function:
void Currency::printStatement() {
//...
}
Finally, you haven't defined Dollar::printStatement. You've defined printStatement, which is not the same thing.
In my case, I had two classes with same name but in two different namespaces.
So, changing the base class to something different solved the problem.

error C2011: 'class type redefinition - Basic Inheritance

Below are by 4 classes, I'm learning about basic c++ syntax and boy is it much harder and less forgiving than other languages I have used. I have a main class, base class "BaseArray" and two sub classes "OrderedArray" and "UnorderedArray".
Main.cpp
#include <iostream>
#include "OrderedArray.cpp"
#include "UnorderedArray.cpp"
using namespace std;
int main() {
system("PAUSE");
return 0;
}
BaseArray.cpp
#include <iostream>
using namespace std;
class BaseArray {
public:
BaseArray::BaseArray() {
}
};
OrderedArray.cpp
#include <iostream>
#include "BaseArray.cpp"
using namespace std;
class OrderedArray : public BaseArray {
OrderedArray::OrderedArray() {
}
};
UnorderedArray.cpp
#include <iostream>
#include "BaseArray.cpp"
using namespace std;
class UnorderedArray : public BaseArray {
UnorderedArray::UnorderedArray() {
}
};
The errors I receive are as followed, from scouting other threads online. I think it might have to do with duplicate calling of classes. To be honest, I have no clue. If someone could point me in the right direction that would be nice, thanks in advance!
error C2011: 'BaseArray':'class' type redefinition
error C2504: 'BaseArray':base class undefined
To fix this error I can remove one of the includes at the top of main.cpp, but I need those to create objects and call functions from the subclasses later on.
You should put your base array in a header:
BaseArray.h
#ifndef BASEARRAY_H_GUARD // include guard
#define BASEARRAY_H_GUARD // include guard
// no using namespace !!
// only includes needed for what's in the header
class BaseArray {
public:
BaseArray();
};
#endif // include guard
And then leave in the cpp only the implementation part of your class:
BaseArray.cpp
#include <iostream>
#include "BaseArray.h"
using namespace std;
BaseArray::BaseArray() { // no need class enclosing: the BaseArray:: prefix is sufficient
}
The you can apply the same principle to the derived classes:
OrderedArray.h
#ifndef BASEARRAY_H_GUARD // include guard
#define BASEARRAY_H_GUARD // include guard
#include "BaseArray.h" // include only those that you need but all those that you need
class OrderedArray : public BaseArray { // requires BaseArray
OrderedArray();
};
#endif
OrderedArray.cpp
#include <iostream> // include headers that are needed for class implementation
#include "OrderedArray.h" // this should be self contained and provide
// evertyhing that is needed for the class itself
using namespace std;
OrderedArray::OrderedArray() {
}
You then have to do the same for UnorderedArray and finally, you have to adapt your main.cpp to include .h instead of .cpp. And you're done.
A final remark: your cpp source code files are now ready for separate compilation. This means that you can no longer compile only main.cpp, hoping that it includes all the code: you have now to compile the 4 cpp files and link them together.

Abstract classes and class organization in C++

I would like to create a basic abstract class in C++, where the subclasses are each in a separate file. My abstract class looks something like
class Process_Base{
public:
virtual void process() = 0;
}
Should a simple implementation like this be contained entirely in a header file? If it is do I need to have a .cpp file associated with it?
When I create the subclasses what should their header file look? I was thinking .cpp file for the subclass should look something like
#include "Process_Base.h"
class Hello_Process : public Process_Base{
void process(){
printf("%s\n", "Hello, World");
}
}
Could someone verify that I am approaching this correctly, and if not give a simple example of what I should be doing.
UPDATE
I continued with the implementation but I am now getting the following compiler error
g++ -c -Wall -g Process_Message.cpp
Process_Message.cpp:4: error: expected class-name before ‘{’ token
The following is the abstract class header
// Abstract header .hpp file
class Process_Base{
public:
virtual void process() = 0;
};
the subclass header
// The subclass header .hpp file
#include "Process_Base.hpp"
class Process_Message : public Process_Base {
public:
void process();
};
and the implementation
// Simple implementation .cpp file
#include <stdio.h>
#include <string.h>
class Process_Message : Process_Base {
public:
void process(){
printf("%s", "Hello");
}
}
I don't understand why I am getting the error, can someone please explain.
You're missing ; at the end of Process_Base declaration, when you include the file, the compiler goes nut. correct is:
class Process_Base{
public:
virtual void process() = 0;
};
Why this 'Process_Base' is there in below code? You have already mentioned inheritance in header file,right?
// Simple implementation .cpp file
#include <stdio.h>
#include <string.h>
class Process_Message : Process_Base {
public:
void process(){
printf("%s", "Hello");
}
}
Also don't forget to type ';' at the end of the class declaration after '}'
Your correct code should look like this:
//Process_Message.h
#include "Process_Base.hpp"
class Process_Message : public Process_Base {
public:
void process();
};
//Process_Message.cpp
#include <stdio.h>
#include <string.h>
#include "Process_Message.h"
void Process_Message::process()
{
printf("%s", "Hello");
}
Don't forget to declare your overrides as virtual, or they will hide parent methods instead of implementing them.
#include <iostream>
class Process_Base
{
public:
virtual ~Process_Base() {}
virtual void process() =0;
};
class Process_Message : public Process_Base
{
public:
virtual void process(); // <- virtual
};
void Process_Message::process()
{
std::cout << "Hello";
}
The above should compile fine