Redefinition of a class in a header file - c++

I'm attempting to compile my code with g++, but its throwing this compiler error:
Enrollment.h:3:7: error: redefinition of class sict::Enrollment
Enrollment.h:3:7: error: previous definition of class sict::Enrollment
my Enrollment.h:
namespace sict{
class Enrollment{
private:
char _name[31];
char _code[11];
int _year;
int _semester;
int _slot;
bool _enrolled;
public:
Enrollment(const char* name , const char* code, int year, int semester , int time );
Enrollment();
void set(const char* , const char* , int ,int, int , bool = false );
void display(bool nameOnly = false)const;
bool valid()const;
void setEmpty();
bool isEnrolled() const;
bool hasConflict(const Enrollment &other) const;
};
}
Any way to fix this?

The problem is likely that your header file is included (directly and indirectly) in the same translation unit. You should use some way of avoiding the multiple includes of the same header file in your cpp's. I prefer #pragma once in the beginning of your header file - it is not standard but it is supported by all major compilers. Otherwise you can go for good-old include guards:
#ifndef _Enrollment_h_
#define _Enrollment_h_
// Your header contents here
#endif
or with pragma:
#pragma once
// Your header contents here

You need to use some include guards. Either #pragma once or:
#ifndef MY_FILE_H
#define MY_FILE_H
....
#endif //MY_FILE_H
This is to prevent the same code being included in every file where you include this header (double inclusion). This will essentially help out the pre-processor. More information here.

Related

Include .c files in Unit test project and get access to it from multiple cpp files without linking problems

I'm doing functional testing on c code. Have include .c file in test .cpp file so far, everything works well. But I need to include the same .c file in another .cpp file where I do other unit tests. Then I get problems that is already defined. Because I already include it in the first file cpp.
If merge all the test methods into one cpp file then it works well. If keep all unit test in one file get to big handle so I need to split up diffrent files in same project it also create help functions for secure that functions get in capsules.
This not a normal LNK2005 because I can not declare the variable and functions in .h: as extern BOOL MyBool; and then assign to it in a .c or .cpp file. Because need include c file as I do unit test this function. Also I can't or should avoid do any changes .c.
I looking way to keep include of .c local not effect other files in same project.
source.h
#ifndef SOURCE_H_
#define SOURCE_H_
#include "../car.h"
enum INITIALMODE {
INITIALMODE_NOT_POSITIONING, // 0
INITIALMODE_NO_DRIVER_INPUT, // 1
INITIALMODE_POSITION_LOW_POSITION, // 2
INITIALMODE_POSITION_STANDARD_POSITION, // 3
INITIALMODE_POSITION_HIGH_POSITION // 4
};
void initMotor(void);
#endif
source.c
/* Compiler include files */
#pragma once
#include "positioning.h"
#include "api.h"
#include "drive.h"
#include "types.h"
static void updateTarget(void);
static SWord getMax(UWord Limit, UWord Aux);
static DWord getHeight(void);
static Bool isMode(void);
static Bool isExiting(void);
#define cMaxHeight 100 * Profile.s.Max /* m -> mm */
void initMotor(void)
{
// do something
}
static void updatePositioning(void)
{
// do something
}
Test files look like this, however, this is very scaled for making exemple small.
UnitTest.cpp and UnitTest2.cpp
#include "CppUnitTest.h"
#ifndef UNIT_TEST
#define UNIT_TEST
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace Test
{
extern "C" {
#include "../../Test/source.h"
#include "../../Test/source.c"
}
TEST_CLASS(UnitTest_1)
{
public:
TEST_METHOD(Test_1)
{
// Verify that the initial state is as expected.
initTest();
//Expected value
UWord Expected = 500
//Trigger to execute.
UWord Test = updatePositioning();
// Verify that the results are as expected.
Assert::AreEqual(Expected, Test);
}
};
}
#endif
You should never include a .C or .CPP file.
However, you can compile C code in C++. Here's an example based on the information you gave in your initial post.
YourCCode.h
#ifndef YourCCode_H
#define YourCCode_H
int FunctionToTest(int SomeParams);
int TestStaticFunctions(int SomeParam1, int SomeParam2);
#endif // YourCCode_H
YourCCode.c
#include "YourCCode.h"
static int SomeStaticFunction(int Param1, int Param2)
{
return Param1 + Param2; // that needs extensive testing, obviously.
}
int FunctionToTest(int SomeParams)
{
return SomeStaticFunction(SomeParams, 1);
}
int TestStaticFunctions(int SomeParam1, int SomeParam2)
{
return SomeStaticFunction(SomeParam1, SomeParam2);
}
UnitTest1.cpp
extern "C" {
#include "YourCCode.h"
}
bool TestFunction(int Value)
{
return (FunctionToTest(Value) == Value+1);
}
UnitTest2.cpp
extern "C" {
#include "YourCCode.h"
}
void AnotherTestFunction(int Val, int Val2)
{
int newValue = TestStaticFunctions(Val, Val2);
ASSERT(newValue == Val+Val2);
}
Then compile your CPP and C file.
After you clarified your intent, I realized you're trying to test static functions from another unit. Static function, by definition, are only available to other functions in the same translation unit. This is mostly use as a protection to prevent programmers to call some functions without knowing how to validate their inputs, know the call order, etc...
My best bet here is either you choose that your functions are not static and you can test them from outside your translation unit, or you implement the test functions inside the translation unit containing those static functions. I would recommend the latter as a translation unit should know (architecturally speaking) how to test their own features.
As a third solution, if you don't have any control over the content of the C file (but since you have that C file, I doubt it), you could have a proxy CPP file that includes the C file, and create a proxy call for each static call.
That is a ugly hack, though, and could break very easily if the C file ever gets updated, so I'm advising against it.
Here's a quick example :
YourCCode.h
#ifndef YourCCode_H
#define YourCCode_H
void SomeFunction(void);
#endif // YourCCode_H
YourCCode.c
#include "YourCCode.h"
static int AddSomething(int Param1, int Param2)
{
return Param1 + Param2;
}
static int SubtractSomething(int Param1, int Param2)
{
return Param1 - Param2;
}
void SomeFunction(void)
{
// code meant to be called externally.
}
ProxyTestCode.hpp
bool TestAddSomething(void);
bool TestSubtractSomething(void);
ProxyTestCode.cpp
extern "C" {
#include "YourCCode.h"
#include "YourCCode.c"
}
bool TestAddSomething(void)
{
return (AddSomething(2,2) == 4);
}
bool TestSubtractSomething(void)
{
return (AddSomething(2,2) == 0);
}
UnitTest1.cpp
#include "ProxyTestCode.hpp"
void TestAdd(void)
{
ASSERT(TestAddSomething());
}
UnitTest2.cpp
#include "ProxyTestCode.hpp"
void TestSubtract(void)
{
ASSERT(TestSubtractSomething());
}
If you do that, don't compile your C file in your project.

