I am new to C++. I am trying to create a subclass of a base class, but it does not seem to work.
I have the base class Person and a sub class Student, and the Person class is complete. Now I want to create a sub class Student. I have the following code:
namespace Uni
{
class Student : public Person
{
private:
int enrollNumber_;
string majorCourse_;
int averageGrade_;
Student(const Student &);
public:
Student(int enrolled_number, string major_course, int average_grade);
~Student();
const int getenrollNumber() const { return enrollNumber_; }
const int getAverageGrade() const { return averageGrade_; }
const string getMajorCourse() const { return majorCourse_;
};
}
The problem is that the IDE says that on the line class Student : Person that Person [is] not a class or struct name.
How can I create the subclass Student?
Related
Why does the code below throw the following compilation error on msvc ?
No default constructor exists for class 'Person'
If I don't create a default constructor in the class Person, then should I delete the constructor of Employee and Student that takes only one argument and call Employee(name,age,grade) and Student(name,age,cl) from ctor of Manager although the Base class constructor is never going to get called from Employee and Student class?
#include<iostream>
#define endl '\n'
using std::cout;
class Person {
std::string mname;
int mage;
public:
//Person() = default;
Person(const std::string& name, int age) :mname{ name }, mage{ age }{}
};
class Employee :virtual public Person {
int msalary;
public:
Employee(const std::string& name, int age, int sal) :Person{ name,age }, msalary{ sal }{}
Employee(int sal): msalary { sal }{}
};
class Student : virtual public Person {
int mclass;
public:
Student(const std::string& name, int age, int cls) :Person{ name,age }, mclass{ cls }{}
Student(int cls) :mclass{ cls } {}
};
class Manager :public Student, Employee {
private:
public:
Manager(const std::string& name,int age, int salary,int cl) :Person{name,age}, Student{cl}, Employee{salary} {}
};
int main() {
Manager manager{ "lorem",40,10000 ,10};
return 0;
}
Why does the above code throws compilation error
The problem is that before entering the body of the ctor Employee::Employee(int), the default ctor Person::Person() of Person will be used but the compiler will not synthesize the default ctor Person::Person() as the parameterized ctor Person::Person(const std::string&, int) is present.
The error can be reproduced by just the following example:
class Person {
std::string mname;
int mage;
public:
//Person() = default;
Person(const std::string& name, int age) :mname{ name }, mage{ age }{}
};
class Employee :virtual public Person {
int msalary;
public:
Employee(const std::string& name, int age, int sal) :Person{ name,age }, msalary{ sal }{}
//--------------------v--------------------->here Person::Person() is called implicitly
Employee(int sal): msalary { sal }{}
};
Demo error
The cause of the problem:
Both Employee and Student have constructors that do not call the only available constructor of the base class Person (requireing name and age parameters). Therefore the compiler will attempt to use a default constuctor fo the base class which is not available.
You can handle it the following way:
Decide what will be the default name and age for a Person derived class like Employee, Student.
Use the defaults to construct the base, e.g.:
static inline const std::string DEFAULT_NAME = "<default_name>";
static inline const int DEFAULT_AGE = 20;
Employee(int sal) : Person(DEFAULT_NAME, DEFAULT_AGE), msalary{ sal } {}
Basically I have to store different movies in a heterogenous collection dynamically, I already have the different movie types (documentary and family) and the class which "masks" the difference (movie) so it can be stored in one place (record).
I'm having trouble with my addMovie(Movie *mov) function. I don't know how to start.
My Record class:
class Record {
String name;
size_t siz;
Movie* movies;
Record(const Record&);
Record& operator=(const Record&);
public:
Record(String n): name(n), siz(0) {movies = new Movie[siz+1];}
void addMovie (Movie *mov);
void removeMovie (Movie *mov);
void listMovies();
void searchMovie (const char* title);
void emptyRecord();
void writeFile();
void readFile();
virtual ~Record() {emptyRecord();}
};
Movie class:
class Movie {
protected:
String name;
String release;
String genre;
public:
Movie(){}
Movie(String n, String r, String g): name(n), release(r), genre(g) {}
virtual void write() {}
virtual ~Movie() {}
};
Documentary class: (the family class is similar, it stores an int age_restriction and the write function writes that)
class Documentary: public Movie {
String description;
public:
Documentary(String n, String r, String d = "Add description up to 50 characters!"): Movie(n,r,"Documentary"), description(d) {}
String getDescription () const {return description;}
void setDescription (String newdescr);
void write();
virtual ~Documentary(){}
};
(PS: if you have any good sources for dynamic heterogenous stores I'm all ears)
Not so clear requirements, but for storing heterogeneous data in one single container, I would advise std::tuple (https://en.cppreference.com/w/cpp/utility/tuple). Let me know if it's what you were looking for ;)
EDIT: a possible solution without STL.
#include <iostream>
using namespace std;
class Base {
};
class A : public Base {
};
class B : public Base {
};
int main(){
const size_t arraySize = 10;
Base* array[arraySize];
//allocate
array[0] = new A();
array[1] = new B();
// ...some more stuff here
//dispose
for (Base* ptr : array) {
if (ptr != nullptr) {
delete ptr;
ptr = nullptr;
}
}
}
Why am I not able to set the class name and inherit it and display in another class like the code given below? What am I doing wrong?
#include<iostream>
#include<string>
using namespace std;
class dealer
{
string name;
public:
dealer(){};
dealer(string n): name(n){};
~dealer(){};
//void setname(string n){name = n;};
void display(){cout<<name<<endl;}
};
class car : public dealer
{
public:
dealer b;
car(){};
//car(string n): dealer(n){};
~car(){};
void display(){dealer::display();}
};
int main ()
{
dealer a("ABC");
car c;
c.display();
}
It is working properly. You initialize c with the car default constructor which implicitly call the dealer default constructor which doesn't do anything. name remains an empty string, which is what is printed out. To solve this problem:
//car(string n): dealer(n){}; <--- uncomment
car c("ABC"); //initialize like this
From comment: Your inheritance hierarchy is incorrect. car has-a dealer, but isn't a dealer. A better design system would look like this:
class dealer { ... };
class car
{
dealer &d;
car(dealer &nd): d(nd) { };
void display(){ d.display();}
}
I'm trying to define an array of type Class, for my homework. The classB and classC is defined inside another classA, and I have to define the an Array which
is defined inside classC of type classB. Below is the code I'm writing.
//main.cpp
...
//cop.h
class cop
{
public:
....
class Person
{
private:
static char name;
static char age;
static char gender;
};
class Station
{
public:
Station();
~Station();
private:
Person personArray[20];
protected:
void visit();
};
//cop.cpp
char cop::Person::name;
char cop::Person::age;
char cop::Person::gender;
cop::Station::Station(){}
cop::Station::~Station(){}
Person cop::Station::personArray[20];
I get following ERROR;
'Person' does not name a type
First of all (as I'm pointing out later) the fields of Person should not be static. After that, remove the following lines:
char cop::Person::name;
char cop::Person::age;
char cop::Person::gender;
Person cop::Station::personArray[20];
Properly designed your code should read like the following:
// Person.h
class Person
{
public:
char name;
char age;
char gender;
};
// Station.h
class Station
{
public:
Station();
~Station();
private:
Person personArray[20];
protected:
void visit();
};
// Station.cpp
Station::Station()
{
for (int i = 0; i < 20; i++)
{
personArray[i].age = ...;
}
}
By the way: declaring all fields of the Person class static will definitely make sure that all persons in your array have the same name, age and gender...
class Society
{
void add_student(string name,string home_town)//add student to society
{
Student a;
a.set_name(name);
a.set_home_town(home_town);
}
bool same_community(Student s1, Student s2){}//check if student 1 & student 2 are in the same community
void join_communities(Student s1,Student s2){}//join communities which student 1 & student 2 are in
int num_of_communities(){}//return the total number of communities inside the society
float max_diversity(){}//return the highest diversity between all communities
};
class Community : public Society
{
void add(Student new_student){}//add new student to community
bool contains(string name_student){}//whether community contains a student named name_student
void join(Community other_community){}//add all students in other_community to this community
float diversity(){}//return the number of distinct hometowns/names for this community
};
class Student :public Community
{
string name, string home_town;
public:
void set_name(string a){name=a;}
void set_home_town(string b){home_town=b;}
string get_name() const{return name;}
string get_home_town() const{return home_town;}
};
I have a parent class named Society and I would like to use its child class named Student in some of the functions.how can I do this?
I agree with other comments, but if necessary, you can apply CRTP pattern with this form. However, this solution only apply to Student communities, you can't mix different community members:
template<typename T>
class Society
{
void add_student(string name,string home_town)
{
T student;
student.set_name(name);
......
}
....
};
template <typename T>
class Comunity : public Society<T>
{
void add(T new_student){}//add new student to community
....
};
class Student : public Comunity<Student>
{
.....
}