【问题标题】:Class inheritance and working with pointers类继承和使用指针
【发布时间】:2019-08-31 03:43:41
【问题描述】:

当我发现我可以像这样使用基类指针来访问派生类时,我并不感到惊讶(非常简单):

class Base
{
    protected:
    int m_value;

    public:
    Base(int value)
        : m_value(value)
    {
    }

    const char* getName() { return "Base"; }
    int getValue() { return m_value; }
};

class Derived: public Base
{
    public:
    Derived(int value)
        : Base(value)
    {
    }

    const char* getName() { return "Derived"; }
    int getValueDoubled() { return m_value * 2; }
};

对象派生类创建后会发生什么?如果我使用

Base &rBase = derived;

我将使用在基类中确定的此类方法。为什么?这是否意味着派生类实际上由基类的第一个确定的 getName() 组成,但现在只使用重载方法,如果我们愿意,我们可以通过基类上的指针调用 origin 方法?请根据指针和地址向我解释一下。

【问题讨论】:

  • 看起来您实际上并没有在这里使用任何指针(如果您使用virtual 的多态性,这将允许您调用派生函数)。除此之外,我强烈建议您在任何地方使用std::string 而不是char *
  • 不幸的是,对于一般情况,不能这样解释。 C++ 标准并未定义多态性的确切工作方式。只定义了必须发生的事情,因此只要他们的解决方案提供正确的结果,实施者就可以进行疯狂的飞行。通常实现将使用所谓的(传入搜索词!)V-Tables,但他们不必这样做。
  • @user4581301 OP 的类中没有多态性。
  • 与我的观点无关。你不能用指针和地址来解释多态性,因为知道如何使用仙尘的人不需要这些粗鲁的工具。

标签: c++ class pointers


【解决方案1】:

在 C++ 中,除非声明,否则成员函数不是虚拟的。

这意味着,在您的情况下,如果您调用rBase.getName(),因为rBase 的类型是Base&,那么无论对象rBase 指的是什么派生类型,都会调用函数Base::getName()有。

如果你想要动态调度,你必须声明函数 virtual

virtual const char* getName() { return "Base"; }

这样,调用rBase.getName(),将查看实际类型 rBase 所引用的对象,并且 -- 如果是 Derived -- 调用 Derived::getName()

顺便说一句,当您想要覆盖虚函数时,请使用 override 关键字。然后编译器可以帮助你找出错误。在您的情况下,您是否在Derived 中使用过它,例如:

const char* getName() override { return "Derived"; }

你会得到类似的错误

 error: only virtual member functions can be marked 'override'

并且,请注意@scohe001 提供的建议,并使用std::string 而不是char*,除非您有充分的理由需要C 风格的字符串。

【讨论】:

    猜你喜欢
    • 2011-02-11
    • 1970-01-01
    • 2016-09-02
    • 1970-01-01
    • 1970-01-01
    • 2013-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多