How to use inheritance and avoid LNK2019 error - c++

What is the correct way to use inheritance among multiple files?
I am new to C++, and I am trying to create a class for all my GDI+ related functions which I'm gonna use in my separate cpp files. I have tried several approaches and to be able to find the problem more easily I got to trying with empty constructor.
I get LNK2019 with this code (I took away parts which are unrelated to the issue, only what is related to WndFuncs class was left):
Header of functions file:
#ifndef WNDFUNCS_H
#define WNDFUNCS_H
class WndFuncs
{
private:
public:
WndFuncs(); //declaration
};
#endif
The file itself:
#include "stdafx.h"
#include <windows.h>
#include <commctrl.h>
#include <winuser.h>
#include <gdiplus.h>
#include "WndFuncs.h"
WndFuncs::WndFuncs() //definition
{
}
The header of class that tries to inherit the class:
#ifndef SEARCHEDITBOX_H
#define SEARCHEDITBOX_H
class SearchEditBox : public WndFuncs
{
private:
WndFuncs b;
SearchEditBox();
public:
~SearchEditBox();
static SearchEditBox* CreateEditBox(HINSTANCE hInst, HWND hwnd, int pos_x, int pos_y, int width, int height, WndCols const* p_wndCols);
#endif
The the class file:
#include "stdafx.h"
#include "WndCols.h"
#include <windows.h>
#include "WndFuncs.h"
#include "SearchEditBox.h"
SearchEditBox::SearchEditBox()
: b()
{
}
SearchEditBox::~SearchEditBox()
{
if (editBox)
DestroyWindow(editBox);
}
SearchEditBox* SearchEditBox::CreateEditBox(HINSTANCE hInst, HWND hwnd, int pos_x, int pos_y, int width, int height, WndCols const* p_wndCols)
{
SearchEditBox *p_SearchEditBox = new SearchEditBox; //allocating dynamic memory for class (which by itself is declared as pointer)
return p_SearchEditBox;
}
The error is:
LNK2019 unresolved external symbol "public: __thiscall
WndFuncs::WndFuncs(void)" (??0WndFuncs##QAE#XZ) referenced in function
"private: __thiscall SearchEditBox::SearchEditBox(void)"
(??0SearchEditBox##AAE#XZ)
I have read the explanation and all the points on the MSDN page (even tried putting "__cdecl" into the function declaration), I am sure the function is declared AND defined (in the class files; I also tried with const int x thinking that the problem may be in empty constructor), so the WndFuncs file should be fine.
I have read this and my assumption is that I declare the class in the wrong way in the inheriting file (and the linker thus can't link to correct functions in WndFuncs class), but even when I am trying to do everything as described in here it does not help either. I am not using any virtual members so the problem should not be related to that (as pointed out on that page).
When I add destructor to the WndFuncs class I get 2 LNK2019 errors, so the problem should not be related to that also. I also have the header files in right order I think (tried both).
I tried also with other function (with or without constructor) with same error.

The problem was solved by adding the class files to the project the correct way: Project > Add class. After that the references were linked correctly.
What I did wrong was adding files to the project separately (through: File > Add > File).

Related

Unresolved External Symbol C++

I have read this informative stackoverflow question regarding unresolved external symbols, but I am still not sure how to solve my issue.
Within Visual Studio 2012, I have a solution consisting of multiple projects, one of which is a static library called common. Each project that produces an executable consists of a header and associated cpp file of all global functions used throughout that specific program, called programglobals. In the process of developing one of these projects, I started duplicating some of this code from one project's programglobals to another. Now that I have completed all the projects, I want to extract the duplicate code into a associated header and cpp file within the common library, but I believe I might be referencing them incorrectly, which is producing these unresolved external symbol errors
Here is a dumbed down example of what I am currently attempting.
Common Library Files
//solutionglobals.h
void commonFunction();
//solutionglobals.cpp
void commonFunction() {
int asdf;
}
Project A Files
// programglobals.h
#include "../common/solutionglobals.h
void functionUsedInProjectA();
// programglobals.cpp
void functionUsedInProjectA() {
int x;
}
// output.h
#include "programglobals.h"
void asdfA();
// output.cpp
void asdfA() {
int x;
functionUsedInProjectA();
commonFunction();
}
Project B Files
// programglobals.h
#include "../common/solutionglobals.h
void functionUsedInProjectB();
// programglobals.cpp
void functionUsedInProjectB() {
int x;
}
// output.h
#include "programglobals.h"
void asdfB();
// output.cpp
void asdfB() {
int x;
functionUsedInProjectB();
commonFunction();
}
Any reference to commonFunction() results in an unresolved external symbol error.
Thanks!
You will have to specify in your executable projects that they reference the static lib. May be http://msdn.microsoft.com/en-us/library/vstudio/ms235627%28v=vs.110%29.aspx#uselibinapp helps (lower third of the article).
Before you can use the math routines in the static library, you must
reference it. To do this, open the shortcut menu for the MyExecRefsLib
project in Solution Explorer, and then choose References. In the
MyExecRefsLib Property Pages dialog box, expand the Common Properties
node, select Framework and References, and then choose the Add New
Reference button.
The linker cannot 'see' your function and as such thinks that it does not have an external symbol referencing it, hence the error.
You must #pragma comment(lib, [library here]) to reference the external function.
The following code can be used to reproduce this error:
[header file- test.h]:
#include "StdAfx.h"
void someOtherFunction();
void someFunction(string thisVar);
[code file- test.cpp]:
#include "StdAfx.h"
#include "test.h"
void someOtherFunction()
{
printf("Hello World!");
}
[function body for someFunction(string thisVar) is missing!]

Trying to create a vector of COORD, causes linking error

my code is:
#pragma once
#include "stdafx.h"
#include <vector>
#include "field.h"
class output
{
void putAtLocation(COORD, char chIcon); //currently this outputs to console
static std::vector<COORD> m_vsOutputBuffer;
public:
output(void);
static void addToken(COORD);
void drawTokens();
~output(void);
};
and the linker error is:
output.obj : error LNK2001: unresolved external symbol "private: static class std::vector<struct _COORD,class std::allocator<struct _COORD> > output::m_vsOutputBuffer" (?m_vsOutputBuffer#output##0V?$vector#U_COORD##V?$allocator#U_COORD###std###std##A)
this must be the problem line:
static std::vector<COORD> m_vsOutputBuffer;
I've been at this for hours stuck. I finally noticed that changing COORD to int causes the linker error to go away. I've read that it's(linker errors) are usually caused by dependency issues. But here it just changing a TYPE. I've also read it can be caused by using a function in a way it wasn't supposed to be. I figure it has to be the way is handling COORDs; or something about COORDS is forward declared, or referenced in output.cpp properly.
Edit:
all changing to int did was make compiler errors that caused it never to hit the linker. now I am back to nothing
and the cpp file:
#include "stdafx.h"
#include "output.h"
#include <vector>
static std::vector<int> m_vsOutputBuffer;
output::output(void)
{
}
void output::addToken(COORD sCoordinate) //mark a coord in the buffer as needing refreshed
{
m_vsOutputBuffer.push_back(sCoordinate);
}
void output::drawTokens() //release the outputbuffer the the output window
{
for (unsigned int iii = 0; iii < m_vsOutputBuffer.size(); iii++)
{
putAtLocation(m_vsOutputBuffer[iii], field::checkHit( m_vsOutputBuffer[iii] ) );
}
}
void output::putAtLocation(COORD sCoordinate, char chIcon) //outputs a single character to the console
{
DWORD dwNumWritten = 0;
LPDWORD lpdNumWritten = &dwNumWritten;
WriteConsoleOutputCharacter(
GetStdHandle( STD_OUTPUT_HANDLE ), //***repeatedly getting this handle may end up a bottleneck
LPCTSTR(&chIcon),
1,
sCoordinate,
lpdNumWritten
);
}
output::~output(void)
{
}
also I found this: http://www.cplusplus.com/forum/general/6111/
so I tried moving the static statement to the cpp file and it compiled and ran. but not its not a member variable. So I Need to somehow forward declare the vector.(before the declaration was also creating the static object in the header file.
you need this line in your .cpp file:
std::vector<COORD> output::m_vsOutputBuffer;
(Note the absence of static and the scope output::)
This is the actual definition of the member variable. What you have in the class (.h) is only the declaration.
Without this the static variable output:m_vsOutputBuffer does not exist and the linker rightfully complains that it can't find it.
Coord is defined in windows.h header... Look into stdafx.h if there is something like
#include <windows.h>.
Other than that I tried to copy your code add this header and compile it.. went smooth
To edited version:
You probably forgot to change
static std::vector<int> m_vsOutputBuffer;
back to
static std::vector<COORD> m_vsOutputBuffer;
But I assume you had it that way before.. Second thing is that you don't have to include the same headers in header and cpp file but this is not causing it.. It is the line in cpp file with
static std::vector<COORD> m_vsOutputBuffer;
change it just to:
std::vector<COORD> output::m_vsOutputBuffer;
You can read on why in this text:
http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr038.htm
Simply said you need do define not just declare.

error C2504: 'BASECLASS' : base class undefined

I checked out a post similar to this but the linkage was different the issue was never resolved. The problem with mine is that for some reason the linker is expecting there to be a definition for the base class, but the base class is just a interface. Below is the error in it's entirety
c:\users\numerical25\desktop\intro todirectx\godfiles\gxrendermanager\gxrendermanager\gxrendermanager\gxdx.h(2) : error C2504: 'GXRenderer' : base class undefined
Below is the code that shows how the headers link with one another
GXRenderManager.h
#ifndef GXRM
#define GXRM
#include <windows.h>
#include "GXRenderer.h"
#include "GXDX.h"
#include "GXGL.h"
enum GXDEVICE {
DIRECTX,
OPENGL
};
class GXRenderManager {
public:
static int Ignite(GXDEVICE);
private:
static GXRenderer *renderDevice;
};
#endif
at the top of GxRenderManager, there is GXRenderer , windows, GXDX, GXGL headers. I am assuming by including them all in this document. they all link to one another as if they were all in the same document. correct me if I am wrong cause that's how a view headers. Moving on...
GXRenderer.h
class GXRenderer {
public:
virtual void Render() = 0;
virtual void StartUp() = 0;
};
GXGL.h
class GXGL: public GXRenderer {
public:
void Render();
void StartUp();
};
GXDX.h
class GXDX: public GXRenderer {
public:
void Render();
void StartUp();
};
GXGL.cpp and GXDX.cpp respectively
#include "GXGL.h"
void GXGL::Render()
{
}
void GXGL::StartUp()
{
}
//...Next document
#include "GXDX.h"
void GXDX::Render()
{
}
void GXDX::StartUp()
{
}
Not sure whats going on. I think its how I am linking the documents, I am not sure.
The problem is You need to have #include "GXRenderer.h" at the top of both: GXGL.h and also GXDX.h.
The base type must be defined not just declared before defining a derived type.
By the way, the error is a compiling error not linking error.
Edit: About your class type redefinition:
at the top of every header file you should have #pragma once.
The #pragma once directive specifies that the file will be included at most once by the compiler in a build.
You included them all into GXRenderManager.h, meaning that GXRenderManager.h is OK.
But you forgot to include them all into GXGL.cpp and GXDX.cpp. In these .cpp files GXRenderer class is completely unknown.
There are at least two "schools" of #include strategies. One says that header file must include everything that is needed for its own compilation. That would mean that GXGL.h and GXDX.h must include GXRenderer.h. If you followed that strategy, your GXGL.cpp and GXDX.cpp would be OK as they are now.
Another "school" says that header files must not include each other at all, i.e. all inclusions must be done through .cpp files. At first sight one could guess that your GXGL.h and GXDX.h follow that strategy (since you are not including anything into them), but then your GXRenderManager.h looks completely different.
You need to decide which strategy you are trying to follow and follow it. I'd recommend the first one.
I got an error C2504: 'CView' : base class undefined
where CView is not directly my base class from which I am inheriting.
I am inherting mYClass from MScrollView, "for this matter any class which is not actual Base Class is what the point is to be noted down here"
but the error is the C2504. When I have included it in the header where this problem is arising, this problem is resolved.
#include "stdafx.h"
where stdafx.h has #include which contains all the basic class defined...hope this answer resolves everyone who are facing this issue.

Base class Undefined WEIRD problem . Need help

My CGameStateLogo which inherit from CGameState:
CGameState.h
#pragma once
#include "GameMain.h"
#include "MyBitmap.h"
class CGameMain;
class CMyBitmap;
class CGameState
{
public:
CMyBitmap* pbmCurrent;
CGameMain* pGM;
int GameStateID;
virtual void MessageEnter () = 0;
virtual void MessageUpdate( int iKey ) = 0;
virtual void MessagePaint( HDC* pDC ) = 0;
void StateHandler ( int msg, HDC* pDC, int key );
public:
CGameState(void);
~CGameState(void);
};
After creating and finding, problem comes from here :
I've created 2 classes: CTest and CGameStateLogo
#pragma once
#include "GameState.h"
class CTest:CGameState
{
public:
CTest(void);
~CTest(void);
};
#pragma once
#include "GameState.h"
class CGameStateLogo:CGameState // Bug at this line
{
public:
CGameStateLogo(void);
~CGameStateLogo(void);
};
Do VS has problem in naming ?
Thanks for reading this :). Things go WEIRD, I'll update my question later. Sorry for wasting your time .
pGameStates.push_back( (CGameState*)gameLogo );
Since CGameStateLogo inherits publically from CGameState, the cast is unneccesary. Upcasts are implicit. Simply write
pGameStates.push_back( gameLogo );
instead.
This does probably not solve your compile troubles, though. As to that, you seem to be mixing up GameState.h and CGameState.h. If that's an actual error in your code, instead of just a copy/paste mistake while writing your question, it could cause this problem.
It could also be that there is some circular dependency problem in your headers. You write
#include "GameState.h"
which should define the GameState class, unless the file has already been included once, but the class definition has not yet been read. This could happen for example in this way:
Some .cpp file includes GameState.h.
GameState.h includes GameMain.h.
GameMain.h includes GameStateLogo.h.
GameStateLogo.h includes GameState.h, but this has already been included, so the include is ignored due to #pragma once.
Generally, such circular dependencies in header files are a thing to avoid.
CGameStateLogo.h is including GameState.h and not CGameState.h. Is it possible you have a file called GameState.h on the include path (and hence you wouldn't get an error about not being able to include GameState.h)?

Why won't my C++ program link when my class has static members?

I have a little class called Stuff that I want to store things in. These things are a list of type int. Throughout my code in whatever classes I use I want to be able to access these things inside the Stuff class.
Main.cpp:
#include "Stuff.h"
int main()
{
Stuff::things.push_back(123);
return 0;
}
Stuff.h:
#include <list>
class Stuff
{
public:
static list<int> things;
};
but I get some build errors with this code:
error LNK2001: unresolved external symbol "public: static class std::list<int,class std::allocator<int> > Stuff::things" (?things#Stuff##2V?$list#HV?$allocator#H#std###std##A) Main.obj CSandbox
fatal error LNK1120: 1 unresolved externals C:\Stuff\Projects\CSandbox\Debug\CSandbox.exe CSandbox
I am a C# guy, and I am trying to learn C++ for a side project. I think that I don't understand how C++ treats static members. So please explain what I have got wrong here.
Mentioning a static member in a class declaration is a declaration only. You must include one definition of the static member for the linker to hook everything up properly. Normally you would include something like the following in a Stuff.cpp file:
#include "Stuff.h"
list<int> Stuff::things;
Be sure to include Stuff.cpp in your program along with Main.cpp.
Static data members have to be defined outside class declarations, much like methods.
For example:
class X {
public:
static int i;
};
Must also have the following:
int X::i = 0; // definition outside class declaration
Stuff::things is only declared, but it is not defined.
please use:
// Stuff.cpp
#include "Stuff.h"
std::list<int> Stuff::things;
Added: it is also a good practice to protect your header files against multiple inclusion:
// Stuff.h
#ifndef STUFF_H_
#define STUFF_H_
#include <list>
class Stuff {
public:
static std::list<int> things;
};
#endif
Just For your Information, why this works is that in C++ all global variables (including static global) are created before the execution of the main function begins.
Static member have to be declared in the class but defined in the unit (cpp file) where it is really located.
The only exception is in case the class is template: in this case you have to define the member outside the class, but you have to provide it too with the class declaration, in the header file.