我正在尝试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);
}
答案 0 :(得分: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) {}
答案 1 :(得分:2)
如果你有一个类的显式构造函数,默认构造函数就不存在了。
因此,在初始化派生类的对象时,它也会尝试初始化基类成员。因为你没有给出一个不带参数的构造函数,所以抛出了这个错误。
为employee
定义默认构造函数或尝试调用基类构造函数:
manager(string idd, int lv):employee(idd){//your code}
答案 2 :(得分:0)
Manager构造函数应该在其初始化列表中调用基类ctor:
manager(string idd, int lv) : employee(idd) {hier=employee::M; id=idd;level=lv;}
还要考虑为您班级中的其他成员使用initlization列表。