Error on my first class when trying to display - c++

I'm building a class that will create a vehicle's characteristics and I'm having some difficulties when trying to display autovehicle a1 on the console. I get an error which I cannot explain. Please help, if possible
#include <iostream>
using namespace std;
class Autovehicle {
private:
//registry number
char * car_registration_number;
char engine;
int engine_cc;
int avg_consumption;
int avg_speed;
int avg_consumption_urban;
int avg_speed_urban;
int max_speed;
static int number_of_autovehicles;
public:
//getters
char * get_car_registration_number() {
return this->car_registration_number;
}
char get_engine()
{
return this->engine;
}
int get_engine_cc() {
return this->engine_cc;
}
int get_avg_consumption() {
return this->avg_consumption;
}
int get_avg_speed() {
return this->avg_speed;
}
int get_avg_consumption_urban() {
return this->avg_consumption_urban;
}
int get_avg_speed_urban() {
return this->avg_speed_urban;
}
int get_max_speed() {
return this->max_speed;
}
static int get_number_of_cars() {
return number_of_autovehicles;
}
//setters
void set_car_registration_number(char *car_reg_nr) {
this->car_registration_number = car_reg_nr;
}
void set_engine(char eng) {
this->engine = eng;
}
void set_engine_cc(int eng_cc) {
this->engine_cc = eng_cc;
}
void set_avg_consumption(int avg_cons) {
this->avg_consumption = avg_cons;
}
void set_avg_speed(int avg_spd) {
if (this->avg_speed > avg_spd)
cout << endl << "You should probably slow down";
this->avg_speed = avg_spd;
}
void set_avg_consumption_urban(int avg_cons_urb) {
this->avg_consumption_urban = avg_cons_urb;
}
void set_avg_speed_urban(int avg_spd_urb) {
if (this->avg_speed_urban > avg_spd_urb)
cout << endl << "You should probably slow down";
this->avg_speed_urban = avg_spd_urb;
}
void set_max_speed(int max_spd) {
this->max_speed = max_spd;
}
//default constructor
Autovehicle(){
number_of_autovehicles++;
this->car_registration_number = new char[strlen("There are no autovehicles") + 1];
strcpy(this->car_registration_number, "There are no autovehicles");
this->engine = NULL;
this->engine_cc = 0;
this->avg_consumption = 0;
this->avg_speed = 0;
this->avg_consumption_urban = 0;
this->avg_speed_urban = 0;
this->max_speed = 0;
}
//constructor
Autovehicle(char* car_reg_nr, char eng, int eng_cc, int avg_cons, int avg_spd, int avg_cons_urb, int avg_spd_urb, int max_spd){
number_of_autovehicles++;
this->car_registration_number = new char[strlen(car_reg_nr) + 1];
strcpy(this->car_registration_number, car_reg_nr);
this->engine = eng;
this->engine_cc = eng_cc;
this->avg_consumption = avg_cons;
this->avg_speed = avg_spd;
this->avg_consumption_urban = avg_cons_urb;
this->avg_speed_urban = avg_spd_urb;
this->max_speed = max_spd;
}
//destructor
~Autovehicle() {
delete[]this->car_registration_number;
number_of_autovehicles--;
}
};
This is where the void main, and the problem starts:
void main() {
Autovehicle a1( "Engniasd", "gasoline", 1980, 11, 50, 8, 100) {
cout<<"registration number: "<< this->car_registration_number;
cout << "engine: " << this->engine;
cout << "engine cc:" << this->engine_cc;
cout << "consumption: " << this->avg_consumption;
cout << "avg speed: " << this->avg_speed;
cout << "urban consumption: " << this->avg_consumption_urban;
cout << "urban speed " << this->avg_speed_urban;
}
}
The problem that I'm getting is "No instance of constructor matches the argument list" when trying to display Autovehicle a1(Engniasd, the first term)

Try to add the registration number to your car and the number of vehicles:
Autovehicle a1("REG12345", "gasoline", 1980, 11, 50, 8, 100, 50, 3).

