14.3多重继承需要注意的问题

多重继承(MI)

  • 公有MI表示的是is-a关系
  • 私有MI和保护MI表示的是has-a关系

这里主要介绍公有MI

公有MI主要解决的几个问题:

  1. 从不同的基类继承多个相同的祖先对象成员------->使用虚继承使只继承一个祖先对象
  2. 从两个不同的基类继承同名方法-------->采用模块化方式而不是递增的方式编程,根据需要选择不同模块组合成新的方法。
  3. 从两个或更多相关基类那里继承同一个类的多个实例------->混合使用虚基类和非虚基类,会导致包含一个虚途经子对象和多个非虚途径子对象

虚基类需要使用新的构造函数规则


// multiple inheritance
class SingingWaiter : public Singer, public Waiter
{
protected:
    void Data() const;
    void Get();

public:
    SingingWaiter() {}
    SingingWaiter(const std::string &s, long n, int p = 0,
                  int v = other)
        : Worker(s, n), Waiter(s, n, p), Singer(s, n, v) {}
    // KP
    // 这里存在的问题是,在自动传递信息时,C++将通过两条不同的途径waiter和singer将wk信息传递给worker
    // 为了避免这种冲突,C++在基类是虚的时,将禁止信息通过中间类自动传递给基类
    // 这里 Waiter(s, n, p), Singer(s, n, v)将只能初始化中间类的新增成员p和v,而对基类成员不做处理
    // 这种情况下,需要自己额在成员初始化列表额外的显示调用所需的基类构造函数
    // 否则,这里默认将采用基类的默认构造函数
    // FAO 对于虚基类,这样做是合法且必须的;而对于非虚基类,这样则是非法的
    SingingWaiter(const Worker &wk, int p = 0, int v = other)
        : Worker(wk), Waiter(wk, p), Singer(wk, v) {}
    SingingWaiter(const Waiter &wt, int v = other)
        : Worker(wt), Waiter(wt), Singer(wt, v) {}
    SingingWaiter(const Singer &wt, int p = 0)
        : Worker(wt), Waiter(wt, p), Singer(wt) {}
    void Set();
    void Show() const;
}

MI每个直接祖先继承自祖宗(一般是一个抽象基类),拥有相同的方法接口(实现可能不同),这使得上述方法的调用是有二义性的。

解决方法:

1. 使用作用域解析运算符
2. 更好的方法是在孙子中使用 模块化方式(配合保护访问方式) 重新定义该方法,并指出要使用哪个show()
class Worker // an abstract base class
{
private:
    std::string fullname;
    long id;

protected:
    //KP 
    // 采用模块化方式而不是递增方式避免数据的重复调用
    // 这里用作协助公有接口的辅助方法
    // 采用保护方式避免使得这些方法只能在继承结构层次类使用他们
    virtual void Data() const; //worker数据的输入
    virtual void Get();    //worker数据的展示
    
public:
    //这里的两个方法调用了上面的保护辅助方法 
    virtual void Set() = 0;
    virtual void Show() const = 0;
};

class Waiter : virtual public Worker
{
private:
    int panache;

protected:
    void Data() const;
    void Get();

public:
// Waiter methods
// 这里使用Worker::Get()模块和派生类新增的Get模块来实现Set方法
void Waiter::Set()
{
    cout << "Enter waiter's name: ";
    // 输入worker部分
    Worker::Get();
    // 输入waiter增加部分
    Get();
}

void Waiter::Show() const
{
    cout << "Category: waiter\n";
    // 展示worker部分
    Worker::Data();
    // 展示waiter部分
    Data();
}
}

void Waiter::Show() const
{
    cout << "Category: waiter\n";
    // 展示worker部分
    Worker::Data();
    // 展示waiter部分
    Data();
}
};

class Singer : virtual public Worker
{
protected:
    void Data() const;
    void Get();
private:
    static char const *pv[Vtypes]; // string equivs of voice types
    int voice;
public:
    void Set();
    void Show() const;
};

// multiple inheritance
class SingingWaiter : public Singer, public Waiter
{
protected:
void SingingWaiter::Data() const
{
    Singer::Data();
    Waiter::Data();
}

void SingingWaiter::Get()
{
    Waiter::Get();
    Singer::Get();
}
public:
// 分别使用了worker模块和waiter新增的和singer新增的
// 模块化编程方式
void SingingWaiter::Set()
{
    cout << "Enter singing waiter's name: ";
    Worker::Get();
    // 模块化,包括了waiter和singer中各自新增的部分
    Get();
}
void SingingWaiter::Show() const
{
    cout << "Category: singing waiter\n";
    Worker::Data();
    Data();
}

};

继承中的同名成员处理:

问题:当子类与父类出现同名的成员,如何通过子类对象,访问到子类或父类中同名的数据呢?

  • 访问子类同名成员,直接访问即可(通过优先规则解决名称二义性)
  • 访问父类同名成员,需要加作用域

总结:

  1. 子类对象可以直接访问子类中同名成员
  2. 子类对象加作用域可以访问到父类中同名成员
  3. 当子类与父类拥有同名的成员函数,子类会隐藏父类中同名的成员函数,加作用域可以访问到父类中成员函数及其重载版本
  4. 非虚继承时,多个不同的类加类名限定即可。

问题:继承中同名的静态成员在子类对象上如何进行访问?

静态成员和非静态成员出现同名,处理方式一致,只不过有两种访问方式(通过对象 和 通过类名)

  • 访问子类同名成员,直接访问即可
  • 访问父类同名成员,需要加作用域
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要安装Multisim 14.3,您可以按照以下步骤进行操作: 1. 首先,确保您已经下载并准备好Multisim 14.3的安装程序。 2. 运行安装程序,通常是一个名为"setup.exe"的文件。 3. 在安装向导中,您将被引导到选择安装位置的页面。您可以选择默认的安装位置,或者根据需要选择其他位置。 4. 接下来,您将被要求选择安装选项。在这里,您可以选择要安装的组件和功能。确保选择安装Multisim 14.3的所有组件。 5. 在安装过程中,您可能需要接受许可协议并进行其他配置选项。 6. 完成安装后,您可以启动Multisim 14.3并开始使用它。 请注意,如果安装过程中遇到问题,您可以尝试以下解决方法: - 确保您的计算机满足Multisim 14.3的系统要求。您可以在官方网站上找到这些要求。 - 如果安装程序无法找到安装路径,请尝试手动查找路径。根据引用,您可以检查路径"C:\Program Files (x86)\National Instruments\Circuit Design Suite 14.3\stringfiles",并查找名为"stringfiles"的文件。 - 如果问题仍然存在,您可以尝试重新下载安装程序,并确保下载的文件完整且没有损坏。 总结,安装Multisim 14.3的步骤包括下载安装程序,运行安装程序,选择安装位置和选项,接受许可协议,并进行必要的配置。如果遇到问题,可以检查系统要求,手动查找安装路径或重新下载安装程序。希望这些信息能帮助到您安装Multisim 14.3

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值