I am trying to practice object oriented programming structure in c++. I have written some piece of code. But I got an undefined reference error.
I've tried to build with clion ide but it gave me error. I've tried to compile it on linux terminal using g++ command but it gave me same error.
Account.h
#ifndef ACCOUNT_H
#define ACCOUNT_H
class Account
{
public:
Account ();
Account(double init_balance);
double getBalance();
void deposit(double amt);
void withdraw(double amt);
private:
double balance;
};
#endif // ACCOUNT_H
Account.cpp
#include "Account.h"
#include <iostream>
using namespace std;
Account::Account(double init_balance)
:balance(init_balance)
{
}
double Account::getBalance(){
return balance;
}
void Account::deposit(double amt){
balance += amt;
}
void Account::withdraw(double amt){
balance -= amt;
}
Customer.h
#ifndef CUSTOMER_H
#define CUSTOMER_H
#include "Account.h"
#include <iostream>
#include <string>
using namespace std;
class Customer
{
public:
Customer(string first_Name, string last_Name) :
firstName(first_Name), lastName(last_Name)
{
}
//Customer(string first_Name, string last_Name);
string getFirstName();
string getLastName();
Account getAccount();
void setAccount(Account acc);
private:
string firstName;
string lastName;
Account account;
};
#endif // CUSTOMER_H
Customer.cpp
#include "Customer.h"
#include <iostream>
#include <string>
using namespace std;
string Customer::getFirstName(){
return firstName;
}
string Customer::getLastName(){
return lastName;
}
Account Customer::getAccount(){
return account;
}
void Customer::setAccount(Account acc)
{
account = acc;
}
main.cpp
#include "Account.h"
#include "Customer.h"
#include <iostream>
using namespace std;
int main(int argc, char** argv) {
Customer *customer;
Account account(0.0);
// Create an account that can has a 500.00 balance.
cout << endl << "Creating the customer Jane Smith.";
customer = new Customer("Jane", "Smith");
cout << endl << "Creating her account with a 500.00 balance.";
customer->setAccount(Account(500.00));
account = customer->getAccount();
cout << endl << "Withdraw 150.00";
account.withdraw(150.00);
cout << endl << "Deposit 22.50";
account.deposit(22.50);
cout << endl << "Withdraw 47.62";
account.withdraw(47.62);
// Print out the final account balance
cout << endl
<< "Customer ["
<< customer->getLastName()
<< ", "
<< customer->getFirstName()
<< "] has a balance of "
<< account.getBalance()
<< endl;
delete customer;
Account acc1(100), acc2(200);
double suAcc = acc1.getBalance()+ acc2.getBalance();
Account sumAcc(suAcc);
cout << "Balance of sumAcc is " << sumAcc.getBalance() << endl;
return (EXIT_SUCCESS);
}
Here is the error:
/cygdrive/c/Users/James/CLionProjects/untitled13/main.cpp:9: undefined reference to `Account::Account(double)'
/cygdrive/c/Users/James/CLionProjects/untitled13/main.cpp:9:(.text+0x2f): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `Account::Account(double)'
/cygdrive/c/Users/James/CLionProjects/untitled13/main.cpp:15: undefined reference to `Account::Account(double)'
/cygdrive/c/Users/James/CLionProjects/untitled13/main.cpp:15:(.text+0x12e): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `Account::Account(double)'
/cygdrive/c/Users/James/CLionProjects/untitled13/main.cpp:15: undefined reference to `Customer::setAccount(Account)
'
It goes on with every method.
I was able to compile this after making several changes.
Remove using namespace std from customer.h. It's bad practice to use "using namespace" here as it could cause name collisions when another file includes customer.h. As a result of removing "using namespace std" you'll need to qualify all of your strings as std::string instead of string.
You declared a default constructor for Account but there is no implementation provided. When a customer is created it tries to call the default constructor of account. If you are on a newer version of c++ you can change this line in your header file.
Account();
to
Account() = default;
If you're on an older version add this to Account.cpp
Account(){}
Related
I have a banking project and I am trying to set up the bank name, address, and working hours. My getlines are showing an error as well as my get functions.
Input exact error messages here please.
'getline': no matching overloaded function found
no suitable user-defined conversion from "Bank" to "std::string" exists
Here's the class for bank:
#include <iostream>
#include <string>
#include <vector>
#include <ctime>
#include <cctype>
#include <cstdlib>
using namespace std;
class Bank {
public:
void setBankName(string bn) { bn = bankname; }
string getBankName() { return bankname; }
void setBankAdd(string ba) { ba = bankadd; }
string getBankAdd() { return bankadd; }
void setWorkingHours(string bwh) { bwh = bankworkinghours; };
string getWorkingHours() { return bankworkinghours; }
private:
string bankname, bankadd, bankworkinghours;
};
//and then this is in my main function
int main() {
Bank bankname, bankadd, bankworkinghours;
char userChoice; // numbers 1-9
int number=0;
system ("color 5f");
cout << "Name of bank: ";
getline(cin, bankname); **//all the get lines also show error**
cout << endl;
cout << "Bank address: ";
getline(cin, bankadd);
cout << endl;
cout << "Bank working hours: ";
getline(cin, bankworkinghours);
cout << endl;
bankname.setBankName(bankname); //the things in the parentheses show error
bankadd.setBankAdd(bankadd);
bankworkinghours.setWorkingHours(bankworkinghours);
The error is self explanatory. 2nd parameter of getline function is std:string so define bankname as std:string and then set the name of bank object by setBankName.
1- You did not created bank Object in the main to set class attributes.
You need an Object with reference to that object you will set the parameters of the class bank.
2- bankname, bankadd, bankworkinghours are string and you made them Bank
Here is updated code and working fine in VS 2019 without any error. Just a few changes in the first 2 and last three lines of main
#include <iostream>
#include <string>
#include <vector>
#include <ctime>
#include <cctype>
#include <cstdlib>
using namespace std;
class Bank {
public:
void setBankName(string bn) { bn = bankname; }
string getBankName() { return bankname; }
void setBankAdd(string ba) { ba = bankadd; }
string getBankAdd() { return bankadd; }
void setWorkingHours(string bwh) { bwh = bankworkinghours; };
string getWorkingHours() { return bankworkinghours; }
private:
string bankname, bankadd, bankworkinghours;
};
//and then this is in my main function
int main() {
Bank bankObj;
string bankname, bankadd, bankworkinghours;
char userChoice; // numbers 1-9
int number = 0;
system("color 5f");
cout << "Name of bank: ";
getline(cin, bankname);
cout << endl;
cout << "Bank address: ";
getline(cin, bankadd);
cout << endl;
cout << "Bank working hours: ";
getline(cin, bankworkinghours);
cout << endl;
bankObj.setBankName(bankname);
bankObj.setBankAdd(bankadd);
bankObj.setWorkingHours(bankworkinghours);
}
void setBankName(string bn) { bn = bankname; } is the wrong way around. try bankname = bn.
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.
My professor gave me two class header and .cpp files to build on. When I include these in main, they work fine. Whenever I just use his files, I get linker errors with clang and xcode.
Here's the error:
shannigan#mbp-007100 inheritance (master) $ make main
c++ main.cpp -o main
Undefined symbols for architecture x86_64:
"SavitchEmployees::SalariedEmployee::SalariedEmployee()", referenced from:
_main in main-0d7e27.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [main] Error 1
Here's my main:
#include "employee.h"
#include "salariedemployee.h"
#include <string>
#include <cstdlib>
#include <iostream>
using namespace SavitchEmployees;
using namespace std;
int main() {
cout << "Do I run?" << endl;
SalariedEmployee sam;
return 0;
};
The header file for Employee:
//This is the header file employee.h.
//This is the interface for the class Employee.
//This is primarily intended to be used as a base class to derive
//classes for different kinds of employees.
#ifndef EMPLOYEE_H
#define EMPLOYEE_H
#include <string>
using std::string;
namespace SavitchEmployees
{
class Employee
{
public:
Employee( );
Employee(const string& theName, const string& theSsn);
string getName( ) const;
string getSsn( ) const;
double getNetPay( ) const;
void setName(const string& newName);
void setSsn(const string& newSsn);
void setNetPay(double newNetPay);
void printCheck( ) const;
protected:
string name;
string ssn;
double netPay;
};
}//SavitchEmployees
#endif //EMPLOYEE_H
The CPP file for main:
//This is the file: employee.cpp
//This is the implementation for the class Employee.
//The interface for the class Employee is in the header file employee.h.
#include <string>
#include <cstdlib>
#include <iostream>
#include "employee.h"
using std::string;
using std::cout;
namespace SavitchEmployees
{
Employee::Employee( ) : name("No name yet"), ssn("No number yet"), netPay(0)
{
//deliberately empty
}
Employee::Employee(const string& theName, const string& theNumber)
: name(theName), ssn(theNumber), netPay(0)
{
//deliberately empty
}
string Employee::getName( ) const
{
return name;
}
string Employee::getSsn( ) const
{
return ssn;
}
double Employee::getNetPay( ) const
{
return netPay;
}
void Employee::setName(const string& newName)
{
name = newName;
}
void Employee::setSsn(const string& newSsn)
{
ssn = newSsn;
}
void Employee::setNetPay (double newNetPay)
{
netPay = newNetPay;
}
void Employee::printCheck( ) const
{
cout << "\nERROR: printCheck FUNCTION CALLED FOR AN \n"
<< "UNDIFFERENTIATED EMPLOYEE. Aborting the program.\n"
<< "Check with the author of the program about this bug.\n";
exit(1);
}
}//SavitchEmployees
SalariedEmployees header:
//This is the header file salariedemployee.h.
//This is the interface for the class SalariedEmployee.
#ifndef SALARIEDEMPLOYEE_H
#define SALARIEDEMPLOYEE_H
#include <string>
#include "employee.h"
using std::string;
namespace SavitchEmployees
{
class SalariedEmployee : public Employee
{
protected:
double salary;//weekly
public:
SalariedEmployee( );
SalariedEmployee (const string& theName, const string& theSsn,
double theWeeklySalary);
double getSalary( ) const;
void setSalary(double newSalary);
void printCheck( );
};
}//SavitchEmployees
#endif //SALARIEDEMPLOYEE_H
SalariedEmployee.cpp:
//This is the file salariedemployee.cpp
//This is the implementation for the class SalariedEmployee.
//The interface for the class SalariedEmployee is in
//the header file salariedemployee.h.
#include <iostream>
#include <string>
#include "salariedemployee.h"
using std::string;
using std::cout;
using std::endl;
namespace SavitchEmployees
{
SalariedEmployee::SalariedEmployee( ) : Employee( ), salary(0)
{
//deliberately empty
}
SalariedEmployee::SalariedEmployee(const string& newName, const string& newNumber,
double newWeeklyPay)
: Employee(newName, newNumber), salary(newWeeklyPay)
{
//deliberately empty
}
double SalariedEmployee::getSalary( ) const
{
return salary;
}
void SalariedEmployee::setSalary(double newSalary)
{
salary = newSalary;
}
void SalariedEmployee::printCheck( )
{
setNetPay(salary);
cout << "\n__________________________________________________\n";
cout << "Pay to the order of " << getName( ) << endl;
cout << "The sum of " << getNetPay( ) << " Dollars\n";
cout << "_________________________________________________\n";
cout << "Check Stub NOT NEGOTIABLE \n";
cout << "Employee Number: " << getSsn( ) << endl;
cout << "Salaried Employee. Regular Pay: "
<< salary << endl;
cout << "_________________________________________________\n";
}
}//SavitchEmployees
How can I get rid of these linker errors so I can focus on my actual code? Is there anything obvious wrong? The only thing I've changed was making the "private" variables protected.
I can't see the class named SalariedEmployee.
I think the main function should look like this.
int main() {
cout << "Do I run?" << endl;
Employee sam;
return 0;
};
You have to use Employee instead of SalariedEmployee
I am making a small console game and I have a player class with private integers for the stats and a private string for the name. What I want to do is to ask the user for their name, and store that into the private name variable in the player class. I got an error stating:
error: no match for 'operator>>'
(operand types are 'std::istream {aka std::basic_istream<char>}' and 'void')
Here is my code:
main.cpp
#include "Player.h"
#include <iostream>
#include <string>
using namespace std;
int main() {
Player the_player;
string name;
cout << "You wake up in a cold sweat. Do you not remember anything \n";
cout << "Do you remember your name? \n";
cin >> the_player.setName(name);
cout << "Your name is: " << the_player.getName() << "?\n";
return 0;
}
Player.h
#ifndef PLAYER_H
#define PLAYER_H
#include <string>
using namespace std;
class Player {
public:
Player();
void setName(string SetAlias);
string getName();
private:
string name;
};
#endif // PLAYER_H
Player.cpp
#include "Player.h"
#include <string>
#include <iostream>
Player::Player() {
}
void Player::setName(string setAlias) {
name = setAlias;
}
string Player::getName() {
return name;
}
The return type for the setName function is void, not a string. So you have to store first the variable in a string, and then pass it to the function.
#include "Player.h"
#include <iostream>
#include <string>
using namespace std;
int main() {
Player the_player;
cout << "You wake up in a cold sweat. Do you not remember anything \n";
cout << "Do you remember your name? \n";
string name;
cin >> name;
the_player.setName(name);
cout << "Your name is: " << the_player.getName() << "?\n";
return 0;
}
If you surely want use function, should return object reference.
string& Player::getNamePtr() {
return name;
}
cin >> the_player.getNamePtr();
Firstly, try to get the value in the name variable from the user and then call the setName method of the class Player:
cin>>name;
the_player.setName(name);
Edit: I had forgotten to explicitly define my class destructors in their respective .cpp files. I replaced *p with string *killList = new string[10];
and my code now compiles. Thanks for your replies!
I've tried to compile the following files using the command :
g++ -o hunter hunter_h.h hunter_h.cpp animal_h.h animal_h.cpp main.cpp
animal_h.h
#include <iostream>
#include <string>
#ifndef ANIMAL_H
#define ANIMAL_H
using namespace std;
// Animal class
class animal
{
friend class hunter;
// need a name, species, private ID
public:
animal();
animal(string aSpecies);
string name;
string species;
string getSpecies();
void setName(string aName);
string getName();
int getID();
~animal();
private:
static int uID;
};
#endif
animal_h.cpp
#include "animal_h.h"
//#include "hunter_h.h"
#include <iostream>
#include <string>
using namespace std;
int animal:: uID = 0 ;
animal::animal()
{
cout << "Created an animal!" << endl;
name = "?";
species = "?";
uID++;
}
animal::animal(string aSpecies)
{
cout << "Created 1 "<< aSpecies << "!" << endl;
name= "?";
species = aSpecies;
uID++;
}
string animal::getSpecies()
{
cout << species << endl;
}
void animal::setName(string aName)
{
name = aName;
cout << "This " << species << " is now called " << name << endl;
}
string animal::getName()
{
cout << name << endl;
}
int animal:: getID()
{
cout << uID << endl;
}
hunter_h.h This is a derived class of the animal base class with unique behaviors.
#include "animal_h.h"
#include <iostream>
#ifndef ANIMAL_HUNTER
#define ANIMAL_HUNTER
class hunter : public animal
{
public:
hunter();
hunter(std::string aSpecies);
void recordKills(std::string kill);
static int tKills;
int totalKills();
static std::string *theKills();
static std::string *p;
static int clearTotal();
~hunter();
};
#endif
hunter_h.cpp
#include "animal_h.h"
#include "hunter_h.h"
#include <iostream>
#include <string>
using namespace std;
int hunter:: tKills =0;
string killList[10];
hunter::hunter()
{
cout<<"created a hunter! "<<endl;
name= "? ";
species="? ";
string *p;
p = &killList[0];
}
hunter::hunter(string aSpecies)
{
name = "?";
species = aSpecies;
cout << "created a hunting "<<species <<endl;
}
string *theKills()
{
return hunter::p;
}
void hunter::recordKills(string kill)
{
cout << kill << " killed." << endl;
*(p+tKills) = kill;
tKills++;
cout << tKills << " total kills." << endl;
}
int hunter::totalKills()
{
cout << name << "'s " << "Total kills: " << tKills << endl;
}
int hunter::clearTotal()
{
delete[] killList;
return 0;
}
main.cpp
#include "animal_h.h"
#include "hunter_h.h"
#include <iostream>
#include <string>
using namespace std;
int main()
{
hunter *hunterC;
hunterC= new hunter("cheetah");
hunterC->recordKills("Mouse");
hunterC-> recordKills("Gazelle, Gazelle");
hunterC-> recordKills("Hyena");
hunterC-> recordKills("Rabbit, Rabbit");
hunterC->theKills;
hunterC->clearTotal;
}
Now, when I try to compile I get the following warning and errors:
hunter_h.cpp: In static member function ‘static int hunter::clearTotal()’:
hunter_h.cpp:49:11: warning: deleting array ‘killList’
delete[] killList;
^
/tmp/ccnv8xdj.o:hunter_h.cpp:(.text+0x71): undefined reference to `animal::~animal()'
/tmp/ccnv8xdj.o:hunter_h.cpp:(.text+0x101): undefined reference to `animal::~animal()'
/tmp/ccnv8xdj.o:hunter_h.cpp:(.text+0x119): undefined reference to `hunter::p'
/tmp/ccnv8xdj.o:hunter_h.cpp:(.text+0x15a): undefined reference to `hunter::p'
/tmp/ccqCD1e7.o:main.cpp:(.text+0x1f4): undefined reference to `animal::~animal()'
/tmp/ccqCD1e7.o:main.cpp:(.text+0x20c): undefined reference to `animal::~animal()'
collect2: error: ld returned 1 exit status
I've been learning C++ for a couple months only so am not sure where the above code is going wrong. How can I get this to compile and run?
killList is not allocated using new[], then dont delete it with delete[]. It is not allocated runtime, then it does not have to be deallocated explicitly. It will release its memory when the program exits. With your code as it is you are running the chance of overrunning you killList array.
Try using std::vector instead.
std::vector<std::string> killList;
...
void recordKills(std::string s)
{
...
killList.push_back(s);
}
void clearTotal()
{
killList.clear();
}
I am trying to implement a linked list using a class template, however each of my classes that I want in the list all inherit from an Account class. I have attempted to template the linked list class as account however Ive come into errors I can't resolve. Any ideas as to how I can go about this?
The error exists within the customer.cpp class where it says
14 IntelliSense: a value of type "Account *" cannot be assigned to an entity of type "CurrentAccount *" f:\Further C++\Assignment with Templates\Assignment\Customer.cpp 22 9 Assignment
Customer class:
#ifndef CUSTOMER_H
#define CUSTOMER_H
#include <iostream>
#include <string>
#include "Account.h"
#include "AccountLinkedList.h"
using namespace std;
class Customer
{
private:
string name;
string telNo;
int doorNum;
string street;
string postcode;
string sex;
string dob;
AccountLinkedList <Account> accountList; //Here is the linkedList templated as Account class
Account * head;
Account * aNode;
public:
int customerID;
Customer * next;
//Customers personal details
Customer(int id, string customerName, string gender, int doorNumber, string customerPostcode, string dateOfBirth)
: customerID(id), name(customerName), sex(gender), doorNum(doorNumber), postcode(customerPostcode), dob(dateOfBirth)
{
};
string getName();
void addAccount(int choice);
void showPersonDetails();
void updatePersonDetails();
};
#endif
Here is the Customer.cpp file:
#include "Customer.h"
#include "Account.h"
#include "CurrentAccount.h"
#include "JuniorCurrentAccount.h"
#include "SavingsAccount.h"
#include "CorporateSavingsAccount.h"
#include "StudentSavingsAccount.h"
#include <string>
using namespace std;
void Customer::addAccount(int choice)
{
int id; // temp account ID
switch(choice)
{
/*Current account + JuniourCurrentAccount both inherit from Account class*/
case 0: CurrentAccount * aNode;
CurrentAccount * head;
/*the two lines below give the error on the = sign*/
aNode = accountList.CreateNode(id/*newaccountID*/);
head = accountList.InsertFirst(head, aNode);
break;
case 1: JuniorCurrentAccount * aNode;
JuniorCurrentAccount * head;
aNode = accountList.CreateNode(id);
head = accountList.InsertFirst(head, aNode);
}
}
string Customer::getName()
{
return name;
}
void Customer::showPersonDetails()
{
cout << name << " details" << endl;
cout << "===============================" << endl;
cout << "sex: " << sex << endl;
cout << "dob: " << dob << endl;
cout << "doorNum: " << doorNum << endl;
cout << "postcode: " << postcode << endl;
cout << "===============================" << endl;
}
Here is the current Account class that inherits from account:
#ifndef CURRENTACCOUNT_H
#define CURRENTACCOUNT_H
#include <iostream>
#include <string>
#include "Account.h"
using namespace std;
class CurrentAccount : Account
{
private:
double intRate;
double balance;
protected:
public:
CurrentAccount * next;
CurrentAccount(int accountNumber, double interestRate, double setBalance) : Account(accountNumber)
{
accountType = "Current Account";
intRate = interestRate;
balance = setBalance;
}
};
#endif