This question already has answers here:
C++: Initialization of inherited field
(5 answers)
Closed 5 years ago.
This post was edited and submitted for review 12 months ago and failed to reopen the post:
Original close reason(s) were not resolved
I want to create a base class with two set, and derived class (inherit) with one set method. I want to combine them in a parameterized constructor.
#include <iostream>
#include <string.h>
using namespace std;
class Code
{
protected:
string letter;
int number;
public:
string getletter();
int getnumber();
void setletter(string letter1);
void setnumber(int number1);
};
void Code::setletter(string letter1)
{
letter=letter1;
}
void Code::setnumber(int number1)
{
number=number1;
}
string Code::getletter()
{
return letter;
}
int Code::getnumber()
{
return number;
}
class Course : public Code
{
private:
string name;
public:
Course(string name1, string letter1, int number1);
string getname();
void show();
};
Course::Course (string name1, string letter1,int number1) :
setletter(letter1), setnumber(number1) //Parameterized Constructor
{
name=name1;
letter=letter1;
number=number1;
}
string Course::getname()
{
return name;
}
void show()
{
Course com("Testing","TST",101);
cout<<"Constructor >>>\n Course Name : "<< com.getname()<<"\n Course Code : "<< com.getletter() << com.getnumber()<<endl;
}
int main()
{
show();
}
If it matters, I am using Microsoft's Visual C++.
You can call them inside your constructor
Course::Course (const string& name1, const string& letter1, const int number1) :
{
name=name;
setletter(letter1); // equivalent to letter=letter1
setnumber(number1);
}
You can add a constructor to your Code class
Code(const string& letter, const int number);
And call it like that in your Course constructor
Course::Course(const string& name1, const string& letter1, const int number1)
: Code(letter1, number1), name(name1)
{
}
But I'm not sure of what your asking, if you can be a little more precise on what you want that could be great, thanks.
The : after the parameter list of a constructor is the 'member initializer list'.
Course::Course (string name1, string letter1,int number1)
: name(name1), letter(letter1), number(number1) { }
Related
Im a newbie in c++ and recently discovered classes;
I learned about constructors, overloading operators, the rule of three and right now i tried to learn inheritance.
I created 4 classes: 2 parents, 2 childs, but i occured some problems in class parent1
This is class parent1:
class parent1{
protected:
float slr;
int age;
char *name;
void set_new_name(char ch[10001]);
public:
parent1()
{
slr=0.0;
age=0;
name=NULL;
}
parent1(char ch[10001], float sl, int ag)
{
slr=sl;
age=ag;
set_new_name(ch);
}
parent1(const parent1 &p1)
{
char temp[10001];
strcpy(temp,p1.name);
if(name != NULL)
delete[] name;
set_new_name(temp);
slr=p1.slr;
age=p1.age;
}
parent1 &operator=(const parent1 &p1)
{
/// same lines as in copy constructor above
return *this;
}
char* get_name() const;
void print1();
~parent1()
{
delete[] name;
}
};
This is his child class, child1:
class child1 : public parent1{
protected:
int id;
void set_id(int j);
public:
child1(): parent1()
{
set_id(0);
}
child1(char ch[10001],float sl, int ag, int j): parent1(ch,sl,ag)
{
set_id(j);
}
child1(const child1 &p2): parent1(p2)
{
set_id(p2.get_id());
}
child1 &operator=(const child1 &p2)
{
set_id(p2.get_id());
parent1::operator=(p2);
}
int get_id() const;
void print2();
};
There is class parent 2:
class parent2{
protected:
char *name1;
char *name2;
void set_new_name1(char ch1[10001]);
void set_new_name2(char ch2[14]);
public:
parent2()
{
name1=NULL;
name2=NULL;
}
parent2(char ch1[10001], char ch2[14])
{
set_new_name1(ch1);
set_new_name2(ch2);
}
parent2(const parent2 &p3)
{
char temp2[10001];
strcpy(temp2,p3.name1);
if(name1 !=NULL)
delete[] name1;
set_new_name1(temp2);
/// .. . same lines as above, this time for name2 and p3.name2
}
parent2 &operator=(const parent2 &p3)
{
/// .. same lines as in copy constructor above
return *this;
}
char* get_name1() const;
char* get_name2() const;
void print3();
~parent2()
{
delete[] name1;
delete[] name2;
}
};
And there is his child, child 2:
class child2: public parent2{
protected:
char *job;
void set_new_job(char ch3[15]);
public:
child2(): parent2()
{
job=NULL;
}
child2(char ch1[10001], char ch2[10001],char ch3[11]): parent2(ch1,ch2)
{
set_new_job(ch3);
}
child2(const child2 &p4): parent2(p4)
{
char temp6[11];
strcpy(temp6, p4.job);
if(job != NULL)
delete[] job;
set_new_job(temp6);
}
child2 &operator=(const child2 &p4)
{
/// same lines as in copy constructor
parent2::operator=(p4);
}
char* get_job() const;
void print4();
~child2()
{
delete[] job;
}
};
As u can see up here, class parent1 have 3 types of parameters ( one float, one int and one char*).
Nonte: set_ functions works ok, get_functions just return class parametes (also works ok) , print functions just print classes parameters ( ex: cout << name1; also works fine)
The problem is that this code refuse to work when i create the objects in main.
First i thought it is operator= being overloaded to many times, bit it turned out to be the float parameter from parent1
There is the main:
char ch[10001]="my name", ch1[10001]="my name 1", ch2[14]="my name 2", ch3[11]="some code";
int ag=10;
float sl=10.1;
parent1 o1;
o1=parent1(ch,sl,ag);
o1.print1();
parent1 o2(o1);
o2.print1();
child1 o3;
o3=child1(ch,sl,ag,3);
o3.print2();
child1 o4;
o4=child1(ch,sl,ag,6);
o4.print2();
o4=o3;
o4.print2();
parent2 o5;
o5=parent2(ch1,ch2);
o5.print3();
child2 o6(ch1,ch2,ch3);
o6.print4();
The only things that seems to make it run are:
deleting the float parameter from parent1;
deleting the last class ; (i really don't know why the last class affect the program)
creating the last object like this : child2 o6(ch1,ch2,ch3); , which is frustrating because it should work like the others;
I know the code i sheared is very long, but Please , Help me to understand what i need to do to solve this stupid bug !
I see at least 3 issues in the code that will lead to a crash/undefined behavior.
First:
parent1(const parent1 &p1)
{
char temp[10001];
strcpy(temp,p1.name);
if(name != NULL) // name isn't initialized yet,
delete[] name; // these 2 lines shouldn't be here
set_new_name(temp);
slr=p1.slr;
age=p1.age;
}
Second: (these ones are reported by the compiler when warnings are enabled)
child1 &operator=(const child1 &p2)
{
set_id(p2.get_id());
parent1::operator=(p2);
return *this; // this line is missing
}
Third:
child2 &operator=(const child2 &p4)
{
char temp7[11];
strcpy(temp7, p4.job);
if(job != NULL)
delete[] job;
set_new_job(temp7);
parent2::operator=(p4);
return *this; // this line is missing
}
The return statement is not "inherited". Each function that's supposed to return something must do so.
With these changes the code runs:
my name
my name
3
6
3
my name 1
my name 2
some code
(Live demo)
Some additional improvement notes:
An array like char ch[10001] can't really be a function argument in C++. When it's used as an argument it silently decays to char *. So you might as well replace all char ch[10001] with const char* ch (and better yet, std::string), to avoid confusion.
Also, there's no point in allocating a temp array. You can just directly do set_new_name(p1.name):
parent1(const parent1 &p1)
{
set_new_name(p1.name);
slr=p1.slr;
age=p1.age;
}
It would be prudent to invest some time in getting familiar with a Debugger. It's all but impossible to make a working application without debugging it. And enable compiler warnings. With GCC use -Wall -Wextra, with MSVC - /W4.
Here's an example of the code using std::string. Thanks to std::string we can follow the rule of 0:
class parent1 {
protected:
float slr = 0;
int age = 0;
string name;
void set_new_name(string const &ch) { name = ch; }
public:
parent1() {}
parent1(string const &name, float slr, int age)
: slr(slr), age(age), name(name) {}
string const &get_name() const { return name; }
void print1();
};
void parent1::print1() { cout << get_name() << '\n'; }
class child1 : public parent1 {
protected:
int id = 0;
void set_id(int j) { id = j; }
public:
child1() : parent1() {}
child1(string const &name, float sl, int ag, int j)
: parent1(name, sl, ag), id(j) {}
int get_id() const { return id; }
void print2();
};
void child1::print2() { cout << get_id() << '\n'; }
class parent2 {
protected:
string name1;
string name2;
void set_new_name1(string const &ch) { name1 = ch; }
void set_new_name2(string const &ch) { name2 = ch; }
public:
parent2() {}
parent2(string const &name1, string const &name2)
: name1(name1), name2(name2) {}
string const &get_name1() const { return name1; }
string const &get_name2() const { return name2; }
void print3();
};
void parent2::print3() {
cout << get_name1() << '\n';
cout << get_name2() << '\n';
}
class child2 : public parent2 {
protected:
string job;
void set_new_job(string const &ch) { job = ch; }
public:
child2() : parent2() {}
child2(string const &name1, string const &name2, string const &job)
: parent2(name1, name2), job(job) {}
string const &get_job() const { return job; }
void print4();
};
void child2::print4() { cout << get_job() << '\n'; }
And this works equally well.
When I initialize hp, damage, and speed and call the getters, the values returned are not the initialized values, but rather larger negative numbers. What am I missing? Here is my base class and my main.cpp
class Character
{
public:
//constructor to initialize data members
explicit Character(string cname)
: name{ cname }, hp{ 10 }, damage{ 5 }, speed{ 2 }
{}
Character();
//call to member function that problem Character depending on user inputs
virtual void special(); //polymorphic special attack
int getHp()
{
return hp;
}
string getName()
{
return name;
}
int getDamage()
{
return damage;
}
int getSpeed()
{
return speed;
}
void setName(std::string cname)
{
name = cname;
}
private:
string name;
int hp;
int damage;
int speed;
int main()
{
string name = "";
int choice = 0;
//declare Picker class
Warrior war;
Mage mage;
Assassin assn;
std::vector<Character*> cptr(3);
cptr[0] = &war;
cout << "Please enter a name for your character\n";
cin >> name;
war.setName(name);
cout << "Here are your characters attributes\n\n";
cout << "Name is: " << war.getName() << "\n";
Calling the base class directly works fine, going through the derived class gives me the large negative number
Adding derived class:
#ifndef Warrior_H
#define Warrior_H
#include "Character.h"
#include <iostream>
using std::cout;
class Warrior: public Character
{
public:
//constructor to initialize data members
explicit Warrior()
: attack{ "Berserker Strike" }, weapon {"War Hammer"}
{}
void special(); //polymorphic special attack
void basic();
string getClassWeapon() { return weapon; }
private:
string attack;
string weapon;
};
You need to invoke the right constructor of the base class:
explicit Warrior() : Character(""), attack{ "Berserker Strike" }, weapon {"War Hammer"} {}
or update the default constructor to initialize those variables (you might be able to invoke the explicit constructor you already have or use a separate init function):
Character() : name{""}, hp{10}, damage{5} {}
I am a newbie in c++ and today I was trying to make access a public class member outside of main(), more exactly in another function.
I tried to create pointer to that class, but I fail at accessing its members. I am going to show an example with a few lines of code, Any help would be appreciated.
Class City
{
private:
string name;
public:
string getName()
{
return name;
}
};
bool isCity(string input)
{
if(input== ???) { return true; }
return false;
}
*The problem: how to access public member getName() from the class I create in main() at the question marks
int main()
{
string input;
City test;
cin >> input;
isCity(input);
cin.get();
}
The pointer to Class is not working, the reference pass isn't working either.
Easiest way is to have isCity part of the class and call it as a method of the object test.isCity(input);
The class should be as follow:
Class City
{
private:
std::string name;
public:
std::string getName() const
{
return name;
}
bool isCity(const std::string& input) const
{
return input.compare(name) == 0
}
};
Else you could have a free function (outside of the class), but the signature should provide the class city object as follow:
bool isCity(const City& c, const std::string& input)
{
return input.compare(c.GetName()) == 0;
}
Which then means you have to call the function as follow:
isCity(test, input);
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
I would like to make this programm show the "Gianna" "Maria" and "M" strings on the screen but I can't. There's no error so I guess there's something wrong with my programm. Any suggestions what could fix my programm?
#include <iostream>
#include <string>
using namespace std;
class name
{
string fName, mName, sName;
public:
name (string fName, string mName, string sName){};
void setFName (string fName);
void setMName (string mName);
void setSName (string sName);
string getFName() const {return fName;}
string getSName() const {return sName;}
string getMName() const {return mName;}
friend ostream & operator <<(ostream &, const name &);
};
ostream& operator<<(ostream& os, const name& n) {
return os << n.fName << " " << n.sName<< " " << n.mName;
}
int main ()
{
name myName ("Gianna", "Maria", "M");
cout<<myName.getFName()<<" "<<myName.getMName()<<" "<<myName.getSName()<<endl;
return 0;
}
Your constructor:
name (string fName, string mName, string sName){};
doesn't do anything. You need to use the parameters to initialise your member variables.
name (string f, string m, string s)
: fName(f), mName(m), sName(s) {}
You forgot to initialize daya members of the class in the constructor.
Define the constructor the following way
name( const string &fName, const string &mName, const string &sName )
: fName( fName ), mName( mName ), sName( sName )
{
}
Correspondingly these member functions should be defined like
void setFName ( const string &fName)
{
this->fName = fName;
}
void setMName (const string &mName)
{
this->mName = mName;
}
void setSName (const string &sName)
{
this->sName = sName;
}
There is no need to make the operator << as a friend function of the class. It can be defined like
ostream& operator <<( ostream& os, const name& n ) {
return os << n.getFName() << " " << n.getMName() << " " << n.getSName();
}
Your constructor must assign the parameters you pass to the member variables, that doesn't happen automatically.
name (string fName, string mName, string sName) : fName(fName), mName(mName), sName(sName) {};
For your constructor, you have the three strings as your parameters but you aren't setting the member variables to their values. You can use an initializer list on the constructor like this...
name (string f, string m, string s)
: fName(f), mName(m), sName(s) // member(parameter) format
{
}
...or you can implement the setter stubs you have...
void setFName(string name) { this->fName = name;}
... and use them inside of your constructor like...
name (string fName, string mName, string sName) {
setFName(fName);
//...
}
Basically the parameters passed in the constructor are getting lost since you are not assigning it to the class vars..
Do something like:
name (string f, string m, string s) : fName(f), mName(m), sName(s){....};
try this. You forgot to implement Constructor of the class
#include <iostream>
#include <string.h>
using namespace std;
class name
{
string sFName, sMName, sSName;
public:
name (string FName, string MName, string SName);
void Display();
void setFName (string fName);
void setMName (string mName);
void setSName (string sName);
string getFName() const {return sFName;}
string getSName() const {return sSName;}
string getMName() const {return sMName;}
};
name::name(string FName, string MName, string SName )
{
sFName = FName;
sMName = MName;
sSName = SName;
}
void name::setFName(string fName)
{
sFName = fName;
}
void name::setMName(string mName)
{
sMName = mName;
}
void name::setSName(string sName)
{
sSName = sName;
}
void name::Display()
{
cout<< sFName<< endl;
cout<< sMName<< endl;
cout<< sSName<< endl;
}
int main ()
{
name myName ("Gianna", "Maria", "M");
myName.Display();
return 0;
}
I recently started playing around with c++, but for I don't understand what this means:
I get this error:
declaration is incompatible with "void
student_system::addStudent(<error-type> z)" (declared at line 31)
and the same goes for removeStudent and editStudent
I copied over the "function()" from another stackoverflow post, which seems fine and added the header with no issues, but my own "student" methods don't seem to work, I do not understand why,
I also tried adding the pointers rather than the variable but that didn't work either ( and by pointer I mean " student *x ").
#include "database.h"
#include <vector>
int main()
{
return 0;
}
class student_system
{
private:
list<student> studList;
public:
student_system();
void addStudent(student x);
void removeStudent(student y);
void editStudent(student z);
void findPos();
void function(int a, int b, vector<int> *p);
};
student_system::student_system()
{
//constructor
}
void student_system::addStudent(student x) // <------------- LINE 31
{
studList.push_back(x);
}
void student_system::removeStudent(student y)
{
/*studList.rem*/
}
void student_system::editStudent(student z)
{
/*get{ return value; }
set{ }*/
}
void student_system::findPos()
{
}
void student_system::function(int a, int b, vector<int> *p)
{
}
class student
{
private:
string name, surname, ID;
int sid;
public :
student::student(int sid, string n, string s, string id);
};
student::student(int sid, string n, string s, string id)
{
(*this).sid = sid;
(*this).name = n;
(*this).surname = s;
(*this).ID = id;
}
Put this bit of code
class student
{
private:
string name, surname, ID;
int sid;
public :
student::student(int sid, string n, string s, string id);
};
Just after the
#include <vector>
So that student_system and its definitions know about it
Add class student; above your student_system class definition.
Edit
Using forward declarations we can only declare methods in which we can use incomplete type not define. So, my first answer was wrong, but the following code will work.
int main()
{
return 0;
}
// Forward Declaration
class student;
// ================================
// Class student_system
// ================================
class student_system
{
private:
list<student> studList;
public:
student_system();
void addStudent(student x);
void removeStudent(student y);
void editStudent(student z);
void findPos();
void function(int a, int b, vector<int> *p);
};
// ================================
// Class student
// ================================
class student
{
private:
string name, surname, ID;
int sid;
public :
student(int sid, string n, string s, string id);
};
// ================================
// Definition of methods
// ================================
student::student(int sid, string n, string s, string id)
{
(*this).sid = sid;
(*this).name = n;
(*this).surname = s;
(*this).ID = id;
}
student_system::student_system()
{
//constructor
}
void student_system::addStudent(student x)
{
studList.push_back(x);
}
void student_system::removeStudent(student y)
{
/*studList.rem*/
}
void student_system::editStudent(student z)
{
/*get{ return value; }
set{ }*/
}
void student_system::findPos()
{
}
void student_system::function(int a, int b, vector<int> *p)
{
}
1) Please simplify a problem down to its basest elements before posting.
2) Please don't post code that relies on non-provided includes or implicit "using" statements or the like
3) "student" should be declared before student_system. The fact that you're not getting more errors surprises me, but maybe you're doing something unseen in database.h