No default constructor exists for class c++ [duplicate] - c++

This question already has answers here:
Why does C++ allow us to surround the variable name in parentheses when declaring a variable?
(2 answers)
Closed 5 years ago.
Hello,
I'm trying to instantiate an anonymous object with a std::string variable 'name'. But intellisenen gives me error saying
E0291 no default constructor exists for class "Player" GoldGame e:\C++ Projects\Hello World\GoldGame\GoldGame.cpp 17
I have provided a constructor which can just take a std::string variable since other parameters are provided with default value.
Can you guys shed some light on this?
What confuses me even more is that when I change
Player(name);
to
Player a(name);
or to
Player("test");
then intellisense becomes totally fine with those.
GoldGame.cpp
#include "stdafx.h"
#include "Creature.h"
#include "Player.h"
#include <iostream>
#include <string>
int main()
{
std::cout << "Enter your name: ";
std::string name;
std::cin >> name;
Player(name);
return 0;
}
Creature.h
#pragma once
#include <string>
class Creature
{
public:
Creature(const std::string &name, const char symbol, const int health, const int damage, const int gold);
~Creature();
//getters
const std::string& getName() { return m_name; }
const char getSymbol() { return m_symbol; }
const int getHealth() { return m_health; }
const int getDamage() { return m_damage; }
const int getGold() { return m_gold; }
//health, gold and dead
void reduceHealth(const int healthMinus);
void addGold(const int gold);
bool isDead();
private:
std::string m_name;
char m_symbol;
int m_health;
int m_damage;
int m_gold;
};
Creature.cpp
#include "stdafx.h"
#include "Creature.h"
Creature::Creature(const std::string & name, const char symbol, const int health, const int damage, const int gold)
:m_name(name), m_symbol(symbol), m_health(health), m_damage(damage), m_gold(gold)
{
}
Creature::~Creature()
{
}
void Creature::reduceHealth(const int healthMinus)
{
m_health -= healthMinus;
}
void Creature::addGold(const int gold)
{
m_gold += gold;
}
bool Creature::isDead()
{
if (m_health>0)
{
return true;
}
else
{
return false;
}
}
Player.h
#pragma once
#include "Creature.h"
#include <string>
class Player :
public Creature
{
public:
Player(const std::string &name, const char symbol='#', const int health=10, const int damage=1, const int gold=0);
~Player();
const int getLevel() { return m_level; }
void levelUp();
bool hasWon();
private:
int m_level;
};
Player.cpp
#include "stdafx.h"
#include "Player.h"
Player::Player(const std::string & name, const char symbol, const int health, const int damage, const int gold)
:Creature(name,symbol,health,damage,gold)
{
}
Player::~Player()
{
}
void Player::levelUp()
{
++m_level;
}
bool Player::hasWon()
{
if (m_level>=20)
{
return true;
}
else
{
return false;
}
}

Player(name); does not do what you think it does. It declares a new variable name of type Player and calls a default constructor. If you want to instantiate an anonymous Player variable then you need to write
(Player(name));
// or
Player{name}; // list initialization since C++11

Related

Why am I getting an undefined reference to a constructor despite not calling it?

