【问题标题】:Inheritance with Overloaded Functions That Rely on Pure Virtual Functions依赖纯虚函数的重载函数的继承
【发布时间】:2019-07-24 02:39:03
【问题描述】:

我有一个基类Write,它有一个纯虚函数write (std::string text),需要所有派生类来实现它。在基类中,有一个重载的write 函数,它接受int 并调用纯虚拟write()

在派生类中,我们根据需要实现write (std::string text)

在主类中,我可以调用console.write("dog\n");,但我无法使用接收 int 的重载版本调用它,而无需通过基类名称Write。无论如何要定义这个继承,以便write 函数,一个接受std::string 和一个接受int 而不会通过Write 类名泄露继承的细节,如程序最后一行所示?

如果可能的话,我不希望用户能够调用重载的write(int)' through theWrite` 类名。

#include <iostream>

class Write
{
protected:
    virtual void write (const std::string &text) = 0;

public:
    void write (const int &number)
    {
        write (std::to_string (number));
    }
};

class Console_Write : public Write
{
public:
    void write (const std::string &text) override
    {
        std::cout << text;
    }
};

int main()
{
    Console_Write console;
    console.write("dog\n");
    console.Write::write (1); // Is it possible to be able to change the inheritance so we can just call: console.write (1);
}

【问题讨论】:

  • Console_Write的定义中,添加using Write::write;
  • 这可行并且允许我们直接调用重载的write,它接收int,但是,没有什么能阻止用户以当前编写的方式调用它。有没有办法定义禁止Console_Write 类的用户通过Write 类名的继承?
  • 你从Write公开派生,建模is-a关系。 “不泄露继承的细节”你不能这样做——public 表示公开;他们不是在开玩笑。 Console_Write is-a Write; Write 的实例可以做任何事情,Console_Write 也可以做任何事情。这就是继承的意义。
  • 如果你有公共的、非虚拟的和受保护的虚拟方法的组合,通常的方法是不要将它们称为相同的,从而也会带来重载。对于您的情况,您经常会看到它们被称为 public write()protected virtual do_write()

标签: c++ inheritance overloading pure-virtual


【解决方案1】:

正常的模式是让你的基类看起来像:

class Write {
 public:
  virtual ~Write() = default;
  void write(const std::string& str) {
    write_internal(str);
  }
  void write(int n) {
    write(std::to_string(n));
  }
 private:
  virtual void write_internal(const std::string& str) = 0;
}

class ConsoleWrite : public Write {
 public:
  ~ConsoleWrite() = default;
 private:
  void write_internal(const std::string& str) {
    std::cout << str;
  }
}

该模式甚至有一个名称“非虚拟接口” - https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-Virtual_Interface 有更多关于该模式的信息。

【讨论】:

  • 我本来希望write(int) 发送到write_internal()。为什么会重用其他公共write(string const&amp;)重载?
  • 很好的答案。这正是我一直在寻找的。我上面的代码只是我正在处理的实际代码的一个超级简化示例,但我按照您的演示实现了它,同时使用了@UlrichEckhardt 的建议。
猜你喜欢
  • 2018-10-09
  • 1970-01-01
  • 2012-01-31
  • 1970-01-01
  • 1970-01-01
  • 2015-08-07
  • 2012-08-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多