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.
Related
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.
I have created a class in a header file and have listed a int rsvdtickets in the private section of the class. When trying to use this member in a function in the same header file (I am trying to add ticket prices so I am wanting to save the total under this int rsvdtickets), the compiler throws an undeclared identifier error.
I've made sure the spelling is all correct, but I am not sure how to fix this problem.
#include <iostream>
#include <math.h>
class tickets
{
public:
void getheldtickets();
void computeseats();
void availabetickets();
private:
int rsvdtickets;
int availtickets;
};
void getheldtickets()
{
int seasontkt;
int corptkt;
std::cout << "How many season ticket holders?";
std::cin >> seasontkt;
std::cout << "How many reserved corporate ticket holders?";
std::cin >> corptkt;
rsvdtickets = seasontkt + corptkt;
}
The problem is that when you have:
void getheldtickets()
{
// ..
rsvdtickets = seasontkt + corptkt;
}
You're not defining tickets::getheldtickets, you're actually declaring and defining an entirely unrelated free function called getheldtickets. That function is unrelated to the class tickets, and thus has no access to the tickets members - and so rsvdtickets is an declared identifier.
The correct way to define a class method external to the class is:
void tickets::getheldtickets()
// ^^^^^^^^^
{
// everything as before
}
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
I created a new WIN32 C++ project. I didn't touch any of the code in the main file yet, and started to write my code in a different file objectsFW.cpp the definitions for the file are located in the file objectsFW.h.
objFW.h looks like:
#pragma once
double g;
typedef struct {
double x;
double y;
}Vector;
typedef struct {
//...
}BoundingBox;
typedef struct {
//...
}Ball;
Vector operator + (Vector a, Vector b) {
//...
}
Vector operator - (Vector a, Vector b) {
//...
}
There are some more operators defined, and the declarations of the functions.
I included the header file in the source file (objectsFW.cpp), and also, added it to the Resources.h file, so that my code will be useable in the main program.
I get linker errors:
Error 1 error LNK2005: "struct Vector __cdecl operator*(struct Vector,double)" (??D#YA?AUVector##U0#N#Z) already defined in ObjectsFW.obj C:\testC\ObjectsCollision\ObjectsCollision\ObjectsCollision.obj ObjectsCollision
...
Error 4 error LNK2005: "struct Vector __cdecl operator+(struct Vector,struct Vector)" (??H#YA?AUVector##U0#0#Z) already defined in ObjectsFW.obj C:\testC\ObjectsCollision\ObjectsCollision\ObjectsCollision.obj ObjectsCollision
and so on.
I know that this happens because the #include "objectFW.h" line appears two times (once in each .cpp file). The question is what is the right way to declare the header file to avoid linker errors?
UPDATE:
After turning the operator functions to inline most of the errors fixed, there is still a program with the line:
double g;
the error is:
Error 1 error LNK2005: "double g" (?g##3NA) already defined in ObjectsCollision.obj C:\testC\ObjectsCollision\ObjectsCollision\ObjectsFW.obj ObjectsCollision
(working on Visual Studio 2012)
About global variables:
1. Refrain from using them. Think encapsulation and data hiding.
2. If you must use them, define the global in 1 source file and place the "extern" in a header file.
Example:
header_file.hpp:
extern unsigned int deadly_global;
source_file.cpp:
unsigned int deadly_global;
Better method for hiding global variables
A better method for controlling (hiding) global variables is to place all the code that uses the variable in the same source file and declare the variable as static:
static unsigned int variable_shared_by_many_functions = 0;
void f1(void)
{
variable_shared_by_many_functions = 42U;
}
void f2(void)
{
std::cout << "Value of shared variable: "
<< variable_shared_by_many_functions
<< "\n";
}
Controlling Global Variables Using Getters and Setters
If you must share the variable among functions in more than one source file, a safer technique is to declare the variable as static in one source file and declare functions (interfaces) to access it.
static int dangerous_variable = 0;
int accessor(void)
{
// Return a copy of the varible.
return dangerous_variable;
}
void setter(int new_value)
{
if ((new_value / 5) != 1)
{
dangerous_variable = new_value;
}
}
This technique allows you to place filters or other controls on setting the variable.
Put in your header:
extern double g;
And in a .cpp:
double g;
That way every file that includes the header will know that there is a variable g, but it will only be declared at one place.
This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
C++: Easiest way to access main variable from function?
I need to get my variable "input" from my main function in a.cpp to another function named check in b.cpp. I looked into it on Google and this forum/thingy, and I found you could do it with global variables using extern, but that's it's also bad to use those and I couldn't find an answer to what an alternative is? How should I transfer the data in the variable to the other function without using globals?
Code of how I got arguments to work.
(What I'm trying to do here is a console "manager" for solutions of project Euler which I can call to solve/view via input, I started working on the code 40 mins ago.)
main.cpp
#include <iostream>
#include <windows.h>
#include "prob.h"
using namespace std;
int check(string x);
int main()
{
string input = "empty";
clear();
cout << "Welcome to the Apeture Labs Project Euler Console! (ALPEC)" << endl << endl;
cout << "We remind you that ALPEC will never threaten to stab you" << endl;
cout << "and, in fact, cannot speak. In the event that ALPEC does speak, " << endl;
cout << "we urge you to disregard its advice." << endl << endl;
cin >> input;
cin.get();
check(input);
cout << input << endl;
cin.get();
return 0;
}
prob.h
#ifndef PROB_H_INCLUDED
#define PROB_H_INCLUDED
int main();
int clear();
int check();
int back();
int P1();
int P2();
int P3();
int P4();
#endif // PROB_H_INCLUDED
back.cpp
#include <iostream>
#include <windows.h>
#include "prob.h"
using namespace std;
int clear()
{
system( "#echo off" );
system( "color 09" );
system( "cls" );
return 0;
}
int check( string x )
{
if( x == "help" );
if( x == "empty" )
{
cout << "And.... You didn't enter anything..." << endl << endl;
}
else
{
cout << "Do you have any clue what you are doing? " << endl << endl;
}
return 0;
}
By passing the data as an function argument.
For example:
int doSomething(int passedVar)
{
}
int main()
{
int i = 10;
doSomething(i);
return 0;
}
Note that the function definition may reside even in a different cpp file. The main only needs to see the function declaration, and the linker shall link the function definition correctly.
Usually, one would add the function declaration in a header file and include the header file in main, while providing the function definition in another cpp file.
The code you show has number of problems:
You do not need to declare main in the header file.
Your function declaration and definition of check() do not match. Your header file says it takes no argument and you define a the function definition to take one argument. Obviously, they don't match. As they stand now they are two completely different functions.
As the compiler sees it you declared one function who's definition you never provided and you defined another function in the cpp file. Thus the function declared(one with no parameters) was never defined and hence the definition not found error.
Andrei Tita is absolutely correct. If you have a "value" in one module (e.g. "main()" in a.cpp), and you wish to use that value in a function (e.g. "foo()" in b.cpp) ... then just pass that value as a function argument!
As your programs become more sophisticated, you'll probably start using classes (instead of functions) .