g++ compiles mingw complaints - c++

I'm having a little problem when trying to compile a very simple test c++ code:
I have a Warrior class when I want to define a copy constructor for test purposes. I declare it in Warrior.h and define it in Warrior.cpp.
When compiling the code with g++ on Ubuntu, it works great, however when trying to compile it on Windows7 Codeblocks (mingw), I get the following message :
error: definition of implicitly-declared 'Warrior::Warrior(const Warrior&)'|||=== Build failed: 1 error(s)
The code:
Warrior.h
#ifndef WARRIOR_H_INCLUDED
#define WARRIOR_H_INCLUDED
#include <string>
#include "Arme.h"
#include "Warrior.h"
class Warrior{
public:
Warrior(Warrior const& other);
std::string getName() const;
Warrior setName(std::string name);
int getAge() const;
Warrior setAge(int age);
int getLife() const;
Warrior setLife(int life);
Arme getArme() const;
Warrior setArme(Arme& arme);
void attaquer(Warrior& autreCombattant);
bool isAlive() const;
Warrior setIsAlive(bool isAlive);
Warrior(std::string name, int age);
~Warrior();
private:
std::string m_name;
int m_age;
int m_life;
bool m_isAlive;
Arme m_arme;
};
#endif // WARRIOR_H_INCLUDED
Warrior.cpp
#include "Warrior.h"
#include "Arme.h"
#include <iostream>
#include <string>
using namespace std;
Warrior Warrior::setName(string name){
m_name=name;
return *this;
}
string Warrior::getName() const{
return m_name;
}
int Warrior::getAge() const{
return m_age;
}
Warrior Warrior::setAge(int age){
m_age=age;
return *this;
}
int Warrior::getLife() const{
return m_life;
}
Warrior Warrior::setLife(int life){
m_life=life;
if(life<=0){
cout << m_name << " est mort." << endl;
}else{
cout << m_name << " a la vie suivante : " << m_life << endl;
}
return *this;
}
Arme Warrior::getArme() const{
return m_arme;
}
Warrior Warrior::setArme(Arme& arme){
m_arme=arme;
cout << m_name << " a maintenant l'arme suivante : " << arme.getName() << endl;
return *this;
}
void Warrior::attaquer(Warrior& autreCombattant){
autreCombattant.setLife(autreCombattant.getLife() - m_arme.getDegat());
}
bool Warrior::isAlive() const{
return m_isAlive;
}
Warrior Warrior::setIsAlive(bool isAlive){
m_isAlive=isAlive;
return *this;
}
Warrior::Warrior(string name, int age): m_name(name), m_age(age), m_arme("b",4){
m_life=300;
cout << name << " vient de rejoindre l'arene" << endl;
}
Warrior::~Warrior(){}
Warrior::Warrior(Warrior const& autre): m_name(autre.getName())
{}
Arme.h
#ifndef ARME_H_INCLUDED
#define ARME_H_INCLUDED
#include <string>
class Arme{
private:
int m_degat;
std::string m_name;
public:
int getDegat() const;
Arme setDegat(int degat);
std::string getName() const;
Arme setName(std::string name);
Arme(std::string name, int degat);
Arme();
};
#endif // ARME_H_INCLUDED
Arme.cpp
#include "Arme.h"
#include <iostream>
#include <string>
using namespace std;
int Arme::getDegat() const{
return m_degat;
}
Arme Arme::setDegat(int degat){
m_degat=degat;
return *this;
}
string Arme::getName() const{
return m_name;
}
Arme Arme::setName(string name){
m_name=name;
return *this;
}
Arme::Arme(std::string name, int degat): m_name(name), m_degat(degat){
}
Arme::Arme(){
m_name="default weapon";
m_degat=1;
}
Thanks for your help

I have removed my project on codeblocks, then created a new one and I have added the previously created files, now it compiles without any problem.
It seems to me Codeblocks has a kind of cache engine that was not refreshed...weird!

Related

Some guidance with C++ and creating objects using composition

