1

我正在尝试来自 TCPL 的派生类示例。

经理是一种具有其他级别信息的员工。我不断收到错误:

no matching function for call to employee::employee() 
in the constructor of manager::manager()

员工的所有成员都是公开的和可访问的。管理器构造函数有什么问题?

#include <iostream>
#include <string>
using namespace std;


class employee{
  public:
    enum type {M,E};
    type hier;
    string id;
    employee(string idd):hier(E){id=idd;};
};

class manager: public employee{
  public:
    int level;
    manager(string idd, int lv){hier=employee::M; id=idd;level=lv;};
};

void print(employee *x){
  if(x->hier == employee::E){
    cout<<"I am employee with id "<<x->id<<endl;
}
  else{
    cout<<"I am manager with id "<<x->id<<endl;
    manager* y=static_cast<manager *>(x);
    cout<<"My level is "<<y->level<<endl;
  }
}

int main(){
  employee t("334");
  manager u("223", 2);
  print(&t);
  print(&u);
}

第二个版本 以前的版本在封装方面不好

这是新版本

#include <iostream>
using namespace std;

enum type {M, E};

class employee{
  string id;
  type hier;
  public:
    employee(string idd, type hi=E):hier(hi),id(idd){}
    string whatid(){return id;}
    type whattype(){return hier;}
};

class manager: public employee{
  int level;
  public:
    manager(string idd, int lv):employee(idd,M),level(lv){}
    int whatlv(){return level;}
};

我没有直接访问员工和经理的私有成员,而是将成员设为私有并使用函数来访问它们。

#include <iostream>
#include <string>
#include "manager_employee.h"
using namespace std;

void print(employee *x){
  if(x->whattype() == E){
    cout<<"I am employee with id "<<x->whatid()<<endl;
  }
  else{
    cout<<"I am manager with id "<<x->whatid()<<endl;
    manager *y=(manager *)x;
//    manager* y=static_cast<manager *>(x);
    cout<<"My level is "<<y->whatlv()<<endl;
  }
}

int main(){
  employee t("334", E);
  manager u("223", 2);
  print(&t);
  print(&u);
}
4

3 回答 3

5

通过在 中声明构造函数employee,可以删除其默认构造函数;所以你不能在不指定 ID 的情况下创建一个。

这意味着任何派生类都需要向基类构造函数提供 ID:

manager(string idd, int lv) : employee(idd) {hier=employee::M; level=lv;}
//                            ^^^^^^^^^^^^^

为了保持一致性,您可能希望level在初始化列表而不是构造函数主体中进行初始化;hier并且通过构造函数中的另一个参数初始化为正确的值可能更有意义employee,而不是给它一个默认值然后覆盖它:

employee(string idd, type hier = E) : hier(hier), id(idd) {}
manager(string idd, int lv) : employee(idd, M), level(lv) {}
于 2013-09-09T12:57:56.470 回答
2

如果您有任何明确的类构造函数,则默认构造函数将不复存在。

因此,出于这个原因,当您初始化派生类的对象时,它也会尝试初始化基类成员。由于您没有给出不带参数的构造函数,因此会引发此错误。

定义默认构造函数employee或尝试调用基类构造函数:

manager(string idd, int lv):employee(idd){//your code}
于 2013-09-09T12:54:31.917 回答
0

管理器构造函数应该在其初始化列表中调用基类 ctor:

manager(string idd, int lv) : employee(idd) {hier=employee::M; id=idd;level=lv;}

还可以考虑为班级中的其他成员使用初始化列表。

于 2013-09-09T12:55:02.940 回答