using functions of another cpp file [duplicate] - c++

This question already has answers here:
One or more multiply defined symbols found
(9 answers)
Closed 8 years ago.
I have a main.cpp file which contains the following:
#include<iostream>
using namespace std;
#include"Command.cpp"
#define EXIT 5
int main(){
int code;
do{
code = getCommand();
doCommand(code);
}while(code != EXIT);
}
and in my Command.cpp file, I have some functions:
#include<iostream>
using namespace std;
#include"Service.h"
Service * first = new Service();
int getCommand(){
cout<<"Choose one of the following commands: "<<endl;
cout<<"1. Add new service"<<endl;
cout<<"2. Add new subservice"<<endl;
cout<<"3. Add parent to a service"<<endl;
cout<<"4. Delete a service(and it's subservices)"<<endl;
cout<<"Your Choice: ";
int c;
cin>>c;
return c;
}
void addService(){
first->add();
}
void addSubService(){
cout<<"Let's choose the parent first: "<<endl;
int * one = new int;
*one = 1;
first->print(one,0);
cout<<"0. here."<<endl<<"> ";
int id;
cin>>id;
Service * f = first->find(one,id);
}
void addParentToService(){
}
void doCommand(int c){
switch(c){
case 1:
addService();
break;
case 2:
addSubService();
break;
case 3:
addParentToService();
break;
case 4:
//deleteService();
break;
}
}
But when I hit the compile button in Visual Studio, I get the following error:
1>Command.obj : error LNK2005: "void __cdecl addParentToService(void)" (?addParentToService##YAXXZ) already defined in Source.obj
1>Command.obj : error LNK2005: "void __cdecl addService(void)" (?addService##YAXXZ) already defined in Source.obj
1>Command.obj : error LNK2005: "void __cdecl addSubService(void)" (?addSubService##YAXXZ) already defined in Source.obj
...
I believe the problem is in the linking of these files but I don't know what to do...

You should never include cpp files into other cpp files. This is where using a .h file comes in. You can refer to this SO question on how to do that:
Using multiple .cpp files in c++ program?
Essentially, the problem you are encountering is that you are including your Command.cpp file multiple times. The preprocessor takes a the contents of a file, and directly copies it into the file it is included in, and that means that you might end up having multiple definitions of the same object if your files are not guarded from being re included. (This is also where include guards come into play).
This is an overall large topic to cover, and there are many resources that talk about this.

When you want to link functions across different files, you should never include .cpp files within another .cpp file. You only include .hh files, where you define any other functions, which are implemented across other .cpp files.
Example: main.cpp
#include "42.hh"
#include <iostream>
int main() {
func42();
return 0;
}
Include file: 42.hh
#ifndef _42_HH_
#define _42_HH_
void func42();
#endif
Function file: 42.cpp
#include <iostream>
void func42() {
std::cout << "Fourty-two" << std::endl;
}
Compile and run:
~$ g++ 42.cpp main.cpp -o fourty-two
~$ ./fourty-two
Fourty-two

Related

Error LNK2001: unresolved external symbol when trying to use source and header files from another directory than the default in Visual Studio 2015 [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 4 years ago.
I have the stdafx.h file and a source (test.cpp) file in the default directory (C:\Users\Roland\Desktop\projects\test\test) together with a header (header.h) and a source (source.cpp) file in an other directory (C:\Users\Roland\Desktop\projects\add) than the default one. The content of these files is the following:
stdafx.h: empty
test.cpp:
#include "stdafx.h"
#include <header.h>
int main()
{
int a = 2;
int b = 3;
swap(a, b);
return 0;
}
header.h:
#ifndef _HEADER_H_
#define _HEADER_H_
void swap(int &a, int &b);
#endif
source.cpp:
void swap(int &a, int &b)
{
int c;
c = a;
a = b;
b = c;
}
I added the following path to the "Additional Include Directory" record: ../../add. When trying to build the solution, I received an error:
error LNK2001: unresolved external symbol "void __cdecl swap(int &,int &)" (?swap##YAXAAH0#Z)
Could you please help me what would be the problem?
update:
I need a solution to making all the source files of the add directory available for my project.
If you have added source.cpp to your project, add source.h and put the swap function prototype in there. In your main function, include source.h and you should be fine.

Program keeps on giving such LNK errors

header.h
#include <iostream>
#include <vector>
#include <ctime>
#include <string>
using namespace std;
//vector <Account> bankAccounts; this is taken out.
extern vector <Account> bankAccounts; //edited
struct Account {
int accountNumber;
string lastName;
string firstName;
double accountbalance;
};
void menu(int*);
void makeAccount(vector <Account>&);
cpp
#include "Header.h"
void menu(int*);
void makeAccount(vector <Account>&);
vector <Account> bankAccounts; //edited
int main() {
int input = 0;
int *inputPtr = &input;
menu(inputPtr);
switch (input) {
case 1:
makeAccount(bankAccounts);
}
}
another cpp
#include "Header.h"
vector <Account> bankAccounts; edited;
void menu(int *inputPtr) {
int select = 0;
cout << "Welcome to MadeUp Banking. Select options below: \n";
cout << "\t 1. Make new account. \n";
cout << "\t 2. Display to an account. \n";
cout << "\t 3. Deposit to an account. \n";
cout << "\t 4. Withdraw from an account. \n";
cout << "\t 5. Print account. \n";
cout << "\t 6. Delete an account. \n";
cout << "\t 7. Quit. \n";
cout << "Selection: ";
cin >> select;
*inputPtr = select;
}
void makeAccount(vector <Account> bankAccounts) {
//edited vector <Account> bankAccounts within makeAccount()
return;
}
When program is ran, the error gives:
main_file.obj : error LNK2005: "class std::vector > bankAccounts" (?bankAccounts##3V?$vector#UAccount##V?$allocator#UAccount###std###std##A) already defined in function_file.obj
1>main_file.obj : error LNK2019: unresolved external symbol "void __cdecl makeAccount(class std::vector > &)" (?makeAccount##YAXAAV?$vector#UAccount##V?$allocator#UAccount###std###std###Z) referenced in function _main
How do I go about fixing this error?
Sorry I'm a rookie coder, if more details are needed, then please tell me and I will edit accordingly. Thank you for the help in advance.
1. bankAccounts already defined in function_file.obj.
You should define bankAccounts in your cpp file. Because if you define it in header file, when you include your header in multiple cpp files, there would be multiple definition of backAccounts.
If you needs it in multiple cpp files, use extern to declare(not define) it in your header file:
extern vector <Account> bankAccounts;
And in one of your cpp file, define it as:
vector <Account> bankAccounts;
2. unresolved external symbol void makeAccount()
Definition of makeAccount() should be like:
void makeAccount(vector <Account>&)
{
// do something
}
While you are defining it as void makeAccount(vector<Account>). Please notice the difference. In your declaration, parameter is reference to a vector, while in your definition, parameter is vector object.
The error message of the first error, which can be abridged to:
main_file.obj : error LNK2005: std::vector<Account> bankAccounts already defined in function_file.obj
The reason for this error is that included files are copy-pasted in place of #include. That way, the std::vector<Account> bankAccounts is defined in both files (and they are, completely separate objects!), so the linker complains because of the multiple-definitions.
To solve this, in the header file, declare the global variable as extern std::vector<Account> bankAccounts, and then define it, in one of the .cpp files as std::vector<Account> bankAccounts. extern, only declares that there will be such a variable defined, at some point, and since you will be defining a global variable once, the linker won't see multiple definitions of said variable.
The second error is just like it sounds: you declared (and tried to call a function with signature void makeAccount(vector <Account>&);, however, you defined a function with signature void makeAccount();, leaving the function void makeAccount(vector <Account>&); undefined. Fix the definition of a function to include the parameter, present in its declarations:
void makeAccount(vector <Account>&) {
return;
}
Unrelated to your issues, but I felt that I should mention several more things:
Don't use using namespace std;, especially in the header files, it is considered a bad practice.
How is your code even reaching the linker stage? It shouldn't even compile, because Account is declared after the void makeAccount(vector <Account>&);, and at the point of such function declaration - struct Account is not known to the compiler.

Visual Studio doesn't accept class implementation [C++]

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.

error LNK2005: "int __cdecl number(void)" (?number##YAHXZ) already defined in functions.obj

I think I am having a similar problem to LNK2005, LNK1169 errors, "int __cdecl g(void)" (?g##YAHXZ) already defined but I cannot find the issue.
I am working with Visual Basic and I am having the following files
main.cpp
#include <iostream>
#include "functions.h"
using namespace std;
int main(){
number();
return 0;
}
I had a functions.cpp but after reading the question I linked before I renamed it for functions.h
int number(){
int i = 1;
return i;
}
Now it is displaying error LNK2005: "int __cdecl number(void)" (?number##YAHXZ) already defined in functions.obj
Is there anything wrong with the function number() in functions.h?
You are having linking issues.
Your immediate issue is that the functions.obj contains code that is being linked in. Then you redefine number() in main.cpp so they collide. Go ahead and clean the project (which should delete functions.obj, and you should be able to compile. I, however, recommend doing it this way.
functions.hpp (or functions.h)
int number();
functions.cpp
int number(){
int i = 1;
return i;
}
main.cpp
#include <iostream>
#include "functions.h"
using namespace std;
int main(){
number();
return 0;
}
When you compile, your program will create 2 objects with compiled code functions.obj, and main.obj. Since you use number in the main file, the compiler looks for the implementation of that function. Since the implementation of that function is in the functions.obj object, then you need to link that in.
If you are going to use number() across several C++ files, then you should always separate the code out into its own file and implementation.
functions.h should only declare the functio, as in
int number();
then functions.cpp should contain the function definition
int number(){
int i = 1;
return i;
}
Of course functions.cpp needs to be compiled (add it to the project).
The problem here is that you are including functions.h in multiple files. The issue could be avoided also by simply declaring the function static as in
static int number(){
int i = 1;
return i;
}
However, since it seems you are just learning, I would suggest you to study the basics of compiling c++ code.
In one of the modules you link in there is a function with the name number(). You define you own implementation so the linker does not know which one to use.
Either rename your function or use namespaces.

C++ Cannot instantiate a class from another file in main.cpp

I cannot get this to work
Addr.h
#ifndef ADDR_H
#define ADDR_H
class Foo{
public:
Foo(); // function called the default constructor
Foo( int a, int b ); // function called the overloaded constructor
int Manipulate( int g, int h );
private:
int x;
int y;
};
#endif
Addr.cpp
#include "addr.h"
Foo::Foo(){
x = 5;
y = 10;
}
Foo::Foo( int a, int b ){
x = a;
y = b;
}
int Foo::Manipulate( int g, int h ){
return x = h + g*x;
}
main.cpp
#include "addr.cpp"
int main(){
Foo myTest = Foo( 20, 45 );
while(1){}
return 0;
}
What am i doing wrong? I get these linker errors:
error LNK2005: "public: int __thiscall Foo::Manipulate(int,int)" (?Manipulate#Foo##QAEHHH#Z) already defined in addr.obj c:\Users\christian\documents\visual studio 2010\Projects\Console Test\Console Test\main.obj
error LNK2005: "public: __thiscall Foo::Foo(int,int)" (??0Foo##QAE#HH#Z) already defined in addr.obj c:\Users\christian\documents\visual studio 2010\Projects\Console Test\Console Test\main.obj
error LNK2005: "public: __thiscall Foo::Foo(void)" (??0Foo##QAE#XZ) already defined in addr.obj c:\Users\christian\documents\visual studio 2010\Projects\Console Test\Console Test\main.obj
error LNK1169: one or more multiply defined symbols found c:\users\christian\documents\visual studio 2010\Projects\Console Test\Release\Console Test.exe
I would appreciate any kind of help!!!
#include "addr.cpp"
You're including the .cpp file to your main.cpp, which is what causing the problem. You should include the header file instead, as:
#include "addr.h" //add this instead, to your main.cpp
Because its the header file which is containing the definition of the class Foo.
In main.cpp, you should include the header file, rather than the cpp file.
Change
#include "addr.cpp"
To
#include "addr.h"
In main.cpp
#include "addr.cpp"
should be
#include "addr.h"
If you #include "addr.cpp", you can compile main.cpp (and even link it into an executable on it's own), but when you link main.obj and add.obj, you get a duplicate definition error, because class Foo is now fully defined in both object files.
You can either #include "addr.h" (as already stated), or make the build system not compile addr.cpp. The former is usually preferred, though the latter would also solve the trouble and is often used with automatic code generation tools' output.
There are two ways of getting the class data into main.cpp
1) include the header file "addr.h" in the main.cpp file, so now you have the class and member functions' definitions, but don't have the implementation part of them. So while compiling, the code should be :
g++ addr.cpp main.cpp.
2) include the cpp file "addr.cpp" in the main.cpp, so you automatically have the definitions also as "addr.h" is included in "addr.cpp". Now you must compile only the main.cpp file: g++ main.cpp.
First method is standard and is a good programming practice for maintaining modularity and encapsulation...