Basically my issue is with compositions. I understand the principle, but I'm struggling with the execution in one of the tests.
From the code of Computer and Monitor below, I have to create a final class Complect which will have its own name , the name of the computer, the name of the monitor, and a price which will be made up from the price() functions.
Computer.h
#ifndef COMPUTER_H
#define COMPUTER_H
#include <string>
class Computer{
public:
Computer(std::string name, int ram, double price);
std::string name() const;
int ram() const;
double price() const;
void printComputer() const;
void setComputer(std::string name, int ram, double price);
private:
std::string its_name;
int ram_gb;
double cost_price;
};
#endif // COMPUTER_H
Computer.cpp
#include "Computer.h"
#include <iostream>
Computer::Computer(std::string name, int ram, double price)
: its_name(name), ram_gb(ram), cost_price(price){
}
std::string Computer::name() const {
return its_name;
}
int Computer::ram() const {
return ram_gb;
}
double Computer::price() const {
return cost_price;
}
void Computer::printComputer() const{
std::cout << "Computer name = " <<name() <<"\n"
<< "Computer RAM = " <<ram() <<" GB\n"
<< "Computer Price = " << price() <<" EUR \n";
}
Monitor.h
#ifndef MONITOR_H
#define MONITOR_H
#include <string>
class Monitor{
public:
Monitor(std::string name, std::string type, double price);
std::string name() const;
std::string type() const;
double price() const;
//print computer
void printMonitor() const;
//set computer
void setMonitor(std::string name, std::string type, double price);
private:
std::string its_name;
std::string type_set;
double cost_price;
};
#endif // MONITOR_H
Monitor.cpp
#include "Monitor.h"
#include <iostream>
Monitor::Monitor(std::string name, std::string type, double price) : its_name(name), type_set(type), cost_price(price){
}
std::string Monitor::name() const {
return its_name;
}
std::string Monitor::type() const{
return type_set;
}
double Monitor::price() const {
return cost_price;
}
void Monitor::printMonitor() const{
std::cout << "Monitor name = " <<name() <<"\n"
<< "Monitor type = " <<type() <<"\n"
<< "Monitor price = " << price() <<" EUR \n";
}
Here is the class that I have made:
Complect.h
#ifndef COMPLECT_H
#define COMPLECT_H
#include <string>
class Complect{
public:
Complect(std::string name, std::string computername, std::string monitorname, double price);
std::string name() const;
std::string computername() const;
std::string monitorname() const;
double price() const;
void printComplect();
void setComplect(std::string name, std::string computername, std::string monitorname, double price);
private:
std::string complect_name;
std::string computername_final;
std::string monitorname_final;
double cost_price;
};
#endif // COMPLECT_H
Complect.cpp
#include "Complect.h"
#include "Monitor.h"
#include "Computer.h"
#include <iostream>
Complect::Complect(std::string name, std::string computername, std::string monitorname, double price) :
complect_name(name), computername_final(computername), monitorname_final(monitorname), cost_price(price){
}
std::string Complect::name() const{
return complect_name;
}
std::string Complect::computername() const{
return computername_final;
}
std::string Complect::monitorname() const{
return monitorname_final;
}
double Complect::price() const{
return cost_price;
}
void Complect::printComplect(){
std::cout << "Complect name = " << name() <<"\n"
<< "Computer name = " <<computername() <<"\n"
<<"Monitor name = " <<monitorname() <<"\n"
<<"Complect price = " <<price() <<" EUR \n";
}
Here is how I use the classes in Main.cpp
#include <iostream>
#include "Computer.h"
#include "Monitor.h"
#include "Complect.h"
int main(){
Computer asus("Asus One", 8, 545.95) ;
asus.printComputer() ;
std::cout << "\n";
Monitor iiyama("Iiyama Blackhawk 27inch", "LED", 299.99);
iiyama.printMonitor();
std::cout <<"\n";
Complect numberOne ("Number one complect", asus.name(), iiyama.name(), iiyama.price() + asus.price());
numberOne.printComplect();
std::cout <<"\n";
system ("pause");
return 0;
}
The end result is what it should be, so this code works.
But the issue with this is that it's incorrectly structured.
In the main.cpp file you will see that the Complect object is being created. But I currently provide all of the informations of that object at construction in main.cpp file.
Sorry the codes a bit messy, but im trying to wrap my head around this and struggling at the moment... How to make the class in complect.cpp file provide itself all its information ?
Currently you do not use composition but copy the attributes from the two other classes and you do a lot of work in the call of the constructor from main
A first little change from your code is to get instances of Computer and Monitor in parameter in the constructor:
Complect(std::string name, const Computer &, const Monitor &);
of course the final price is also computed inside that constructor, in main you just create a Complect with its name and its parts :
Complect numberOne ("Number one complect", asus, iiyama);
Now main fortunately does not have to know how the price is computed, else imagine if the formula change and you have to update all the calls of the constructor :-(. The way the price is computed is only the responsibility of Complect.
Complect numberOne ("Number one complect", asus, iiyama);
More than the constructor setComplect must be updated to receive the price of the monitor and computer separated for the same reason.
void setComplect(std::string name, std::string computername, std::string monitorname, double computerprice, double monitorprice);
or probably better to replace it by the methods
void setname(std::string name);
void setcomputer(std::string computername, double computerprice);
void setmonitor(std::string monitorname, double monitorprice);
But to duplicate all the attributes of Computer and Monitor in Complect is not practical, and you do not have composition to the instances. A first possibility is to save a copy of them :
class Complect{
...
private:
Computer computer;
Monitor monitor;
// does not need attribute "double cost_price;"
...
};
Complect::Complect(std::string name, const Computer & c, const Monitor & m)
: complect_name(name), computer(c), monitor(m) {
}
std::string Complect::computername() const{
return computer.name();
}
std::string Complect::monitorname() const{
return monitor.name();
}
double Complect::price() const{
return computer.price() + monitor.price();
}
void Complect::printComplect(){
std::cout << "Complect name = " << name() <<"\n"
<< "Computer name = " << computer.name() <<"\n"
<<"Monitor name = " << monitor.name() <<"\n"
<<"Complect price = " << price() <<" EUR \n";
}
The advantage of that solution is you are not impacted if the initial instances of Monitor and Computer disappear. The disadvantage is for instance the price is not updated if the price of one of the cloned part changes except by calling setXXX
An other way is to not clone the Monitor and Conputer, but you cannot have just that :
class Complect{
...
private:
Computer & computer;
Monitor & monitor;
// does not need attribute "double cost_price;"
...
};
Complect::Complect(std::string name, const Computer & c, const Monitor & m)
: complect_name(name), computer(c), monitor(m) {
}
because that supposes the instances of Monitor and Computer still exist while the corresponding instance of Complect exists
Fortunately C++ offers interesting features to manage that

I dont understand error "definition of implicity-declared 'Clothing::Clothing()'

The question:
Why is the following error happening?
definition of implicity-declared 'Clothing::Clothing()
The context:
As an assignment I have to do constructors, destructors and methods in a class Clothing. I'm having a problem when I try to define the constructor in clothing.cpp. I have read that the problem is because I did not declare the constructor in clothing.h, but I think how I have done it, it's declared. I have no clue where the problem lies.
My code:
clothing.h:
#ifndef CLOTHING_H_
#define CLOTHING_H_
#include <string>
#include <iostream>
using namespace std;
class Clothing {
private:
int gender;
int size;
string name;
public:
Clothing();
Clothing(const Clothing &t);
Clothing(int gender, int size, string name);
~Clothing();
int getGender();
int getSize();
string getName();
void setGender(int gender1);
void setSize(int size1);
void setName(string name1);
void print();
void toString();
};
#endif /* CLOTHING_H_ */
clothing.cpp:
#include <iostream>
#include "clothing.h"
#include <string>
#include <sstream>
using namespace std;
Clothing::Clothing() :
gender(1),
size(1),
name("outofstock") {
}
Clothing::Clothing(const Clothing& t) :
gender(t.gender),
size(t.size),
name(t.name) {
}
Clothing::Clothing(int gender, int size, string name) {
}
int Clothing::getGender() {
return gender;
}
int Clothing::getSize() {
return size;
}
string Clothing::getName() {
return name;
}
void Clothing::setGender(int gender1) {
gender = gender1;
}
void Clothing::setSize(int size1) {
size = size1;
}
void Clothing::setName(string name1) {
name = name1;
}
void Clothing::print() {
cout << name << " " << gender << " " << size << endl;
}
void Clothing::toString() {
stringstream ss;
ss << name << " " << gender << " " << size;
cout << ss.str();
}
Errors: \src\clothing.cpp:7:21: error: definition of implicitly-declared 'Clothing::Clothing()'
\src\clothing.cpp:14:37: error: definition of implicitly-declared 'Clothing::Clothing(const Clothing&)'
The error is: you declared a destructor but you didn't define it. Add a definition for the destructor or define it as default:
#ifndef CLOTHING_H_
#define CLOTHING_H_
#include <string>
#include <iostream>
using namespace std;
class Clothing {
private:
int gender;
int size;
string name;
public:
Clothing();
Clothing(const Clothing &t);
Clothing(int gender, int size, string name);
~Clothing() = default; // <-- add a default destructor
int getGender();
int getSize();
string getName();
void setGender(int gender1);
void setSize(int size1);
void setName(string name1);
void print();
void toString();
};
#endif /* CLOTHING_H_ */
After fixing this your code snippet works: tio.run
If you have more problems with your code, the problems are outside of your provided code snippet.

C++ class not printing? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I'mm getting a bit confused why this isn't printing the name!
I've got a human.cpp :
#include <string>
#include <iostream>
#include "human.h"
human::human(int age, human *n){
m_age=age;
name = new char[2];
human::~human() = default;
void human::printDetails(){
std::cout <<"name is " << name << " age is " << m_age << std::endl;
}
and human.h:
class human {
public: //: needed
human(int age, human *name);
~human();
void printDetails();
private :
char *name;
int m_age;
};
and finally the main.cpp:
#include <iostream>
#include <string>
#include "human.h"
int main()
{
human *Alex = new human(10, Alex); //pointer // needs argument //should have both age and name
Alex->printDetails(); //print not Print
}
So my issue is: it prints the age, but does not print the name? Any suggestions? Thanks :)
There is no need for any new in your code. Since you #included <string> in your code I assume you want to use it:
#include <string>
#include <iostream>
class Person
{
int age;
std::string name;
public:
Person(int age, std::string name)
: age { age },
name { name }
{}
int get_age() const { return age; }
std::string const& get_name() const { return name; }
void print_details() const {
std::cout << "My name is " << name << ". I am " << age << " years old.\n";
}
};
int main()
{
Person p{ 19, "Alex" };
p.print_details();
}
If you *really* want to do it the hard waytm:
#include <cstring> // std::strlen()
#include <utility> // std::exchange(), std::swap()
#include <iostream>
class Person
{
char *name_;
int age_;
public:
Person(int age, char const *name) // constructor
// we don't want to call std::strlen() on a nullptr
// instead allocate just one char and set it '\0'.
: name_ { new char[name ? std::strlen(name) + 1 : 1]{} },
age_ { age }
{
if (name)
std::strcpy(name_, name);
}
Person(Person const &other) // copy-constructor
: name_ { new char[std::strlen(other.name_) + 1] },
age_ { other.age_ }
{
std::strcpy(name_, other.name_);
}
Person(Person &&other) noexcept // move-constructor
: name_ { std::exchange(other.name_, nullptr) }, // since other will be
age_ { other.age_ } // wasted anyway, we
{} // "steal" its resource
Person& operator=(Person other) noexcept // copy-assignment operator
{ // since the parameter other got
std::swap(name_, other.name_); // copied and will be destructed
age_ = other.age_; // at the end of the function we
return *this; // can simply swap the pointers
} // - know as the copy&swap idiom.
~Person() { delete[] name_; } // destructor
void print_details() const
{
std::cout << "I am " << name_ << ". I am " << age_ << " years old.\n";
}
};
int main()
{
Person p{ 19, "Alex" };
p.print_details();
}
If you don't want to implement the special member functions you'd have to = delete; them so the compiler-generated versions - which won't work correctly for classes managing their own resources - won't get called by accident.
#include <iostream>
#include <cstring>
#include <new>
using namespace std;
class human {
public:
human(int age, const char * name)
{
m_age=age;
m_name = new char[strlen(name)+1];
strcpy(m_name,name);
}
~human()
{
delete[] m_name;
}
void printDetails()
{
std::cout <<"name is " << m_name << " age is " << m_age << std::endl;
}
private :
char *m_name;
int m_age;
};
int main()
{
human *Alex = new human(10, "alex"); //pointer // needs argument //should have both age and name
Alex->printDetails(); //print not Print
delete Alex;
return 0;
}
You need to read more. The example you shared was wrong at many level, also read about dynamic memory management.
I guess you're confused with the second parameter of the human constructor. Look at this changes:
human.h
class human {
public:
human(int age, char *name);
human(const human& h);
human& operator=(const human& h);
void printDetails();
virtual ~human();
private:
int age;
char *name;
};
human.cpp
human::human(int _age, char *_name) {
age = _age;
name = new char[strlen(_name)+1];
strcpy(name, _name);
}
human::human(const human& _h) { //Copy constructor
age = _h.age;
name = new char[strlen(_h.name)+1];
strcpy(name, _h.name);
}
human& human::operator=(const human& _h) { //Copy assignment operator
age = _h.age;
name = new char[strlen(_h.name)+1];
strcpy(name, _h.name);
return *this;
}
void human::printDetails(){
std::cout <<"name is " << name << " age is " << age << std::endl;
}
human::~human() { //Destructor
delete[] name;
}
main.cpp
int main() {
human *alex = new human(10, "Alex");
alex->printDetails();
human *anotherAlex = new human(*alex);
anotherAlex->printDetails();
delete alex;
delete anotherAlex;
}
A suggestions: I would use Human as the class names and alex for the variable names. (See how I capitalized them)
For beginner you may use std::string, so you already included it. ))
human.h
#include <string>
class human
{
public: //: needed
human(int age, std::string name);
void printDetails();
private :
std::string name;
int m_age;
};
human.cpp
#include <iostream>
#include "human.h"
human::human(int age, std::string n)
{
m_age = age;
name = n;
}
void human::printDetails()
{
std::cout <<"name is: " << name << " age is: " << m_age << std::endl;
}
main.cpp
#include "human.h"
int main()
{
human *Alex = new human(10, "Alex");
Alex->printDetails();
}

