I have a starter project and I need to write a custom allocator and diagnostic tools for it. I made a class Class in which I have 2 methods for the custom allocator void alloc() void dealloc() and for the diagnostic tools void evaluate().Now, I declared an object test of type Class in CustomAllocator.h and use the 2 methods to allocate and deallocate memory with no problems. But when I try to call the evaluate() method in CustomAllocatorTest.cpp I got the linker error class Class test(?test##3VClass##A) already defined in CustomAllocatorTest.obj and LNK1169 one or more multiply defined symbols found.
Class.h
#pragma once
class Class
{
public:
void alloc() { std::cout << "alloc"; }
void dealloc() { std::cout << "dealloc"; }
void evaluate() { std::cout << "evaluate"; }
};
CustomAllocator.h
#ifndef _CUSTOM_ALLOCATOR_H_
#define _CUSTOM_ALLOCATOR_H_
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <stdlib.h>
#include "Class.h"
Class test;
#endif // _CUSTOM_ALLOCATOR_H_
CustomAllocator.cpp (#include "stdafx.h" includes "CustomAllocator.h")
#include "stdafx.h"
using namespace std;
int main()
{
test.evaluate();
return 0;
}
in your file CustomAllocator.h you declare test in global scope :
#ifndef _CUSTOM_ALLOCATOR_H_
#define _CUSTOM_ALLOCATOR_H_
#include "Class.h"
Class test; // <-- Declaration of test
#endif
But your CustomAllocator.h is included many times, in many places (in UseCustomAllocator.h and CustomAllocator.cpp) which will generate an already defined error for test variable.
Please see how to declare externe globale variable here #pragma once doesn't prevent multiple variable definitions
Related
I have a class SetStructure with this .h file:
#ifndef setstructure_h
#define setstructure_h
#include "Matrix.h"
class SetStructure {
public:
SetStructure();
//some other functions
};
#endif
And a training class with this .h file:
#ifndef training_h
#define training_h
#include "SetStructure.h"
#include "Matrix.h"
class Training {
private:
//some functions
public:
//some functions
};
#endif
When I compile everything, I get this error in my implementation file for Training:
SetStructure training = new SetStructure();
This gives an error
'SetStructure' was not declared in this scope.
Furthermore the compiler thinks all my functions in Training return int even though they're specified as other return types in the Training.h file.
Is there some problem with my #include statements or something else which might lead to this issue?
I am trying to run a function from a class file, but it is not working and I get the the following error messages:
error LNK1120: 1 unresolved externals
error LNK2019: unresolved external symbol "public: void __thiscall NS::Class1::test(void)" (?test#Class1#NS##QAEXXZ) referenced in function _main
//Main.cpp
#include<iostream>
#include<string>
#include<Windows.h>
#include "Class1.h"
int main(){
NS::Class1 E;
E.test();
return 0;
};
//Class1.cpp
#include <Windows.h>
#include <string>
namespace NS{
class Class1{
Class1(){
OutputDebugString(L"Created.");
}
void test(){
OutputDebugString(L"Hello World");
}
};
}
//Class1.h
#ifndef _Class1_H_
#define _Class1_H_
namespace NS{
class Class1{
public:
void test();
};
}
#endif
In your source file, you're redefining the class, rather than defining its member functions. That will give undefined behaviour, since you're only allowed to define the class once. The source file should look more like:
#include "Class1.h"
#include <Windows.h>
NS::Class1::Class1(){
OutputDebugString(L"Created.");
}
void NS::Class1::test(){
OutputDebugString(L"Hello World");
}
You'll also need to modify the class definition in the header, since it doesn't declare a constructor.
Also, make sure that your project is compiling and linking both source files.
Your header file contains reserved IDs for the include guard and misses the declaration of the constructor. It should look like this:
#ifndef CLASS1_H
#define CLASS1_H
namespace NS {
class Class1
{
public:
Class1();
void test();
};
}
#endif
The definition of the class should not include the class declaration, it should include it, and should look more like this:
#include <Windows.h>
#include "Class1.h"
namespace NS {
Class1::Class1()
{
OutputDebugString(L"Created.");
}
void Class1::test()
{
OutputDebugString(L"Hello World");
}
}
I think your .cpp file might be causing the issue. Since you already created the class definition in your header with class member declarations, just import the Class1.h header in the Class1.cpp file and scope the member functions then defining their behavior.
so maybe try:
#include <Class1.h>
NS::Class1::Class1(){}//constructor
void NS::Class1::test(std::cout << "hi"){}
I did not realize in a .dll library object types that depends on things that happen at compile time can case problems until I read the question Could I ignore C4251 warning in this case? In deed, if the library compilation settings for the library and the program that uses the library are different, some errors can occur. Here is an example:
dll.h
#include <iostream>
#include <string>
using namespace std;
class __declspec(dllexport) HelloWorld
{
public:
#ifdef DTEST
int test;
#endif
HelloWorld();
};
dll.cpp
#include "dll.h"
HelloWorld::HelloWorld()
{
#ifdef DTEST
test=0;
#endif
}
exe.cpp
#include "dll.h"
#include <iostream>
using namespace std;
int main(void)
{
HelloWorld myworld;
return 0;
}
If I compile dll.h and dll.cpp to create dll.lib and dll.dll with the definition of DTEST but compile exe.cpp without the definition of DTEST. I will have a runtime check failure #2 error. Could some explain why I have this error. Thanks!
You have this error because DTEST is a preprocessor macro and you are not defining it consistently for all pieces of your program. It is completely removed by the time your code reaches the actual compiler, so the compiler won't catch the problem. If you define DTEST for dll.cpp but not for exe.cpp, then exe.cpp will look like this to the compiler:
(...contents of <iostream>...)
(...contents of <string>...)
using namespace std;
class __declspec(dllexport) HelloWorld
{
public:
HelloWorld();
};
(...contents of <iostream> again...)
using namespace std;
int main(void)
{
HelloWorld myworld;
return 0;
}
However, dll.cpp will look like this:
(...contents of <iostream>...)
(...contents of <string>...)
using namespace std;
class __declspec(dllexport) HelloWorld
{
public:
int test;
HelloWorld();
};
HelloWorld::HelloWorld()
{
test=0;
}
The problem here is dll.cpp and exe.cpp have two different ideas of what HelloWorld is: dll.cpp thinks it contains test, but exe.cpp thinks it doesn't. There is a runtime check that catches this mismatch, which is what you're seeing.
What the compiler sees is the results of preprocessor expansion.
In your example, the compiler sees:
class HelloWorld
{
public:
int test;
HelloWorld();
};
in dll.cpp, and
class HelloWorld
{
public:
HelloWorld();
};
in exe.cpp. Same class, two different definitions. That's
a violation of the one definition rule, which results in
undefined behavior.
This has nothing to do with the C4251 warning (which if
I understand correctly, only concerns linking between different
DLLs).
Here's the whole code getting the errors:
Engine.h
#ifndef ENGINE_H
#define ENGINE_H
#include "DXManager.h"
namespace XEngine
{
class Engine
{
};
}
#endif
DXManager.h
#ifndef DX_MANAGER_H
#define DX_MANAGER_H
namespace XEngine
{
class Engine; // forward declaration
class DXManager
{
public:
void run(Engine *engine);
};
}
#endif
DXManager.cpp
#include <iostream>
#include "Engine.h"
#include "DXManager.h"
using namespace XEngine;
void DXManager::run(Engine *engine)
{
std::cout<<"DXManager::run"<<std::endl;
}
With these 30 lines of code, I'm getting 20 errors like:
'XEngine' : a namespace with this name does not exist
'XEngine' : a symbol with this name already exists and therefore this name cannot be used as a namespace name
syntax error : identifier 'Engine'
Clearly, I'm missing something important here. What am I doing wrong?
note: I am aware that circular dependency is a bad thing, but in my particular case I believe that it is relevant.
In DXManager.cpp you are not just using some names from namespace XEngine. You define the function in that namespace.
So must be:
DXManager.cpp
#include <iostream>
#include "Engine.h"
#include "DXManager.h"
namespace XEngine {
void DXManager::run(Engine *engine)
{
std::cout<<"DXManager::run"<<std::endl;
}
}
AFAIK some of the compilers (like MSVC) process using variant too.
But it is not correct because your syntax tries to define function ::DXManager::run - not ::XEngine::DXManager::run you intend to define.
In the forward-declaration of class Engine the namespace XEngine doesn't exist at this point.
A workaround would be moving the declaration inside the namespace block.
When Engine.h includes DXManager.h, the latter defines a class XEngine::Engine without declaring the namespace first.
My code is stored in a main.cpp file which contains the void main() function, and a class MyClass which I now want to split to another file. IDE is Microsoft Visual Studio 2008 Professional.
myclass.h
#include <tchar.h>
class MyClass {
public:
static bool MyFunction (TCHAR* someStringArgument);
};
myclass.cpp
#include <tchar.h>
class MyClass {
private:
static bool someProperty;
static void doSomeOneTimeCode () {
if (!someProperty) {
/* do something */
someProperty = true;
}
}
public:
static bool MyFunction (TCHAR* someStringArgument) {
doSomeOneTimeCode();
/* do something */
return true;
}
};
bool MyClass::someProperty = false;
main.cpp
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include "myclass.h"
void main () {
if (MyClass::MyFunction(TEXT("myString"))) {
_tprintf(TEXT("Yay\n"));
}
}
However, when I try to run it, I get two linker errors.
LNK2019: unresolved external symbol ... (mentions MyClass::MyFunction)
LNK1120: 1 unresolved externals
What can I do to prevent these linker errors?
You declared two classes here. One of them is in myclass.h and the other is in myclass.cpp. Try the following instead:
myclass.h
#ifndef myclass_h_included
#define myclass_h_included
#include <tchar.h>
class MyClass {
private:
static bool someProperty;
static void doSomeOneTimeCode ();
public:
static bool MyFunction (TCHAR* someStringArgument);
};
#endif //!myclass_h_included
myclass.cpp
#include "myclass.h"
/*static*/ bool MyClass::someProperty = false;
void
MyClass::doSomeOneTimeCode() {
//...
}
bool
MyClass::MyFunction(TCHAR* someStringArgument) {
//...
}
Your main.cpp can stay the same. I would pay attention to UncleBens reply as well. One time initialization code should be hidden if at all possible.
Yo can't split a class definition in parts. It must be defined as a whole in one place. If you want to just have some methods of the class defined create a interface class that the MyClass class will later inherit. You should put the class' definition in a header file (myclass.h) and it's implementation in a cpp file (myclass.cpp). That way you can include the "myclass.h" in your main cpp file and use the class in your main function (which should be int main() or int main( int argc, char *argv[] )).
Strange that you didn't get a compiler error, as you are redefining MyClass.
Definitions (implementations) go into the cpp, and they are defined like this:
#include "myclass.h"
//helper functions, particularly if static, don't need to be in the class
//unnamed namespace means this stuff is available only for this source file
namespace
{
bool someProperty;
void doSomeOneTimeCode () {
if (!someProperty) {
/* do something */
someProperty = true;
}
}
}
bool MyClass::MyFunction (TCHAR* someStringArgument) {
doSomeOneTimeCode();
/* do something */
return true;
}