Your constructor defines eng as a char, but you're passing it "gasoline" which is a const char*.
Also, storing the car registration number as a char*. Make your life easier and use a std::string instead. That way you, and your class users, don't need to worry about managing the lifetime of the pointer.
And, in main you've declared a variable called a1 but it looks like you are trying to call methods on it using this. You need to call against the instance variable:
cout << "engine: " << a1.engine;
You also need to terminate the a1 declaration with a semicolon and don't need the braces, eg:
Autovehicle a1( "Engniasd", "gasoline", 1980, 11, 50, 8, 100);
cout << "registration number: "<< a1.car_registration_number;

At school atm and unable to get a good look at this, but look at your constructor, you have a char instead of a char ptr for your 2nd argument. you can't implicitly convert char to const char*, you can char* -> const char*, so change your 2nd argument to a char*. Also, change void main() to int main(), main is supposed to be an int (ansi standard), and many compilers might not accept you using void main().

I see several problems.
Can you explain why car_registration_number and engine have different types?
If you can answer this one for yourself, you can fix one of your issues.
Also you should separate the class declaration from the implementation and make sure that you initialize all the variables. Including the static one.

Problems in calling constructor
Autovehicle(char* , char , int, int, int, int, int, int)
the second parameter is char, but you pass char*, also constructor have 6 int parameters, but you pass only five in main. And you cannot print values of object in your way. Create function in you class
void print()
{
cout<<"registration number: "<< this->car_registration_number;
cout << "engine: " << this->engine;
cout << "engine cc:" << this->engine_cc;
cout << "consumption: " << this->avg_consumption;
cout << "avg speed: " << this->avg_speed;
cout << "urban consumption: " << this->avg_consumption_urban;
cout << "urban speed " << this->avg_speed_urban;
}
and call it in main() as
Autovehicle a1( "Engniasd", "gasoline", 1980, 11, 50, 8, 100, 0);
a1.print();

Related

Why are my member functions/class variables outputting the wrong numbers?

I am learning how to use classes in c++. Right now I'm working on a small program which should display the miles per gallon of a vehicle based on the given number of miles and gallons. The assignment says to call member functions within the main function in order to set the member variables within the Auto class. Here is my code:
#include <iostream>
using namespace std;
class Auto {
public:
string model;
int milesDriven;
double gallonsOfGas;
double calculateMilesPerGallon(int milesDriven, double gallonsOfGas) {
return milesDriven / gallonsOfGas;
}
void setModel(string newModel){
model = newModel;
}
void setMilesDriven(int newMiles){
milesDriven = newMiles;
}
void setGallonsOfGas(double newGallons){
gallonsOfGas = newGallons;
}
void output(){
cout << "A " << model << " was driven " << milesDriven << " miles, and used " << gallonsOfGas << endl;
cout << "This car gets " << calculateMilesPerGallon(milesDriven, gallonsOfGas) << "mpg.";
}
};
int main()
{
Auto modelFunction;
Auto milesFunction;
Auto gasFunction;
Auto outputFunction;
string carModel = "Toyota Camry";
int carMiles = 100;
double carGallons = 10;
modelFunction.setModel(carModel);
milesFunction.setMilesDriven(carMiles);
gasFunction.setGallonsOfGas(carGallons);
outputFunction.output();
return 0;
}
It's supposed to display something like "A Toyota Camry was driven 100, and used 10 gallons of gas, and gets 10 mpg." Instead, my output shows "A was driven -1538932792 miles, and used 4.66265e-310
This car gets -infmpg." What am I doing that is causing the output to be like this? I just started using classes so I don't have much experience with them. Thanks for the advice.
The error you're encountering is because you're creating four different Auto objects, each of which will have their own member variables. If you change your main function to the following, it will work:
int main()
{
Auto car;
string carModel = "Toyota Camry";
int carMiles = 100;
double carGallons = 10;
car.setModel(carModel);
car.setMilesDriven(carMiles);
car.setGallonsOfGas(carGallons);
car.output();
return 0;
}
Note that there is now only one 'Auto' object entitled 'car'.
You have to create only one instance of class Auto cause you only want to show the info for one car (with the name "Toyota Camry").
#include <iostream>
using namespace std; // strongly encouraging you to avoid using this
// in file scope
class Auto {
public:
string model;
int milesDriven;
double gallonsOfGas;
double calculateMilesPerGallon(/*no params required*/) {
return milesDriven / gallonsOfGas;
}
void setModel(string newModel){
model = newModel;
}
void setMilesDriven(int newMiles){
milesDriven = newMiles;
}
void setGallonsOfGas(double newGallons){
gallonsOfGas = newGallons;
}
void output(){
cout << "A " << model << " was driven " << milesDriven << " miles, and used " << gallonsOfGas << endl;
cout << "This car gets " << calculateMilesPerGallon() << "mpg.";
}
};
int main()
{
string carModel = "Toyota Camry";
int carMiles = 100;
double carGallons = 10;
Auto car;
car.setModel(carModel);
car.setMilesDriven(carMiles);
car.setGallonsOfGas(carGallons);
car.output();
return 0;
}

