How to define an Object using inheritance - c++

I have a small problem with a task which was given to us for a preparation for my exam:
In the UML you see the classes. I have to define class Student.
The Constructor I have to define looks like this:
The class Students inherits from interface Immatrikulation and class person.
Also there is a struct for Adresse
In Adresse you can find the string ort (which I have to use in the Constructor) and in "Adresse" you have the string name(also needed)
Student(const string& name, const string& ort, int matrikelnr);
I know how I can access and save data for matrikelnr, since I have the variable in the same class, but i don't know how I can define ort and name for student.
UML

Just call the base class constructor. Following your UML:
class Student : public Person {
public:
Student(const string& name, const string& ort, int matrikeInr) :
Person(name, ort), matrikeINr(matrikeInr)
{ }
// etc...
private:
int matrikeINr;
};

Related

Explicitly initalize abstract base class constructor with value determined by parameter of derived class constructor

Within my vehicle base class, I have a private member variable, string type (for type of vehicle, ie car, motorbike, tricycle, etc).
#pragma once
using namespace std;
#include <string>
#include <iostream>
class vehicle {
public:
vehicle(string reg, string make, string model, int age, string type);
virtual ~vehicle() = default;
virtual double costPerDay() = 0;
protected:
int age;
int perDayCostCap(int costPD);
double penceToPounds(int pence);
private:
const string type;
string const reg, make, model;
};
One of the derived classes, bike, has a numberOfWheels variable which is to be passed into its constructor. I want to initialize the base class constructor with type bicycle or tricycle depending on the numberOfWheels.
I can not figure out how to achieve this, seeing as the base class constructor has to be initialized before the function body of the child class.
The following shows what I would like to achieve (though, I know this is not possible):
bike::bike(int engineCC, int numOfWheels, string reg, string make, string model, int age)
:engineCC(engineCC), numOfWheels(numOfWheels) {
string tricOrBic = (numOfWheels == 2) ? "bicicle" : "tricicle";
vehicle:reg=reg, make=make, model=model, age=age, type=tricOrBic;
};
Like this?
bike::bike(int engineCC, int numOfWheels, string reg, string make, string model, int age)
: vehicle(reg, make, model, age, numOfWheels == 2 ? "bicycle" : "tricycle")
, engineCC(engineCC)
, numOfWheels(numOfWheels)
{
}
This is normal programming, maybe you had some problem I'm not seeing.

how typeid(type).name() decide name for user define class? and can i change this behaviour?

i want to know for user define class how typeid(type) will decide the name for type of user define class check my below code for student class i got an output like 7Student but i don't understand why 7 is appended before Student class.
#include <iostream>
class Person {
protected:
std::string name;
public:
Person(std::string name)
: name(name) {}
};
class Student : public Person{
private:
std::string id;
public:
Student(std::string name,std::string id)
: id(id) , Person(name) {}
};
template<typename Type>
class Test {
private:
Type type;
public:
Test(Type type)
: type(type) {}
const char* getType() const {
return typeid(this->type).name();
}
};
int main() {
Test<int> *test1 = new Test<int>(5);
std::cout<<test1->getType()<<std::endl;
Test<float> *test2 = new Test<float>(1.1);
std::cout<<test2->getType()<<std::endl;
Test<double> *test3 = new Test<double>(1.1);
std::cout<<test3->getType()<<std::endl;
Test<long> *test4 = new Test<long>(11);
std::cout<<test4->getType()<<std::endl;
Test<unsigned int> *test5 = new Test<unsigned int>(11);
std::cout<<test5->getType()<<std::endl;
Test<Student> *test6 = new Test<Student>(*(new Student("visrut","111")));
std::cout<<test6->getType()<<std::endl; // 7Student
Test<Person> *test7 = new Test<Person>(*(new Person("visrut")));
std::cout<<test7->getType()<<std::endl;
Test<std::string> *test8 = new Test<std::string>("visrut");
std::cout<<test8->getType()<<std::endl;
return 0;
}
i tried this code with extend Person class and without extend Person class but output is same for last type and it is 7Student.
for your reference on my g++ compiler output is below
i
f
d
l
j
7Student
6Person
NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE
Now when i tested for Person class also it's output is 6Person so i found this behaviour as {length of user-define class}{class-name} but i got weird output for std::string so i want to ask can i change this behaviour in Person or Student class is there is something built in method i can write in Person or Student class that return specific const char * for typeid().name() ?
The name() member of std::type_info is totally implementation defined. You cannot change what is output, and it is not known what will be output. It may even be different between runs.
Returns an implementation defined null-terminated character string containing the name of the type. No guarantees are given; in particular, the returned string can be identical for several types and change between invocations of the same program.
From here.
If you need to define and retrieve a specific name from a class, you are looking at doing something called reflection (or a very simply form of it). This is not something that c++ was designed for and you should avoid relying on needing to do this if you can. IF you find you really need to do it, you can find more info at How can I add reflection to a C++ application?.

C++ Declaring an inherited constructor?

