在父类中为多个孩子定义方法

Posted

技术标签:

【中文标题】在父类中为多个孩子定义方法【英文标题】:Defining methods in parent class for multiple children 【发布时间】:2019-10-25 09:47:44 【问题描述】:

我有一个父类Person,然后被EmployeeCustomer继承,这些又被进一步继承。 我还有一个Person 指针数组,我在其中存储“第三级”类。 我希望salary() 只能由Employees 访问,charge() 只能由Customers 访问。 尝试在Person 中使用纯函数,但随后EmployeeCustomer 仍然需要定义两者来构造。

也许我可以以其他方式定义或以某种方式阻止/删除孩子不需要的功能?

class Person 
public:
    int money;
    Person()  money = 1000; 
    virtual ~Person() 
    void salary(int m)  if (m >= 0) money += m; 
    void charge(int m)  if (m >= 0) money -= m; 
;

class Employee : public Person ;
class Customer : public Person ;

class Programmer : public Employee ;
class Secretary  : public Employee ;
class Janitor    : public Employee ;
class Business   : public Customer ;
class Private    : public Customer ;
class Charity    : public Customer ;

编辑:

Person* people[10];
Person[0] = new Programmer();
...

然后我想使用这些指针调用一个方法,例如(*person[0]).salary(100) 派生自员工或 (*person[5]).charge(500) 派生自客户。 我使用强制转换来知道对象是来自 E 还是 C。

【问题讨论】:

【参考方案1】:

由于类型擦除,这无法在编译时完成,但您可以在运行时完成。

首先,在相关类而不是基类中定义函数:

class Person 
    // no salary or change
;

class Employee : public Person 
public:
    virtual void salary(int m)
    
        // ...
    
;

class Customer : public Person 
public:
    virtual void change(int m)
    
        // ...
    
;

然后,如果您已经知道 Person* 指向员工,请使用 static_cast

static_cast<Employee*>(people[0])->salary(100);

如果您不知道,请使用dynamic_cast

if (auto* employee = dynamic_cast<Employee*>(people[0])) 
    employee->salary(100);
 else 
    // report error

【讨论】:

【参考方案2】:

我不确定这是否会按照您的要求解决,但我会为您提供解决方法:

class Person 
public:
    int money;
    Person()  money = 1000; 
    virtual ~Person() 
;
// providing the methods as specialization to the Employee and Customer classes    
class Employee : public Person 
    public:
    void salary(int m)  if (m >= 0) money += m; 
;
class Customer : public Person 
    public:
    void charge(int m)  if (m >= 0) money -= m; 
;
class Programmer : public Employee ;
class Secretary  : public Employee ;
class Janitor    : public Employee ;
class Business   : public Customer ;
class Private    : public Customer ;
class Charity    : public Customer ;

现在您可以确保只有员工可以访问薪金方法,而客户可以访问收费方法。但是在访问时你必须写一张支票:

Person* people[10];
people[0] = new Programmer();
// while accessing you need to make sure that it is type employee!!
if (auto employee = dynamic_cast<Employee*>(people[0])) 
    employee->salary(100)

同样适用于客户!!!

不要忘记将&lt;typeinfo&gt; 包含在dynamic_cast 中!!

【讨论】:

以上是关于在父类中为多个孩子定义方法的主要内容,如果未能解决你的问题,请参考以下文章

C++ 虚拟方法:我必须在父类中为子级和父级不共享的每个方法创建一个虚拟方法吗?

c#如何在父类(或是接口)当中定义一个子类必须要重写的字段(属性)?

如何理解“子类不能降低父类中定义的方法的可访问性”这句话?

在子类中定义一个属性,然后在父类中使用它,PHP中的奇怪行为?

C#在父类中获取子类的类名

父类中的私有变量