This error is beyond my current understanding. I have tried for hours to figure out why this is the case. Can someone help me?
Warrior.h
#include <string>
#ifndef __WARRIOR_H__
#define __WARRIOR_H__
#include "Character.h"
// HeroType type;
// string name;
// double health;
// double attackStrength;
class Warrior : public Character {
private:
string allegiance;
public:
Warrior(const string & _name, double _health, double _attackStrength, string _allegiance) : Character(WARRIOR, _name, _health, _attackStrength), allegiance(_allegiance){}
void attack(Character &);
};
#endif
// Warrior::Warrior(const string & _name, double _health, double _attackStrength, string _allegiance) : Character(WARRIOR, _name, _health, _attackStrength), allegiance(_allegiance)
// {}
Warrior.cpp
#include <iostream>
#include <vector>
#include <cstdlib>
#include "Warrior.h"
using namespace std;
void Warrior::attack(Character &opponent) {
Warrior &opp = dynamic_cast<Warrior &>(opponent);
if (opp.allegiance != allegiance)
{
double totalDamage;
totalDamage = (health / MAX_HEALTH);
opp.damage(totalDamage);
}
}
// Lecturer::Lecturer(const string & name,
// const string & addr,
// const string & email,
// const string & eid,
// double courseRate,
// double emplPerc)
// : Employee(name, addr, email, eid), courseRate(courseRate), emplPerc(emplPerc)
// {}
Character.h
#include <string>
using namespace std;
#ifndef __CHARACTER_H__
#define __CHARACTER_H__
enum HeroType {WARRIOR, ELF, WIZARD};
const double MAX_HEALTH = 100.0;
class Character {
protected:
HeroType type;
string name;
double health;
double attackStrength;
public:
Character(HeroType type, const string &name, double health, double attackStrength);
HeroType getType() const;
const string & getName() const;
int getHealth() const;
void damage(double d);
bool isAlive() const;
virtual void attack(Character &) = 0; //Abstract
};
#endif
Character.cpp
#include <iostream>
#include <vector>
#include <cstdlib>
using namespace std;
#include "Character.h"
Character::Character(HeroType type, const string &name, double health, double attackStrength) {
this->type = type;
this->name = name;
this->health = health;
this->attackStrength = attackStrength;
}
HeroType Character::getType() const {
return type;
}
const string & Character::getName() const {
return name;
}
int Character::getHealth() const {
return health;
}
void Character::damage(double d) {
health = health - d;
}
bool Character::isAlive() const {
return (health > 0);
}
Compiler error
In function Warrior::Warrior(std::string const&, double, double, std::string):
main.cpp:(.text._ZN7WarriorC2ERKSsddSs[_ZN7WarriorC5ERKSsddSs]+0x46): undefined reference to Character::Character(HeroType, std::string const&, double, double)
Warrior.o: In function Warrior::attack(Character&):
Warrior.cpp:(.text+0x87): undefined reference to Character::damage(double)
collect2: error: ld returned 1 exit status
Why am I getting an undefined reference to a constructor despite not calling it?
But you are calling it.
Warrior(const string & _name, double _health, double _attackStrength, string _allegiance) : Character(WARRIOR, _name, _health, _attackStrength), allegiance(_allegiance){}
calls the constructor referenced in the error message, namely:
Character::Character(HeroType type, const string &name, double health, double attackStrength)
As Jeremy says, it looks like you are failing to include Character.cpp in your build, hence the 'undefined reference' errors.

Why I get this random weird number C++

I am new to using pointers with c++, so I am trying this small code but the problem is that when i try to print name i get this random weird number \364\277\357\376\326\241+\310\364\277\357\376\310. This is not the memory address, which is confusing and what confuses me more that when i replace name with getName() it works perfectly and prints the name! Thanks you!!
Person.cpp
#include "Pesron.hpp"
#include <string>
#include <iostream>
using namespace std;
Person:: Person()
{
}
Person::Person(string Name, int Age)
{
name=&Name;
age=Age;
}
void Person:: setName(string Name)
{
name=&Name;
}
void Person:: setAge(int Age)
{
age=Age;
}
string Person:: getName()
{
return *name;
}
int Person:: getAge()
{
return age;
}
void Person:: display()
{
cout<<*name<<" "<<age<<" ";
}
Person::~Person()
{
}
Student.cpp
#include "Student.hpp"
Student:: Student(string Name, int Age,int Grades, int ID):Person(Name , Age)
{
grades=Grades;
id=ID;
}
void Student:: setId(int ID)
{
id=ID;
}
int Student:: getId()
{
return id;
}
void Student:: setGrades(int Grades )
{
grades= Grades;
}
int Student:: getGrades()
{
return grades;
}
void Student:: display()
{
Person::display();
cout<<grades<<" "<<id<<endl;
}
main.cpp
#include "Pesron.hpp"
#include "Student.hpp"
#include "graduteStudent.hpp"
#include <iostream>
int main(int argc, const char * argv[]) {
// insert code here...
Student student("ZAID",21,2211,11);
student.display();
return 0;
}
Output
\364\277\357\376\326\241+\310\364\277\357\376\310 21 2211 11
Person::name looks like it is a std::string *. In Person::Person(string Name, int Age) you pass the paramater Name by value and then store the address of this local variable in name. When Name goes out of scope you have a dangling pointer.
(This also applies to void Person::setName(string Name))
Dereferencing Person::name is undefined behaviour, because the object it is pointing doesn't exist anymore. The solution is to simply store a std::string and not just a pointer to it.
So you get something like
class Person {
private:
std::string name;
int age;
public:
Person(std::string Name, int Age) : name(Name), age(Age) {}
};

