I'm trying to move from Dev C++ to Visual Studio while studying C++ (since I'll have to work with the latter) but for some reason, a rather simple class implementation that perfectly works in Dev C++ creates a long list of errors in Visual Studio.
The files are simple:
header file, for the declaration of constructors, variables etc
cpp file, to implement said constructors, functions etc
consoleapplication file (on visual studio), to produce the "main()" function.
stock2.h
#ifndef STOCK2_H_
#define STOCK2_H_
class Stock
{
public:
Stock();
Stock(const char* co, int n = 0, double pr = 0.0);
~Stock();
void show()const;
private:
std::string company;
int shares;
double share_val;
double total_val;
};
#endif
stock2.cpp
#include "stdafx.h"
#include <iostream>
#include <string>
#include "stock2.h"
Stock::Stock() //default constructor
{
//code
}
Stock::Stock(const char* co, int n, double pr)
{
//code
}
Stock::~Stock()
{
std::cout << "Stock object has been destroyed" << std::endl;
}
//Methods
void Stock::show() const
{
//code
}
ConsoleApplication.cpp
#include "stdafx.h"
#include "stock2.cpp"
int main()
{
using std::cout;
const int STKS = 4;
Stock stocks[STKS] = {
Stock("NanoSmart", 12, 20.1),
Stock("Boffo Objects", 200, 2.0),
Stock(),
Stock("Monolithic Obelisks", 130, 3.25)
};
cout << "Stock Holdings: \n";
for (int st = 0; st<STKS; st++)
stocks[st].show();
return 0;
}
I've tried to find the solution on other questions posted here but I really can't figure out what's wrong here.
I also read that one is not supposed to #include a cpp file since the header should be the link between the main() and the cpp file itself, but if I decide to use #include stock2.H instead of .CPP in consoleapplication, then the compiler can't find the methods implementations anymore.
EDIT: In the rush i forgot to post the errors!
They're all in this form:
Error LNK2005
"public: void __thiscall Stock::update(double)" (?update#Stock##QAEXN#Z) already defined in
ConsoleApplication1.obj ConsoleApplication1 //path\ConsoleApplication1\ConsoleApplication1\stock2.obj
EDIT2: Since many of you are asking me about the "Solution Explorer", I better just add a screenshot to show you how it's made right now
You included stock2.cpp in your ConsoleApplication.cpp. This means all the code inside stock2.cpp is now compiled twice, and the linker shows the error message
Error LNK2005 "public: void __thiscall Stock::<...> already defined
for the now duplicated functions. Simply replace
#include "stock2.cpp"
with
#include "stock2.h"
If you get another error when doing so, please post the error message for this.
Related
I encountered this problem when I try to compile my code
I thought it might be caused by header files including each other. But as far as I can tell I did not find any issues with my header files
Error LNK1169 one or more multiply defined symbols
found Homework2 D:\05Development\04 C_C++\C\DS Alg
class\Homework2\Debug\Homework2.exe 1
also, there's an error telling me that function Assert() has been declared elsewhere.
Error LNK2005 "void __cdecl Assert(bool,class
std::basic_string,class
std::allocator >)"
(?Assert##YAX_NV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z)
already defined in DataBase.obj Homework2 D:\05Development\04
C_C++\C\DS Alg class\Homework2\Homework2\dbTest.obj 1
here's the structure of my code:
function
void Assert(bool val, string s)
{
if (!val)
{
cout << "Assertion Failed!!: " << s << endl;
exit(-1);
}
}
is in Constants.h
A virtual class List includes Constants.h
#pragma once // List.h
#include "Constants.h"
An array list includes List class, in the AList class it calls the Assert function
#pragma once //AList.h
#include "List.h"
...
Assert((pos >= 0) && (pos < listSize), "Position out of range");
In the DataBase class I created a AList member
private:
AList<CData> set;
header looks like this:
#pragma once
#include "AList.h"
#include "CData.h"
and CData.h looks like this:
#pragma once
class CData
{
private:
std::string m_name;
int m_x;
int m_y;
public:
CData(std::string str = "null", int x = 0, int y = 0) : m_name(str), m_x(x), m_y(y) {}
// Helper functions
const std::string& GetName() const { return this->m_name; }
const int& GetX() const { return this->m_x; }
const int& GetY() const { return this->m_y; }
};
When you build your project, each .cpp file gets compiled separately into different object files. The once in #pragma once only applies to the compilation of a single .cpp file, not for the project as a whole. Thus if a .cpp file includes header A and header B, and header B also includes header A, then the second include of header A will be skipped.
However, if you have another .cpp file that includes A, A will be included in that object file again -- because #pragma once only works when compiling a single .cpp file.
An #include statement literally takes the content of the included file and "pastes" it into the file that included it. You can try this by looking at the output of the C preprocessor tool (cpp in the gcc toolchain). If you are using the gcc toolchain, you can try something like this to see the file after its includes have been applied:
cpp file.cpp -o file_with_includes.cpp
If you have a function in your header, like Assert in your example, the function gets replicated into each .cpp file you include it in.
If you have A.cpp and B.cpp, that both include your Constants.h file, each object file (.o or .obj depending on your environment) will include a copy of your Assert function. When the linker combines the object files to create a binary, both object files will declare that they provide the definition for Assert, and the linker will complain, because it doesn't know which one to use.
The solution here is either to inline your Assert function, like this:
inline void Assert(bool val, string s)
{
if (!val)
{
cout << "Assertion Failed!!: " << s << endl;
exit(-1);
}
}
or to provide its body in its own .cpp file, leaving only the function prototype in the header.
Constants.h:
void Assert(bool val, string s);
Constants.cpp:
void Assert(bool val, string s)
{
if (!val)
{
cout << "Assertion Failed!!: " << s << endl;
exit(-1);
}
}
Mind you, the Standard Library also offers assert(), which works nicely too. (see https://en.cppreference.com/w/cpp/error/assert).
#include <cassert>
...
assert(is_my_condition_true());
assert(my_variable > 23);
// etc..
Just keep in mind that the assert declared in cassert only works when compiling for Debug, and gets compiled out when building for Release (to speed up execution), so don't put any code in assert that has side effects.
#include <cassert>
...
// Don't call functions with side effects.
// Thus function decreases a "count" and returns the new value
// In Release builds, this line will disappear and the decrement
// won't occur.
assert(myclass.decrement_count() > 0);
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).
I work with an application that appears (just started a few weeks ago, so I am still learning the older apps) to be built in C and my company wants to use that program's ability to make a call to an outside DLL to extend some new functionality. To do this, I started working on my POC, which is the first two files below. The only specification we were given was that the dll has to export the following function:
extern int __stdcall TestMethod_LoadCustomer(const char * name, char * id);
I tried to implement that as follows:
TestDLL.h
#define TestDLL_API __declspec(dllexport)
namespace TestDLL
{
class TestDLL
{
public:
static TestDLL_API int TestMethod_LoadCustomer(const char* name, char* id);
};
}
TestDLL.cpp
// TestDLL.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
#include "TestDLL.h"
#include <string.h>
extern "C" int __declspec(dllexport) __stdcall TestMethod_LoadCustomer(const char* name, char* id)
{
if (strlen(name) <= 8) {
strcpy(id, name); // name contains customer id
} else {
id[0] = 0; // Customer not found
}
return 0;
}
These two files compile fine. The problem comes in when I try to test this dll via a separate little console app shown here:
RunTEST.cpp
// RunTest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include "TestDLL.h"
using namespace std;
int _tmain()
{
char* id= "";
TestDLL::TestDLL::TestMethod_LoadCustomer("77777", id);
cout << id;
cin >> id;
return 0;
}
All I am looking for is to be able to pass in a character string into the call TestMethod_LoadCustomer() and have it be added to the id field.
When I actually try to build this solution, I get the following error:
"error LNK2019: unresolved external symbol "public: static int __cdecl TestDLL::TestDLL::TestMethod_LoadCustomer(char const *, char *)" (?TestMethod_LoadCustomer#TestDLL#1#SAHPBDAD#Z) referenced in function _wmain"
I am assuming it has something to do with the way I am trying to reference it in my client app, but I am not sure. I have looked at other LNK2019 errors on StackOverflow, but none of those solutions seemed to work here, of I have incorrectly implemented them. Can any one assist in helping me get rid of this error message?
On the TestDLL.cpp file is missing two things:
1) The namespace TestDLL.
2) the TestDLL:: before the method name.
// TestDLL.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
#include "TestDLL.h"
#include <string.h>
namespace TestDLL {
extern "C" int __declspec(dllexport) __stdcall TestDLL::TestMethod_LoadCustomer(const char* name, char* id)
{
if (strlen(name) <= 8) {
strcpy(id, name); // name contains customer id
} else {
id[0] = 0; // Customer not found
}
return 0;
}
}
While defining the function in TestDLL.cpp you didn't mention that the function is member of the class TestDLL.
I am trying to run a main.cpp which access 3 different classes. For some reason, I am getting a unresolved external symbol error. From what I've seen online, its clearly a linking error somewhere, but I cannot find it. I've listed the error below, but it's got a lot of info in it and im having trouble finding out exactly what it means.
The error: main.obj:-1: error: LNK2001: unresolved external symbol "public: __thiscall AtpReader::AtpReader(class std::basic_string,class std::allocator >)" (??0AtpReader##QAE#V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z)
My code is:
main.cpp:
#include <iostream>
#include "atlasobject.h"
#include "atp.h"
#include "atpreader.h"
using namespace std;
int main()
{
AtpReader reader("E:/doc.txt");
return 0;
}
AtpReader.h:
#ifndef ATPREADER_H
#define ATPREADER_H
#include "atp.h"
class AtpReader
{
public:
AtpReader();
AtpReader(string filename);
void atpReadHeader();
void atpRead();
string decryptLine(string line);
ATP readerATP;
private:
string file;
};
#endif // ATPREADER_H
atp.h:
#ifndef ATP_H
#define ATP_H
#include "atlasobject.h"
#include "vector"
struct Image{
string Dim;
string Vox;
string Ori;
char* data;
};
class ATP
{
public:
ATP();
vector<AtlasObject> listOfMaps;
private:
Image referenceImage;
};
#endif // ATP_H
and AtlasObject.h:
#ifndef ATLASOBJECT_H
#define ATLASOBJECT_H
#include <string>
using namespace std;
class AtlasObject{
public:
//virtual void create();
AtlasObject();
void set_uid(string id);
void set_label(string l);
void set_offset(string o);
void set_mapInfo(string info);
void set_data(char* inData);
void set_isEncrypted(int encrypted);
string get_uid();
string get_label();
string get_offset();
string get_mapInfo();
char* get_data();
int get_isEncrypted();
protected:
string uid;
string label;
string offset;
string mapInfo;
char *data;
int isEncrypted;
};
#endif // ATLASOBJECT_H
my AtpReader.cpp is:
#include "atpreader.h"
#include <iostream>
#include <fstream>
#include <stdint.h>
#include <sstream>
AtpReader::AtpReader()
{
printf("AtpReader()\n");
}
AtpReader::AtpReader(string filename)
{
printf("AtpReader(%s)\n",filename.c_str());
}
I see you did not include AtpReader.h in AtpReader.cpp, but probably you just missed it when you made copy/paste, to insert it here, because if you didn't really include it, the error would have been different. Also, I see you're including in your main.cpp both "atlasobject.h"
and "atp.h" and you don't really need that.
Later edit: Your problem is in the atp.h...you constructor is declared but never defined. Do this: ATP(){};
Try using g++ in linux terminal
make the object files of each of the source codes and then link the object files and run the executable
g++ -c atp.cpp AtpReader.cpp AtlasObject.cpp
g++ -o exe atp.o AtpReader.o AtlasObject.o
./exe
AtpReader.cpp is not getting built or the its object file is not getting linked to final executable. Check if AtpReader.obj/.o is created in build directory.
Because of the linker error you are getting and assuming that this is some of your actual code. Since I can't see any function inlining, global constants or variables being used out of scope I think the problem is located in the AtpReader.cpp, are you missing an #include AtpReader.h there?
With just a function prototype, the compiler can continue without error, but the linker cannot resolve a call to an address because there is no function code or variable space reserved. You will not see this error until you create a call to the function that the linker must resolve.
My code will be similar to the below code:
class DMLGroup
{
public:
DMLGroup();
~DMLGroup();
void SetName(string name);
private:
string mName;
};
void DMLGroup::SetName(string nm){
mName.assign( nm );
}
int main()
{
string api="API_DML";
DMLGroup * dmlGr = new DMLGroup();
dmlGr->SetName(api.c_str()); //Getting link error with this statement
}
I could able to compile the above code but failed to link using MS visual studio 9 on windows 7 32-bit OS.
Note: I am able to compile, link and run successfully on suselinux-x8664 platform. The problem is only with windows
Please tell me how to resolve this?
The following code compiles & links fine:
#include "stdafx.h"
#include <string>
class DMLGroup
{
public:
DMLGroup() {}
~DMLGroup(){}
void SetName(std::string name);
private:
std::string mName;
};
void DMLGroup::SetName(std::string nm){
mName.assign( nm );
}
int main()
{
std::string api="API_DML";
DMLGroup * dmlGr = new DMLGroup();
dmlGr->SetName(api.c_str()); //Getting link error with this statement
}
What I changed:
#included stdafx.h because it's VS standard - you can turn it off
#includes because it was missing
decorated every use of string with std:: - because most probably you'll use your class definition in a header file and there you simply don't use "using namespace"
supplied default implementation for constructor & destructor
That's all. Check what from the above part is missing or supply an example that exposes the problem & supply the linker error message.