error C2011: 'SelectorBox' : 'class' type redefinition

I have a problem with a following code:
#ifndef HEADER_H_
class SelectorBox{
public:
string selectorName;
map < string, string > attributeMap;
void setSelectorName(string name);
void setAttribute(string key, string value);
};
string trimTheString(string str); //trimming a string
#endif
//include libraries
#include "Header.h"
using namespace std;
int main()
{
vector <SelectorBox> vectorSelectBox;
SelectorBox *selectorBox;
//code
return 0;
}
#include "Header.h"
#include "main.cpp"
void SelectorBox::setSelectorName(string name) //setter
{
name = trimTheString(name);
selectorName = name;
}
void SelectorBox::setAttribute(string key, string value) //setter
{
key = trimTheString(key);
value = trimTheString(value);
attributeMap[key] = value;
}
When I compile a program, it shows many errors (specifically errors 4430 and 2061), but I believe that the main error is:
error C2011: 'SelectorBox' : 'class' type redefinition.
You must define HEADER_H_. You missed second line from below code.
#ifndef HEADER_H_
#define HEADER_H_
...
#endif
You are including the same header twice, first before main second after main, this causes a problem if you don't use proper include guards.
Your include guard is incomplete, so multiple includes of the same header will cause this error. The trick is to check if a header-specific preprocessor name is defined: If not, then define it, else skip the whole header.
The pattern to use is like this
#ifndef GUARD
#define GUARD
/// the actual header contents
#endif
but simply copying it into every header will cause another problem, because its lack of header specificity. The simplest way to find a good name is to derive it from the file name itself. In your case I'd name the header after the class SelectorBox defined in it, so SelectorBox.h would be a good name, and the include guards would look like this:
#ifndef SELECTORBOX_H
#define SELECTORBOX_H
class SelectorBox {
/// etc.
};
#endif
Using multiple headers with the same include guard is much worse than using no include guards at all.
I guess, you have 3 files:
Header.h
main.cpp
FileX.cpp (you didn't disclose the real name of mister X so far)
In main.cpp you are including Header.h, in FileX.cpp you are including Header.h and main.cpp. Let me show a simplified version of what happens here:
The contents of main.cpp gets transformed into
//include libraries
class SelectorBox{
public:
string selectorName;
map < string, string > attributeMap;
void setSelectorName(string name);
void setAttribute(string key, string value);
};
string trimTheString(string str); //trimming a string
using namespace std;
int main()
{
vector <SelectorBox> vectorSelectBox;
SelectorBox *selectorBox;
//code
return 0;
}
Assuming you included string and map and there is another using namespace std; somewhere before your class definition, this could compile without errors.
But now let's see what happens in FileX.cpp. Its contents gets transformed into the following, and I hope you'll see now what the compilers sees: there is more than one definition of the class SelectorBox:
class SelectorBox{
public:
string selectorName;
map < string, string > attributeMap;
void setSelectorName(string name);
void setAttribute(string key, string value);
};
string trimTheString(string str); //trimming a string
//include libraries
class SelectorBox{
public:
string selectorName;
map < string, string > attributeMap;
void setSelectorName(string name);
void setAttribute(string key, string value);
};
string trimTheString(string str); //trimming a string
using namespace std;
int main()
{
vector <SelectorBox> vectorSelectBox;
SelectorBox *selectorBox;
//code
return 0;
}
void SelectorBox::setSelectorName(string name) //setter
{
name = trimTheString(name);
selectorName = name;
}
void SelectorBox::setAttribute(string key, string value) //setter
{
key = trimTheString(key);
value = trimTheString(value);
attributeMap[key] = value;
}
... compilers use to call that a "redefinition".

multiple definition of a function

I defined a function to show a message when debug flags are off in a header file as below:
#ifdef NDEBUG
#define debug_msg(expr, msg) (static_cast<void>(0))
#else /* Not NDEBUG. */
#ifndef SHOW_DEBUG_H_
#define SHOW_DEBUG_H_
#include <stdio.h>
void _show_in_debug(const char *_file, unsigned int _line,
const char *_function, const char *_msg)
{
printf("%s\t%d\t%s\t%s\n", _file, _line, _function, _msg);
fflush(NULL);
}
#endif
#define debug_msg(expr, msg) \
((expr) \
? _show_in_debug(__FILE__, __LINE__, __func__, msg) \
: static_cast<void>(0))
#endif
when I include the header in more than a file, I get the following error:
multiple definition of `_show_in_debug(char const*, unsigned int, char
const*, char const*)'
I don't exactly know what I am doing wrong here, any help ?
Even with the include guards, you end up with a definition of _show_in_debug in each compilation unit. Linking those units then results to a multiple definition error.
For a debugging function like this, define the function as static so that it is not visible outside its compilation unit:
static void _show_in_debug(const char *_file, unsigned int _line,
const char *_function, const char *_msg)
{
printf("%s\t%d\t%s\t%s\n", _file, _line, _function, _msg);
fflush(NULL);
}
If you include that header into more than one .c file, each of them will define the function. That is what the error says.
What you should do is to only declare the function in the header (i.e. only put the prototype there; which you always should) and then define it in a single .c file (i.e. put the body in the .c file), encapsulated into the same switches as the prototype.
Header to be changed to this:
/* ... as you quoted ... */
void _show_in_debug(const char *_file, unsigned int _line,
const char *_function, const char *_msg);
/* ... rest of what you quoted ... */
Code file to contain this:
#incude <stdio.h>
#include "Yourheader.h"
#ifdef NDEBUG
void _show_in_debug(const char *_file, unsigned int _line,
const char *_function, const char *_msg)
{
printf("%s\t%d\t%s\t%s\n", _file, _line, _function, _msg);
fflush(NULL);
}
#endif
I assume the file header file that you have presented is included in several source files. Why is this a problem? That is because you have defined your _show_in_debug() function in the header instead of declaring it in the header and defining it in a source file file. This leads to the function be defined in multiple source files that have included your header.
See http://www.cprogramming.com/declare_vs_define.html for more details (especially, see the "Common Cases" section).

Static variables and initialization

I am trying to reach a static variable declared in MyClass.h from MyClass.cpp. But I get following errors.
I made a research but still have no clue why my code does not compile. I use visual studio 2013.
MyClass.h
#ifndef __MyClass_h_
#define __MyClass_h_
class MyClass {
static int x;
public:
static int y;
};
#endif
MyClass.cpp
#include "MyClass.h"
void MyClass::sor() (const string& var1, const unsigned count) const {
// What goes here? See below for what I have tried
}
So, if I use:
int MyClass::x=8;
This says int MyClass::x redefinition and MyClass::x 'MyClass::x' : definition or redeclaration illegal in current scope
If I use:
MyClass::x=8;
This gives the error 1 unresolved external.
If I use:
MyClass::y=8;
This also gives the error 1 unresolved external.
If I use:
int MyClass::y=8;
This says int MyClass::y redefinition and 'MyClass::y' : definition or redeclaration illegal in current scope
You need to understand you don't have a static variable in a header, how other answers suggest. You have a static member of a class, which is perfectly fine.
In order to access it you write: MyClass::x. You need to initialize it also.
Unrelated to the static member, you need to declare the method also:
header:
#ifndef __MyClass_h_
#define __MyClass_h_
class MyClass {
static int x;
public:
static int y;
void sor() (const string& var1, const unsigned count) const;
};
#endif
source file:
#include "MyClass.h"
int MyClass::x = 0; // intialization
void MyClass::sor() (const string& var1, const unsigned count) const {
MyClaxx::x = 11; // access it
}
You have a declaration for the static variable but don't have the definition for it. In order to use static class members you should define them in the corresponding translation unit. You can't do it in the header file because it will violate ODR(one definition rule) so you should define it in the .cpp file to confrom the aforementioned rule.
So you have to put int MyClass::x = 0; in your cpp file in global scope(or under the namespace if you have one) to get it working. Note, that you could use whatever value insted of 0 or even didn't provide any(in this case it will be 0 anyway, due to special treatment of global(static) variables.)
When static variable is declared in a header file is its scope limited to .h file or across all units.
Refer here for source
This is simple. When you declare a static variable in a header file, it's scope is limited to header file. When you going to use that static variable in a .cpp file you getting an error like this. It is because you didn't give the definition of the static variable. So in any of the .cpp file you need to give the definition of static variable. ex :
.h file
class MyClass {
static int x;
.....
}
Top of the .cpp file you should define the static variable like this.
#include "MyClass.h"
int MyClass::x = 0 ;
void MyClass::sor() (const string& var1, const unsigned count) const {
MyClass::x = 8 ; // you can access without any issue
}

Error in C++ : redefinition of class constructor using templates

Anybody know how I can fix these errors?
i have been looking at it for a while and just cannot figure out what to do.
Error:
indexList.cpp:18: error: redefinition of `indexList<T>::indexList()'
indexList.cpp:18: error: `indexList<T>::indexList()' previously declared here
indexList.cpp:30: error: redefinition of `bool indexList<T>::append(T)'
indexList.cpp:30: error: `bool indexList<T>::append(T)' previously declared here
cpp file:
//
//
//
//
//
//
#include "indexList.h"
#include <iostream>
using namespace std;
//constuctor
//Descriptions: Initializes numberOfElement to 0
// Initializes maxSize to 100
//Parameters: none
//Return: none
template <class T>
indexList<T>::indexList()
{
numberOfElements = 0;
maxSize = 100;
}
//Name: append
//Purpose: Adds element to the end of the list. If array is full, returns false
//Paramters: value - thing to append
//Return: true if append succeeds, false otherwise
template <class T>
bool indexList<T>::append(T value)
{
if (maxSize > numberOfElements)
{
list[numberOfElements] = value;
numberOfElements ++;
return true;
}
else
return false;
}
I didn't put all the the cpp file because the rest of the errors are similar to the ones above, and it is quite long
header:
#include <iostream>
using namespace std;
#ifndef INDEXLIST_H
#define INDEXLIST_H
template <class T>
class indexList
{
public:
indexList();
bool append(T value);
bool insert(int indx, T value);
bool replace(int indx, T newValue);
bool retrieve(int indx, T &value) const;
bool remove(int indx);
void sort();
int search(T value) const;
private:
T list[100];
int numberOfElements;
int maxSize;
};
template <class T>
ostream &operator<<(ostream &outStream, const indexList<T> &lst);
#include "indexList.cpp"
#endif
I did put the entire header
Each of your two files tries to include the other, which can cause the preprocessor to output some repeated code.
Take the #include "indexList.h" out of the file indexList.cpp.
Also, your build process should not attempt to compile indexList.cpp into an object file.
Another way to arrange things would be to just put all the contents you currently have in indexList.cpp near the end of indexList.h, and there would be no indexList.cpp file at all.
What you've done is ok, but you must realise that the .cpp file should not itself be compiled into an object - instead, just include the .h file from your application code:
// main.cc
#include "indexList.h"
int main()
{
indexList<int> il;
}
c++ -o main main.cc
I'd bet it's because you've tried to do a c++ -c indexList.cpp or c++ indexList.cpp that you get the errors (or perhaps your make tool is trying that automatically for all .cpp files in your source code directories - you could try renaming indexList.cpp to indexList.inl or .inc or whatever - remember to change the name in indexList.h too - to see if that fixes the problem), as in that situation the definitions are seen twice: once as the compile includes indexList.h, and again as it finishes compiling indexList.cpp.
There's no need to include indexList.h from within the .cpp anyway - that makes it look as if the indexList.cpp is designed for separate compilation.
Put any of your templated methods in an indexList.inl file, and include that from your header. Don't include the header from this file.
Put any other methods in your indexList.cpp file. Include the header from this file.