I'm having difficulties in defining a constructor for a class that inherits the properties of another class
class Transportation {
public:
int ID;
string company;
string vehicleOperator;
Transportation(int,string,string) {
}
};
class SeaTransport: public Transportation {
public:
int portNumber;
SeaTransport(int)::Transportation(int,string,string) {
}
};
I'm having issues with line 18 (SeaTransport(int)::Transportation(int,string,string)).
The error I receive occurs at the pont where I declare Transportation.
As seen in the code, a class Transportation is the body class and class SeaTransport inherits the properies of Transportation.
Transportation::Transportation(int, std::string, std::string)
+2 overloads
type name is not allowed
This error occurs at the int
typedef std::__cxx11::basic_string std::string
type name is not allowed
and this final error occurs at both string variables.
It seems you mix together scoping and a constructor initializer list.
The double-colon operator :: is for scope, while a constructor followed by a single colon and a list of initializations is an initializer list.
You must declare the SeaTransport constructor to take all the arguments, including those for the parent class (assuming you want to pass them on to the base constructor):
SeaTransport(int port, int id, string company, string operator);
Then in the definition (implementation) of the constructor you "call" the parent constructor in the constructor initializer list:
SeaTransport(int port, int id, string company, string oper)
: Transport(id, company, oper), // "Call" the parent class constructor
portNumber(port) // Initialize the own members
{
}
As Mr Some Programmer Dude said, you've a Scope problem in your code,
I will try to answer for your second question which is, how to add featured variables on your constructor.
Same as what you did for the port attribute.
You can define before all your Attribute which is boatNumber as int boadNumber = 0 then, you'll overload your
constructor with boatNumber(num) after the initializer operator and int num before the initializer operator.
class Transportation {
public:
int ID;
string company;
string vehicleOperator;
Transportation(int,string,string) {
}
~Transportation(){}
};
class SeaTransport: public Transportation {
public:
int portNumber;
int boatNumber;
SeaTransport(int num, int port, int id, string company, string oper)
:Transportation(id, company, oper), boatNumber(num),portNumber(port) {}
~SeaTransport(){}
};
But, if you want to get things more specific, you can create another class which is derived from SeaTransport
And then you'll define the number of your boat and more other details, if you want.
I'll draw you an instance of it :
class Boat: public SeaTransport {
public:
int boatNumber;
Boat(int bNum,int num, int port, int id, string company, string oper):
SeaTransport( num, port, id, company, oper),boatNumber(bNum){}
~Boat(){}
};

How is a constructor for a derived class supposed to be like in c++ when derived class has added data member

I am new to c++. I have been trying to get past this error. I know when a class in derived, it inherits everything from the base class, but what if the derived class has other data members? How is the constructor suppose to be?
When I try putting only the new I try to pass parameters to the newly made class members in the constructor I get an error to say it doesn't match that of the base class. When I try using that of the base class and adding the new data members it tells me I am redefining. So I wonder whats left to do to get past this error below is my code.
This is the base class:
class movielibrarybase
{
public:
movielibrarybase(string name, string dirname, string gen, int price);
void setname(string name);
string getname();
void setdirector_name(string dirname);
string getdirector_name();
void setgenre(string gen);
string getgenre();
void setprice(int price);
int getprice();
void display();
~movielibrarybase();
protected:
string name;
string director_name;
string genre;
int price;
};
And this is the derived class:
class songlibrary: public movielibrarybase
{
public:
songlibrary();
void setartist_name(string name);
string getartist_name();
void setsong_position(string position);
string getsong_position;
~songlibrary();
protected:
string artist_name;
string song_postion;
};
I am getting the following errors:
songlibrary.cpp||In constructor 'songlibrary::songlibrary(std::string, std::string, std::string, int, std::string, std::string)':|
songlibrary.cpp|6|error: no matching function for call to 'movielibrarybase::movielibrarybase()'|
movielibrarybase.cpp|3|note: candidates are: movielibrarybase::movielibrarybase(std::string, std::string, std::string, int)|
movielibrarybase.h|8|note: movielibrarybase::movielibrarybase(const movielibrarybase&)|
songlibrary.cpp|34|error: no 'std::string songlibrary::getsong_position()' member function declared in class 'songlibrary'|
For that case you use the member initializer list in the constructor to invoke the right constructor in the base class:
songlibrary::songlibrary(string name, string dirname, string gen, int price,
string artist_name, string song_position)
: movielibrarybase(name, dirname, gen, price), // initialize base class
artist_name(artist_name), // initialize member in this class
song_position(song_position) {
// other ctor stuff
}
If you do not state the parent class on that list, it will default to the default constructor. Since there is no default constructor in your movielibrarybase class, a compiler error occurred.
In your case it would be something like:-
songlibrary::songlibrary( string n, string director, string gen,
int pri, string artist, string song )
: movielibrarybase( n, director, gen, pri ),
artist_name( artist ), song_postion( song )
One thing to note here is sequence in member initializer list matters. First calls should be to base classes and then derived classes members should be initialized in the order in which they are declared in a class.
Also, class members are initialized in the order of their declaration in the class, the order in which they are listed in a member initialization list makes not a whit of difference

Inherited elements C++

i have two c++ classes, one which inherits an abstract base class for a student database.
The base class is the record which contains all the student information (name, id vector of courses & marks):
class student{
protected:
string fName,sName;
int id;
vector<string> cname;
vector<double> cmark;
public:
virtual ~student();
virtual void addClass(string name, double mark)=0;
};
I Need to be able to access the vector cname and cmark in the addCourse function in the below class
class degree : public student{
public:
degree(string f, string s, int i){
this->setName(f,s);
this->setID(i);
}
~degree();
void AddCourse(string name, int mark){
}
I dont know how to do this without making a set function in the base class like i have done with the degree constructor.
I could just make a set function in the base class but i would rather some method of initializing the inherited elements without using functions, just to make the code less messy, is this possible? i thought about using this->cname but that gave me errors.
I Need to be able to access the vector cname and cmark in the addCourse function in the below class
Just access them, they are protected, so derived classes have access:
void AddCourse(string name, int mark){
cname.push_back(name);
cmark.push_back(mark);
}