如何避免虚拟关键字

How to avoid the virtual keyword

本文关键字:关键字 虚拟 何避免      更新时间:2023-10-16

如果没有虚拟键,我如何访问派生类的成员函数。

#include<iostream>
using namespace std;
class Employee{
public:
     void what(){
        cout<<"Employee"<<endl;
    }
};
class Secretary:public Employee{
    public:
    void what(){
        cout<<"Secretary"<<endl;
    }
};
class Manager:public Employee{
    public:
    void what(){
        cout<<"Manager"<<endl;
    }
};
class Director:public Manager{
    public:
    void what(){
        cout<<"Director"<<endl;
    }
};
void f(Employee*);
int main(){
    Employee a;
    Manager b;
    Director c;
    Secretary d;
    f(&a);
    f(&b);
    f(&c);
    f(&d);
    return 1;
}
void f(Employee *a){
    a->what();
}

它总是打印"员工"。我想打印每个对象的类名。和a.what()正确打印它的类名。但我必须在这个任务中使用指针和f(Employee*)函数。

好的,这里有一个完全人为设计的方法,它不使用virtual,它的灵感来自@Stephen的评论-它只是将文本存储在基类中,这样当函数f对类进行切片时,数据仍然存在。

#include<iostream>
using namespace std;
class Employee{
public:
    std::string name;
    Employee(std::string name = "Employee"):name(name){}
    void what(){
        cout<<name<<endl;
    }
};
class Secretary:public Employee{
    public:
    Secretary(std::string name = "Secretary"):Employee(name){}
};
class Manager:public Employee{
    public:
    Manager(std::string name = "Manager"):Employee(name){}
};
class Director:public Manager{
    public:
    Director(std::string name = "Director"):Manager(name){}
};
void f(Employee*);
int main(){
    Employee a;
    Manager b;
    Director c;
    Secretary d;
    f(&a);
    f(&b);
    f(&c);
    f(&d);
    return 1;
}
void f(Employee *a){
    a->what();
}

您必须重载void f()函数来处理Manager数据类型。

void f(Manager *a){
    a->what();
}

但它只适用于Manager数据类型,而不适用于从Manager派生的任何类。

如果您想创建一个函数来为employee类规则所有成员,并使用基类指针来访问派生成员,那么您需要使用virtual关键字。这只是C++的一个要求。(我相信还有其他方法,因为C++非常灵活,但它们非常复杂,需要时间和额外的代码。)

然而,您只需要在基类中键入"virtual",尽管这被认为是不好的做法。像这样:

class Employee{
public:
    virtual void what(){
        cout<<"Employee"<<endl;
    }
};
class Secretary:public Employee{
public:
    void what(){ /*Still inherits 'virtual' without typing it.*/
        cout<<"Secretary"<<endl;
    }
};

一个选项是:

void f(Employee*a) { a->what(); }
void f(Secretary*a) { a->what(); }
void f(Manager*a) { a->what(); }
void f(Director*a) { a->what(); }

你可以使用一个模板,而不是写出四个副本:

template<typename T>
void f(T *a) { a->what(); }