Polymorphism program

I am needing help with polymorphism. I have no clue how to work with this. I have to write a program that creates an Orc and a Human and demonstrates the behavior of the classes. I am just needing some help with setting this program up. I have set up the classes with the information, but how do I get the createCharacter function to work? Would I have characterTotal = characterStrength + characterDexterity + characterIntelligence in the createCharacter function? I know my program is not correct right now and I have some errors and things, but I am still just trying to get a better understanding of this.
UPDATE:
I am having trouble with the createCharacter function. It is a pure virtual function and I am needing some help on how to get it to work.
For Human class createCharacter will:
Get the values of STR, DEX and INT. Will calculate the total of the values.
(Let’s assume STR = 17, DEX = 12 and INT = 10. It will store 37 into characterTotal.Itwill print out a message: “The strong human Paladin, has a total scoreof 37.” (Strong adjective comes due to STR being 17. If something is above 17 you should say something related. STR = strong, DEX = dexterous, INT =
intelligent).
For Orc class createCharacter will:
Get the values of STR, DEX and INT. Will calculate the total of the values.
However Orcs receive -2 to INT and DEX. They receive +2 to STR. (Let’s
assume STR = 16, DEX = 10 and INT = 8. It will store 16+2,10-2,8-2 = 28 into
characterTotal.
It will print out a message “The berserker Orc has a total score of 28.” (Here the
Orcs get their adjectives from their clan names so you do not need to do
something specific to STR, DEX or INT.)
CODE:
//character.h
#ifndef CHARACTER_H
#define CHARACTER_H
using namespace std;
class Character
{
protected:
float characterTotal;
public:
virtual void createCharacter() = 0; //Pure virtual function
};
#endif
//human.h
#ifndef HUMAN_H
#define HUMAN_H
#include "Character.h"
using namespace std;
class Human
{
private:
int characterStrength;
int characterDexterity;
int characterIntelligence;
string characterType;
public:
Human();//Constructor
int getStength
{
cout << "Enter a number from 0 to 18\n";
cin >> characterStrength;
return characterStrength;
}
int getDexterity
{
cout << "Enter a number from 0 to 18\n";
cin >> characterDexterity;
return CharacterDexterity;
}
int getIntelligence
{
cout << "Enter a number from 0 to 18\n";
cin >> characterIntelligence;
return characterIntelligence;
}
string getType
{
cout << "Please choose one of the following\n";
cout << "A -- Paladin \n";
cout << "B -- Ranger \n";
cout << "C -- Wizard \n";\
cin >> characterType;
return characterType;
}
};
#endif
//orc.h
#ifndef ORC_H
#define ORC_H
#include "Character.h"
#include "Human.h"
using namespace std;
class orc
{
private:
int characterStrength;
int characterDexterity;
int characterIntelligence;
string characterClan;
public:
orc(); //Constructor
int getStrength
{
cout << "Enter a number between 0 to 18\n";
cin >> characterStrength;
return characterStrength;
}
int getDexterity
{
cout << "Enter a number between 0 to 18\n";
cin >> characterDexterity;
return characterDexterity;
}
int getIntelligence
{
cout << "Enter a number between 0 to 18\n";
cin >> characterIntelligence;
return characterIntelligence;
}
string getClan
{
cout << "Please choose one of the following\n";
cout << "A -- Barbarian \n";
cout << "B -- Berserker \n";
cout << "C -- Vanguard \n";\
cin >> characterClan;
return characterClan;
}
};
#endif
Example: A class called Account posesses a container with Character. Your classes Human and Orc inherit both from Character. Inside of your Human class you may want to set spell ABC to all characters which are created (in createCharacter). But if the player creates an Orc, you might want to set another spell XYZ to it, instead of ABC. Base classes come in handy here. In this example you see one of these abstract functions in action (Character::initCharacter).
You can put in more abstract functions inside of Character IF the classes which are supposed to inherit from Character MUST / NEED TO implement these functions.
This is only an example. If you want to do it properly, you need more than this and would have to modify all for database access and further abstraction.
enum CharacterType
{
CHAR_INVALID = 0x0,
CHAR_HUMAN = 0x1,
CHAR_ORC = 0x4
};
class Character
{
public:
Character(unsigned int charGUID) //You might want to set data in the constructor already
: m_charGUID(charGUID) //right after it has been load from Account::LoadAccountInformation()
{
std::cout << "Constructor of \"Character\"" << std::endl;
}
virtual ~Character(void) //Cleanup if needed
{
std::cout << "Destructor of \"Character\"" << std::endl;
}
virtual void createCharacter(void) = 0;
virtual void initCharacter(void) = 0;
CharacterType GetTypeID(void)
{ return m_typeID; }
protected:
void SetTypeID(CharacterType ct)
{ m_typeID = ct; }
private:
Character(const Character &);
unsigned int m_charGUID;
CharacterType m_typeID;
};
class Human : public Character
{
public:
Human(unsigned int charGUID)
: Character(charGUID)
{
SetTypeID(CHAR_HUMAN);
std::cout << "Constructor of \"Human\"" << std::endl;
}
virtual ~Human(void) //Cleanup if needed
{
std::cout << "Destructor of \"Human\"" << std::endl;
}
void createCharacter(void) override
{
//Set data...
}
void initCharacter(void) override
{
std::cout << "You initialized a character of type \"Human\"" << std::endl;
}
};
class Orc : public Character
{
public:
Orc(unsigned int charGUID)
: Character(charGUID)
{
SetTypeID(CHAR_ORC);
std::cout << "Constructor of \"Orc\"" << std::endl;
}
virtual ~Orc(void) //Cleanup if needed
{
std::cout << "Destructor of \"Orc\"" << std::endl;
}
void createCharacter(void) override
{
//Set data...
}
void initCharacter(void) override
{
std::cout << "You initialized a character of type \"Orc\"" << std::endl;
}
};
class Account
{
public:
Account(unsigned int accountGUID)
{ m_accGUID = accountGUID; }
//#Return: False if load from database failed
bool LoadAccountInformation(void) //You could give it data also
{
//You could also load data directly from a database here if you'd like to
//Here are just some sample values (partially hardcoded)
characters.clear();
const int charsOnAccount = 1; //Load from database
for (int i = 0; i < charsOnAccount; ++i)
{
CharacterType ct = CHAR_HUMAN; //Load from database
unsigned int characterGUID = i;
switch (ct)
{
case CHAR_HUMAN:
{
characters[characterGUID] = std::move(std::shared_ptr<Character>(new Human(characterGUID)));
} break;
case CHAR_ORC:
{
characters[characterGUID] = std::move(std::shared_ptr<Character>(new Orc(characterGUID)));
} break;
default:
{
std::cout << "Invalid character type: " << ct << std::endl; //Or log to file
} break;
}
}
return true;
}
void InitCharacters(void)
{
for (auto itr = std::begin(characters); itr != std::end(characters); ++itr)
itr->second->initCharacter();
}
private:
//A unique account-GUID
unsigned int m_accGUID;
//Let's say a unique char-GUID and the Character object
std::map<unsigned int, std::shared_ptr<Character> > characters;
//And more information...
};
int main(int argc, char *argv[])
{
Account ac = Account(1);
ac.LoadAccountInformation();
ac.InitCharacters();
return 0;
}

Undefined Reference c++ lost

#include "assert.h"; // for some reason assert wouldn't work on my compiler without this
#include <iostream>
#include <string>
#include <limits> // This is helpful for inputting values. Otherwise, funny stuff happens
using namespace std;
class Product
{
public:
Product();
Product(string the_name, int the_price, int number_of);
string return_name();
void reduce_amount();
void print_data() const;
private:
string prod_name; // name of your product
int price_in_cents; // it's price in cents
int amount; // the number of the product that you have
};
Product::Product()
{
prod_name = "NULL_NAME: NEED DATA";
price_in_cents = 0;
}
Product::Product(string the_name, int the_price, int number_of)
{
assert(the_price>0);
assert(number_of>0);
assert(number_of<21);
assert(prod_name !="NULL_NAME: NEED DATA");
prod_name = the_name;
price_in_cents = the_price;
amount = number_of;
}
void Product::print_data() const
{
cout<<prod_name << endl;
cout<<"The price in cents is: " <<price_in_cents<< endl;
cout<< "Amount left: " << " " << amount << endl;
}
void Product::reduce_amount()
{
amount = amount -1;
}
string Product::return_name()
{
return prod_name;
}
class Vending_Machine
{
public:
Vending_Machine();
void empty_coins();
void print_vend_stats();
void add_product();
Product buy_product();
private:
int income_in_cents;
Product product1();
Product product2();
Product product3();
Product product4();
Product product5();
};
void Vending_Machine::empty_coins()
{
cout << "The total amount of money earned today is " << income_in_cents << " cents" << endl;
income_in_cents = 0;
cout << "All the coins have been withdrawn. The balance is now zero." << endl;
}
void Vending_Machine::print_vend_stats()
{
cout<< "Total income thus far: " << income_in_cents << endl;
if (product1().return_name() != "NULL_NAME: NEED DATA")
{
//stuff happens
}
}
int main()
{
return 0;
}
So, I'm not sure if I did all the identation correctly, but I'm having a problem with the boolean statement in vending machine print_vend_stats() function. It's saying I am making an undefined fereence to product1(). What does this mean?
When you declare
Product product1();
you declare a member function, the parentheses is what makes it a function.
If you drop the parentheses
Product product1;
you declare a member variable, an actual instance of the Product class.
Another example, you wouldn't write e.g.
int income_in_cents();
do declare income_in_cents as a variable, now would you?
It doesn't matter if the type is a primitive type like int, or a class like Product, Member variables are declared like normal variables like you do anywhere else.

Concept of data storing in c++

I have a Spieler class and a Verein class with a vector of Spieler members.
Now if I change something of the Players like the Staerke(german for strength) by using a function of this class in the player class it does not automatically change the value for this player.
Here is the code:
#include <vector>
#include<iostream>
#include <string>
using namespace std;
class Spieler
{
public:
void setinformation(int a, string b, string c, int d)
{
ID = a;
Vorname = b;
Nachname = c;
Staerke = d;
}
void getinformation()
{
cout << "ID: " << ID << endl;
cout << "Vorname: " << Vorname << endl;
cout << "Nachname: " << Nachname << endl;
cout << "Staerke: " << Staerke << endl << endl;
}
void setStaerke(int x)
{
Staerke = x;
}
int getStaerke()
{
return Staerke;
}
private:
string Vorname, Nachname;
int Staerke, ID;
};
class Verein
{
public:
void setSpielerListe(vector<Spieler> x)
{
Spielerliste = x;
}
vector<Spieler> getSpielerListe()
{
return Spielerliste;
}
string getVereinsName()
{
return VereinsName;
}
int getVereinsID() const
{
return VereinsID;
}
void setVereinsID(int x)
{
VereinsID = x;
}
int getGesamtstaerke()
{
Gesamtstaerke = 0;
vector<Spieler> b;
b = getSpielerListe();
for (size_t i = 0; i < b.size(); i++)
{
Gesamtstaerke = Gesamtstaerke + b[i].getStaerke();
}
return Gesamtstaerke;
}
void Vereinsinformationen()
{
vector<Spieler> list;
int id;
string vereinsname;
int gesamtstaerke;
id = getVereinsID();
vereinsname = getVereinsName();
gesamtstaerke = getGesamtstaerke();
list = getSpielerListe();
cout << "VereinsID: " << id << endl;
cout << "Vereinsname: " << vereinsname << endl;
cout << "Gesamstaerke: " << gesamtstaerke << endl << endl;
cout << "Spieler: " << endl;
for (size_t i = 0; i < list.size(); i++)
list[i].getinformation();
}
private:
vector<Spieler> Spielerliste;
int VereinsID, Gesamtstaerke;
string VereinsName;
};
vector<Spieler> spieler;
int main()
{
Spieler Spieler1;
Spieler1.setinformation(0, "Peter", "Pan", 10);
spieler.emplace_back(Spieler1);
Verein Team1;
Team1.setSpielerListe(spieler);
Spieler1.setStaerke(20);
Team1.Vereinsinformationen();
cin.get();
return 0;
}
I'm really new into c++ and programming so the code might be terrible.
Guess it has to do with pointers, I'm really not into the concept of storing data in c++, try to get it by trial & error; So how to change the Staerke in a way that it is changed in the Teams Playerlist too?
The problem is you are storing full object in the vector and not pointers. When you run this line:
spieler.emplace_back(Spieler1);
a copy of Spieler1 is made and put in the vector. So modifying it in the main will have no effect in the vector. Also not that you are copying the vector when setting in Verein class.
You should use pointer if this is what you are after or better yet have a function to modify strength from Verein class taking its id and new strength as parameters might be a good idea. Something like this:
void setStaerke(int id, int x)
{
vector<Spieler>::iterator it = Spielerliste.begin();
while (it != Spielerliste.end())
{
if ((*it).GetId() == id)
{
(*it).setStaerke(x);
break;
}
}
}
If you have access to C++11, it could be made more elegantly.
Hereby you pass and store a copy from the vector into the object:
Team1.setSpielerListe(spieler);
Therefore changes to the original vector and the contained objects will not affect the member.
Further, I don't have much experience with emplace_back, but the more usual way to append an object to a std::vector would also append a copy:
spieler.push_back(Spieler1);
Therefore changes to the original object would not affect the object you've appended to the container.
Make sure you better understand when objects are copied.
For reference:
http://en.cppreference.com/w/cpp/container/vector/emplace_back
http://en.cppreference.com/w/cpp/container/vector/push_back
How to pass objects to functions in C++?

c++ Passing a value the wrong way?

When i am passing an object to a function, I am getting undesired results. It seems to happen when I pass a Character through a Mage's action() function.
Here are some snippits of my code:
character.h
class Character {
public:
Character();
int getMaxLives() const;
int getMaxCraft() const;
protected:
maxLives;
maxCraft;
};
character.cpp
#include "character.h"
Character::Character () {
maxLives = 5;
MaxCraft = 10;
}
int Character::getMaxLives() const {
return maxLives;
}
int Character::getMaxCraft() const {
return maxCraft;
}
mage.h
#include "character.h"
class Mage {
public:
Mage();
void action(Character c1);
};
mage.cpp
#include "mage.h"
Mage::Mage () { ... }
void Mage::action(Character c1) {
cout << "Max Craft: " << c1.getMaxCraft() << endl;
cout << "Max Lives: " << c1.getMaxLives() << endl;
}
driver.cpp
int main () {
Character c1;
Mage m1;
m1.action(c1);
My ouput gives me the following:
Max Craft: 728798402 (The number varies)
Max Lives: 5
However, if in my diver, i do:
cout << "Max Craft: " << c1.getMaxCraft() << endl;
cout << "Max Lives: " << c1.getMaxLives() << endl;
I get:
Max Craft: 10
Max Lives: 5
Any ideas?
Looks like you meant for MaxCraft = 10; (in your default constructor) to actually be maxCraft = 10;. As #chris says in the comments, it appears that you're using some (evil, evil) C++ extension that allows implicitly-typed variables, so the MaxCraft = 10; line is simply defining a new variable named MaxCraft.