C++ clang linker command failed with exit code 1 [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.
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

Simple C++ Class add and display Song object

I am new to C++ and am having issues when running this code, I have no idea where I have gone wrong.
I am just trying to make a simple Song class, then add and display an instance of the song object.
The error is saying that allot of my Methods are already defined in projectName.obj. I am also getting unresolved external symbol on IDSeed.
I am using visual studio 2017.
Main
#include "stdafx.h"
#include "Song.h"
#include "Song.cpp"
int main()
{
Song testSong("Evil Tram", "Catz N dogz");
testSong.setGenre("Tech House");
testSong.display();
return 0;
}
Song.cpp
#include "stdafx.h"
#include "Song.h"
Song::Song()
{
m_title = "";
m_album = "";//change to class
m_artist = "";//change to class
m_genre = "";//change to enum
m_ID = 0;
IDSeed = 0;
}
Song::Song(string title, string artist)
{
m_title = title;
m_album = "No Album";
m_genre = "No Genre";
m_artist = artist;
IDSeed++;
m_ID = IDSeed;
}
string Song::getTitle() const
{
return m_title;
}
string Song::getAlbum() const
{
return m_album;
}
string Song::getArtist() const
{
return m_artist;
}
string Song::getGenre() const
{
return m_genre;
}
int Song::getID() const
{
return m_ID;
}
void Song::setTitle(string title)
{
m_title = title;
}
void Song::setAlbum(string album)
{
m_album = album;
}
void Song::setArtist(string artist)
{
m_artist = artist;
}
void Song::setGenre(string genre)
{
m_genre = genre;
}
void Song::setID(int id)
{
m_ID = id;
}
void Song::display() const
{
cout << m_title << ", " << m_album << ", "
<< m_artist << ", " << m_genre << endl;
}
Song::~Song()
{
}
ostream & operator<<(ostream & out, Song & s)
{
out << s.m_title << ", " << s.m_album << ", "
<< s.m_artist << ", " << s.m_genre << endl;
return out;
}
istream & operator>>(istream & in, Song & s)
{
in >> s.m_title >> s.m_album >> s.m_artist >> s.m_genre;
return in;
}
Song.h
#pragma once
#include <iostream>
#include <string>
#include <ostream>
using std::string;
using std::cout;
using std::endl;
using std::ostream;
using std::istream;
class Song
{
private:
#pragma region Variables
string m_title;
string m_album;//change to class
string m_artist;//change to class
string m_genre;//change to enum
int m_ID;
static int IDSeed;
#pragma endregion
public:
Song();
Song(string title, string artist);
#pragma region Getters
string getTitle() const;
string getAlbum()const;
string getArtist()const;
string getGenre()const;
int getID()const;
#pragma endregion
#pragma region Setters
void setTitle(string title);
void setAlbum(string album);
void setArtist(string artist);
void setGenre(string genre);
void setID(int id);
#pragma endregion
#pragma region Methods
void display() const;
#pragma endregion
friend ostream& operator<<(ostream& out,
Song& s);
friend istream& operator>>(istream& in,
Song& s);
~Song();//destructer
};
Solved by removing the #include song.cpp and placing the static keyword in the cpp file instead of the .h