【问题标题】:Problem constructing a base class from within a subclass constructor从子类构造函数中构造基类的问题
【发布时间】:2020-04-16 21:59:16
【问题描述】:

我有 2 节课。由于 Doctor 将被视为 Employee,我应该在 Doctor 类中使用 Employee 类函数。 Doctor类唯一的额外内容是TITLE。基本上,我尝试的是我想将值发送给 Doctor 的构造函数,设置标题然后将剩余的值发送给 Employee 的类;但是,我不能。这是我到目前为止所做的,

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;
}

【问题讨论】:

  • 你有什么问题?
  • 你有employee.hEmployee.h。根据操作系统的不同,它们可能不一样。
  • 对于部分问题,初始化DoctorEmployee 基类,您将需要使用Member Initializer List
  • 我调用Doctor构造函数,在Doctor Constructor中,我想调用Employee类来注册它。它不发送它。
  • 您应该了解继承的工作原理,尽可能使用最少的“玩具”代码,并且只有在您了解继承后才转向具有多个文件的项目。

标签: c++ class inheritance member-initialization object-construction


【解决方案1】:

C++ 中的子类构造工作,因此必须在执行子类的构造函数体时构造基类对象:

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();
    }
};

请注意,在此示例中,由于我们没有为 A 实例选择显式构造函数,因此将使用默认构造函数 A::A();如果该构造函数不可用 - 我们会收到编译错误。调用A 的构造函数这一事实使我们能够使用A 类的方法 - 就像上面示例中的A::do_stuff()

但是 - 我们如何在B 构造函数的主体之前指定不同的构造函数?或者在你的情况下,我们如何在 Doctor 构造函数的主体之前为 Employee 使用适当的构造函数?

@user4581301 提出了答案:您需要使用member initializer list。此列表上的初始化/构造在主体之前执行,并且可能包括基础类。我将用一个简化的例子来演示。假设 Employee 只有一个 id,Doctor 只有一个额外的标题。

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_; }
};

因此,在构造 Doctor 时,它会使用得到的 id 构造其底层的 Employee 实例。除了简单的成员初始化之外,构造函数主体用于更复杂的代码。


PS:

  1. 您可能希望使用std::move(title) 而不仅仅是title 来初始化title_ 成员,有关详细信息,请参阅this question
  2. 当构造函数有两个或三个以上类型兼容的参数时,会让人感到困惑——用户很可能会将它们相互混淆。您可以考虑为大多数字段设置默认值,并在构建后设置它们,或者使用构建器模式。
  3. 地址,有两个 d,不是地址。
  4. 除非您打算就地编辑 char* 字段,否则请使用 const char *
  5. 它们是您编写类的方式,Doctor 方法不会对Employee 方法进行写入访问;确保这是您的意图。
  6. 我还有一些其他的挑剔,但我现在就停下来......

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-19
    • 2018-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多