从基类派生函数
Deriving functions from a base class
我可能走错了路。我被要求创建一个特定类的对象数组。但是,这个类有两个派生类。
class Employee {
// Some stuff here about the backbone of the Employee class
}
class Salary: public Employee {
// Manipulation for Salary employee
}
class Hourly: public Employee {
// Manipulation for hourly Employee
}
// Main Program
int main (int argc, char**argv) {
Employee data[100]; // Creates an array of Employee objects
while (employeecount > 100 || employeecount < 1) {
cout << "How many employees? ";
cin >> employeecount;
}
for(int x = 0; x <= employeecount; x++) {
while (status != "S" || status != "s"|| status != "H" || status != "h") {
cout << "Employee Wage Class (enter H for hourly or S for Salary)";
cin >> status;
}
if (status == "S" || status == "s") { // Salaried Employee
new
} else { // We valid for hourly or salary, so if its not Salaried it's an hourly
}
}
return 0;
}
我想问的问题是,基类可以调用派生类的方法吗?例如,如果我为Salary类创建了一个名为getgross
的方法:我可以像这样调用Employee.getgross()
吗?如果不是,我怎么能调用子类的方法?
为了避免切片,您需要存储指向对象的指针
Employee* data[100];
然后你可以从各种派生类中创建对象并将它们放入数组中,例如
data[0] = new Salary;
为了使正确的方法被调用,你需要在基类中声明一个虚方法,然后在派生类中重写它。
在Employee
类中声明getgross()
为virtual
的例子:
class Employee {
virtual int getgross();
}
class Salary: public Employee {
virtual int getgross();
}
在指向Salary
对象的Employee*
上调用getgross()
时,将调用Salary
的getgross()
。
我也将virtual
添加到Salary::getgross()
中,目前不需要,但现在最好包含它,因为以后您可能想要派生Salary
的类。
数组必须是指针数组,以避免切片问题。使用vector
的智能指针会更好。
最好的方法是在基类(虚方法)中使用getGross()方法,以便派生类可以继承它。
正如大家所说,你必须使用指针指向Employee对象,而不是数组中的Employee对象。这样,Employee的任何派生类都可以被Employee指针指向。
我认为你要做的是实现员工基类中的方法,并使其可用于所有派生类。如果是,下面应该是你的答案。
(从这里借用这个答案):
如何在我的派生类的成员函数调用相同的函数从它的基类?
"使用基地::f ();
让我们从一个简单的例子开始。当调用非虚函数时,编译器显然不使用虚函数机制。相反,它使用成员函数的完全限定名按名称调用函数。例如,下面的c++代码…
void mycode(Fred* p)
{
p->goBowling(); // Pretend, Fred::goBowling() is non-virtual
}
…可能会被编译成类似c语言的代码(p形参变成了成员函数中的this对象):
void mycode(Fred* p)
{
__Fred__goBowling(p); // Pseudo-code only; not real
}
实际的名称混淆方案比上面暗示的简单方案要复杂得多,但是您可以理解。关键是这个特殊的情况没有什么奇怪的——它被解析成一个类似printf()的普通函数。
现在对于上面的问题所处理的情况:当您使用虚函数的全限定名(类名后面跟着"::")调用虚函数时,编译器不使用虚函数调用机制,而是使用与调用非虚函数相同的机制。换句话说,它按名称而不是按槽号调用函数。因此,如果您希望派生类Der中的代码调用Base::f(),即在其基类Base中定义的f()版本,您应该编写:
void Der::f()
{
Base::f(); // Or, if you prefer, this->Base::f();
}
编译器会把它变成类似下面的东西(再次使用过于简单的名称混淆方案):
void __Der__f(Der* this) //Pseudo-code only; not real
{
__Base__f(this); // Pseudo-code only; not real
}
"
几点思考:
- 你需要存储一个指针数组的员工。一个简单的employee数组是行不通的。每当你向数组中添加Employee时,它将被"截断"到基类,并且任何额外的信息将丢失。你可以使用dynamic_cast测试指针的类型,所以你可以在调用之前检查类型。否则,在给定基类指针(或引用)的情况下,不能调用纯派生成员函数。
- 旧的指导原则"更喜欢遏制而不是继承"可以以一种完全不同的方式解决问题。只需将pay类型设置为Employee的属性,并完全失去继承。
- 为什么使用 "this" 指针调用派生成员函数?
- 在派生函数中指定void*参数
- 如何通过派生类函数更改基类中的向量
- 如何委托派生类使用其父构造函数?
- 如何使用单独文件中的派生类访问友元函数对象
- 使用基类指针创建对象时,缺少派生类析构函数
- 在 C++ 中用派生类型重写成员函数
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 如果基类包含双指针成员,则派生类的构造函数
- 有没有比在库中添加一个并非由所有派生类实现的新虚拟函数更好的设计实践
- 在派生类中绑定非静态模板化成员函数
- 使用 std::variant<...时调用 BaseState 函数而不是派生函数>
- C++:为什么无法在派生类中访问受保护的构造函数?
- C++派生的类构造函数
- C++重载函数,一个采用基类的参数,另一个采用派生类的参数
- C ++如何在原始抽象类中创建一个函数,该函数接受派生类的输入
- 覆盖虚拟函数 - 派生类具有不同的参数
- 正在调用基方法,而不是从构造函数派生方法
- 从具有相同虚拟函数的父函数派生时如何调用子函数
- 从派生类对象调用基类函数.派生类构造函数中设置的基类数据成员