-2

I have 2 classes. Since Doctor will be considered as Employee, I should be using Employee class functions in Doctor class. Only extra thing that Doctor class has is TITLE. Basically, What I tried is I wanted to send value to Doctor's constructor,set title then send remained value to Employee's class ;however, I could not. This is what I have done so far,

employee.h

#ifndef EMPLOYEE_H
#define EMPLOYEE_H
class Employee {
private:
    int ID;
    char *firstname;
    char *lastname;
    int telno;
    char *adress;
    char *mail;
    int salary; 

public:
    Employee();
    Employee(int,char *,char*,int,char*,char*,int);

    char* getfmame();
    char* getlname();
    char* getadress();
    char* getmail();
    int getID();
    int gettel();
    int getsalary();
    void printall();
};
#endif

Employee.cpp

#include <iostream>
#include "employee.h"

using namespace std;
Employee::Employee() {
    firstname = "Empty";
    ID=0;
    firstname="Empty";
    lastname="Empty";
    telno=0;
    adress="Empty";
    mail="Empty";
    salary=0; 
}

Employee::Employee(int id,char * first,char* last,int tell,char* adres,char* email,int salar){
    ID=id;
    firstname=first;
    lastname=last;
    telno=tell;
    adress=adres;
    mail=email;
    salary=salar;

}
char* Employee::getfmame(){ return firstname; }
char* Employee::getlname(){ return lastname; }
char* Employee::getadress(){ return adress; }
char* Employee::getmail(){ return mail; }
int Employee::getID(){ return ID; }
int Employee::gettel(){ return telno; }
int Employee::getsalary(){ return salary; }

void Employee::printall(){
    cout<<endl<<"EMLOYEE INFORMATION"<<endl<<"------------------"<<endl;
    cout<<endl<<"ID :"<<ID<<endl<<"FIRST NAME: "<< firstname <<endl<<"LAST NAME: "<< lastname << endl << "TELEPHONE NUMBER: "<<telno<<endl<<"ADRESS: "<<adress<<endl<<"MAIL: "<<mail<<endl<<"SALARY: "<<salary<<endl;

}

Doctor.h

#ifndef DOCTOR_H
#define DOCTOR_H
#include "Employee.h"

using namespace std;
class Doctor :Employee {
public:
    enum title {Intern=0,Practitioner=1,Assistant=2,Specialist=3,Docent=4,Professor=5,None=6};
    Doctor();
    Doctor(title a,int id,char * first,char* last,int tell,char* adres,char* email,int salar);  
};
#endif

Doctor.cpp

#include <iostream>
#include "Doctor.h"
#include "Employee.h"

using namespace std;

Doctor::Doctor() {
    title tit = None ;
}

Doctor::Doctor(title a,int id,char * first,char* last,int tell,char* adres,char* email,int salar) {
    title tit=a;
    Employee(id,first,last, tell,adres,email,salar);
    printall();
    cout<<"typed";
}

Main.cpp

#include <iostream>
#include "employee.h"
#include "doctor.h"
using namespace std;

int main(){ 
    Doctor a=Doctor(Doctor::None,12,"a","b",0550550505,"8424 str nu:5","@hotmail",5000);
    return 0;
}
  • What problem are you having? – Barmar Apr 16 '20 at 22:05
  • 2
    You have `employee.h` and `Employee.h`. Depending on the operating system, they may not be considered the same. – Barmar Apr 16 '20 at 22:06
  • 1
    For part of your problem, initializing the `Employee` base class of `Doctor`, you will need to make use of a [Member Initializer List](https://en.cppreference.com/w/cpp/language/initializer_list) – user4581301 Apr 16 '20 at 22:07
  • I call Doctor constructor ,and in Doctor Constructor ,i want to call Employee class to register it.It doesn't send it. – Mert Özçelik Apr 16 '20 at 22:14
  • I get errors when I try to compile your code. Since you use private inheritance, the methods inherited from `Employee` become private methods of `Doctor`, so you can't call `a.printall()`. – Barmar Apr 16 '20 at 22:14
  • You don't do that by calling the constructor explicitly. Follow the link to see the correct way to do it. – Barmar Apr 16 '20 at 22:14
  • 1
    You should learn how inheritance works using the absolute minimal amount of "toy" code possible and only turn to a project with multiple files when you understand inheritance. – David Schwartz Apr 16 '20 at 22:57

1 Answers1

1

Subclass construction in C++ works so that the base class object must be constructed when the subclass' constructor body is executed:

class A {
    /* etc. etc. */ 
public:
    void do_stuff();
};

class B : public A {
    B() {
        // at this point, an A has already been constructed!
        A::do_stuff();
    }
};

Note that in this example, since we haven't chosen an explicit constructor for the A instance, the default constructor, A::A(), will be used; and if that constructor is unavailable - we get a compilation error. The fact that a constructor for A has been called is what allows us to then use methods of class A - like A::do_stuff() in the example above.

But - how can we specify a different constructor before the body of the B constructor? Or in your case, how can we use the appropriate constructor for Employee before the body of the Doctor constructor?

The answer was suggested by @user4581301: You need to use an member initializer list. Initializations/constructions on this list are performed before the body, and may include the underlying class. I'll demonstrate with a simplified example. Let's suppose an Employee only has an id and a Doctor only has an additional title.

class Employee {
protected:
    int id_;
public:
    Employee(int id) : id_(id) { };
    int id() const { return id_; }
};

class Doctor : public Employee {
protected:
    std::string title_;
public:
    Doctor(int id, std::string title) : Employee(id), title_(title) { };
    const std::string& title() const { return title_; }
};

So, when a Doctor is being constructed, it constructs its underlying Employee instance using the id it got. The constructor body is used for more complex code beyond simple member initializations.


PS:

  1. You might want to initialize the title_ member with std::move(title) rather than just title, see this question for details.
  2. It's confusing when a constructor has more than two or three parameters with compatible types - users are likely to confuse them with each other. You might consider default values for most fields and setting them after construction, or alternatively, using a builder pattern.
  3. address, with two d's, not adress.
  4. Unless you plan on editing char* fields in-place, use const char *.
  5. They way you've written your classes, Doctor methods would not have write acesss to Employee methods; make sure that's what you intended.
  6. I have some other nitpicks but I'll stop now...
einpoklum
  • 118,144
  • 57
  • 340
  • 684