C++ 'unknown type name' and 'use of undeclared identifier' errors

I am writing a small program, for a school project, that emulate a shared editor (like Google Docs)
I've written all the classes that I need but when I try to build the program I get this errors:
error: unknown type name 'NetworkServer'
NetworkServer &_server;
error: use of undeclared identifier 'SharedEditor' std::vector<SharedEditor*> SEditors;
error: expected expression std::vector<SharedEditor*> SEditors;
error: unknown type name 'SharedEditor' int connect(SharedEditor* sharedEditor);
Here are my .h files
NetworkServer.h
#include <vector>
#include <queue>
#include "SharedEditor.h"
#include "Message.h"
class NetworkServer {
private:
std::vector<SharedEditor*> SEditors;
std::vector<int> idEditors;
std::queue<Message> messages;
public:
int connect(SharedEditor* sharedEditor);
int disconnect(SharedEditor* sharedEditor);
void send(const Message& m);
void dispatchMessages();
};
SharedEditor.h
#include "NetworkServer.h"
#include "Message.h"
#include "Symbol.h"
class SharedEditor {
private:
NetworkServer& _server;
int _siteId{};
std::vector<Symbol> _symbols;
int _counter;
public:
SharedEditor() = delete;
SharedEditor(NetworkServer& server);
void localInsert(int index, char value);
void localErase(int index);
void process(const Message& m);
std::string to_string();
int getSiteId() const;
};
Symbol.h
#include <vector>
class Symbol {
private:
char value;
int idClient;
int num;
std::vector<int> pos;
public:
Symbol(char value, int client, int num, std::vector<int> pos);
char getValue() const;
int getIdClient() const;
int getNum() const;
const std::vector<int> &getPos() const;
};
Message.h
#include <vector>
class Message {
bool insert; // true --> insert || false --> delete
int _siteId;
int num;
char value{};
std::vector<int> pos;
public:
Message(bool insert, int siteId, int num, char value, std::vector<int> pos);
Message(bool insert, int siteId, int num);
bool isInsert() const;
int getSiteId() const;
int getNum() const;
char getValue() const;
const std::vector<int> &getPos() const;
};
I don't understand where I am doing something wrong. BTW I am using CLion

error: base operand of '->' has non-pointer type

This is my enum header file
//use like PostionType::President
enum PositionType
{ President,
VicePresident,
Secretary,
Treasurer,
Normal
};
And in my Ballot paper header and cpp file
#include <list>
#include <iostream>
#include "Candidate.h"
#include "PositionType.h" //include enum
class BallotPaper
{
private:
PositionType _positionbp;
std::list<Candidate> _candidatesbp;
public:
BallotPaper();
void setPositionBP(PositionType positionbp);
PositionType getPositionBP();
void setCandidateBP(std::list<Candidate> candidatesbp);
std::list<Candidate> getCandidateBP();
Candidate getCandidate(int index);
void ShowCandidates();
~BallotPaper();
};
#include "BallotPaper.h"
#include <string>
#include <iostream>
void BallotPaper::setPositionBP(PositionType positionbp)
{
_positionbp = positionbp;
}
PositionType BallotPaper::getPositionBP()
{
return _positionbp;
}
void BallotPaper::setCandidateBP(std::list<Candidate> candidatesbp)
{
_candidatesbp = candidatesbp;
}
std::list<Candidate> BallotPaper::getCandidateBP()
{
return _candidatesbp;
}
void BallotPaper::ShowCandidates()
{
for(Candidate c : _candidatesbp)
{
c->IncreaseVoteCount(); //ERROR!!!!
}
}
and this will be my candidate header and cpp file
class Candidate:public Member
{
private:
int _votecount;
PositionType _position;
public:
Candidate(std::string name, int id, std::string course, int contact, std::string joindate, PositionType currentposition) ;
~Candidate();
void setVoteCount(int votecount);
int getVoteCount();
void setPosition(PositionType position);
PositionType getPosition();
void IncreaseVoteCount(); //increase _votecount
};
#include "Candidate.h"
Candidate::Candidate()
{
_votecount = 0;
}
void Candidate::setVoteCount(int votecount)
{
_votecount = votecount;
}
int Candidate::getVoteCount()
{
return _votecount;
}
void Candidate::setPosition(PositionType position)
{
_position = position;
}
PositionType Candidate::getPosition()
{
return _position;
}
void Candidate::IncreaseVoteCount()
{
_votecount++;
}
I know is a super long code, and I appreciate for your patience in looking through it. My error is that it seems that it cannot recognize the function of "IncreaseVoteCount" in 'Candidate c'.
I have try to double check the syntax and the code for multiple times but i still don't understand what is the error here.

how can I use constructors in place of setter member functions

my program basically depends on setters to initialize the data in my object instances but I want to remove them and have constructors in place of the setters, Is there a way I can do this or can anybody provide me a reference?
Instantiate object
//Using SDL and standard IO
#include <SDL.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <iomanip>
#include <archer.hpp>
#include <ctime>
#include <ArmouredArcher.hpp>
#include <RNGI.hpp>
using namespace std; //Declaring use of namespace std
void instantiateMuskateer();
int main(int argc, char* argv[])
{
//init muskateer object
instantiateMuskateer();
system("pause");
return 0;
}
Instantiation, Activity and destruction
void instantiateMuskateer()
{
Archer* Muskateer = new Archer();
Muskateer->setName("Brett");
delete Muskateer;
}
.hpp file
#ifndef _Archer_
#define _Archer_
#include <string>
class Archer
{
public:
inline Archer() :
name(""),
healthpoints(0),
baseDamage(0),
range(0)
{ ; } //All Member varials are in a known state
inline Archer(std::string name, int healthpoints, int baseDamage, int range) :
name(name),
healthpoints(healthpoints),
baseDamage(baseDamage),
range(range) //All member variables are in a known state
{
;
}
inline ~Archer() { ; } // empty destructor
inline std::string getName() { return name; }
inline void setName(std::string name) { this->name = name; }
inline int getHealthPoints() { return healthpoints; }
inline void setHealthPoints(int healthpoints) { this->healthpoints = healthpoints; }
inline int getBaseDamage() { return baseDamage; }
inline void setBaseDamage(int baseDamage) { this->baseDamage = baseDamage; }
inline int getRange() { return range; }
inline void setRange(int range) { this->range = range; }
/*std::string getName(); //getter for name
void setName(std::string name); //Set the name
int getHealthPoints();
void setHealthPoints(int healthpoints);
int getBaseDamage();
void setBaseDamage(int baseDamage);
int getRange();
void setRange(int range); */
protected:
private:
// copy constructor
Archer(const Archer& other) = delete;
// overload assignment operator
Archer& operator=(const Archer& other) = delete;
std::string name;
int healthpoints;
int baseDamage;
int range;
};
#endif
In your example, it is really simple, you just have to take the parameters you need in your constructor:
Archer(std::string n) :
name(n),
healthpoints(0),
baseDamage(0),
range(0)
{} //All Member varials are in a known state
And then you can simply do that:
void instantiateMuskateer()
{
Archer* Muskateer = new Archer("Brett");
delete Muskateer;
}
A few comments not related, but to improve your code. Writing inline is useless when you declare and implement your functions inside your class, the inline is implied. Also, if your destructor does nothing, you should not define it or use = default, that way you can enable some optimizations from the compiler.
Also, in your previous function i see no need to allocate the object on the heap, it is again a loss of performance and a source of error (such as forgetting to delete the object), allocate it on the stack:
void instantiateMuskateer()
{
Archer Muskateer("Brett");
// do your things
}
Or use a unique_ptr.