C ++如何在不使用static_cast或dynamic_cast的情况下从基类指针访问派生类成员? [英] C++ How to access derived class member from base class pointer without using a static_cast or dynamic_cast?

查看:60
本文介绍了C ++如何在不使用static_cast或dynamic_cast的情况下从基类指针访问派生类成员?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看到了以下问题,我问自己,是否有更好的方法来解决此问题,因此不需要强制转换.考虑以下代码:

I saw the following question and I asked myself if there is a better way to address this problem, so there is no need for a cast. Consider the following code:

#include <iostream>

class Base
{
    public:
        virtual ~Base() {}
};

class Derived : public Base
{
    protected:
        int someVar = 2;

    public:
        int getSomeVar () {return this->someVar;}   
};


int main()
{
    Base    B = Base(); 
    Derived D = Derived();

    Base *PointerToDerived  = &D;
    Base *PointerToBase     = &B;

    std::cout << dynamic_cast<Derived*>(PointerToDerived)->getSomeVar() << "\n"; //this will work
    std::cout << dynamic_cast<Derived*>(PointerToBase)->getSomeVar() << "\n"; //this will create a runtime error

    return 0;

}

是否有更好的设计方法,因此不需要强制转换,并且可以避免类似的运行时错误?

Is there a better way to design this, so no cast is needed and runtime errors like this can be avoided?

推荐答案

访问者模式使用double dispatch允许您使用特定于类的成员函数和成员变量(与成员函数/可在层次结构中使用的变量相对).

The visitor pattern use double dispatch to allow you to use class-specific member function and member variable (opposed to member function/variable available through the hierarchy).

要实现访客模式,您需要一个 visitor 和一个 visited 的层次结构(在您的示例中,它是 Base 以及从基本).以您的示例为例,它会给出类似的信息:

To implement the visitor pattern, you need a visitor and a hierarchy of visited (in your example it's Base and the classes derived from Base). With your example it would give something like that:

class Base
{
    public:
        virtual ~Base() {}
        virtual void visit(Visitor) = 0;
};

class Derived : public Base
{
    protected:
        int someVar = 2;

    public:
        int getSomeVar () {return this->someVar;}
        void visit(Visitor& v) {
            v.visit(this);
         }
};
class Visitor {
    public:
         void visit(Derived& d) {
              bar(d.someVar);
         }
};

访问者背后的想法是, this Derived 知道它是实型,而一个多态变量( Base& 基本* )不可以.通过覆盖 Base :: visit ,您可以调用 visit ,后者将向右侧的 Visitor :: visit 进行调度.

The idea behind the visitor is that this of Derived know it's real type while a polymorphic variable (a Base& or Base*) don't. OverridingBase::visit allow you to call the visit who will do the dispatch to the right Visitor::visit.

如果您不覆盖 Base :: visit ,则在 Base& (或 Base * )上调用它时,它将调用 Base 对象上的函数(因此 this 的类型为 Base * ).这就是为什么示例 Base :: visit 是抽象的,否则这样做只会使错误更有可能发生(例如忘记覆盖 visit ).

If you don't override Base::visit, when calling it on a Base& (or Base*) it will call the function on a Base object (so this will be of type Base*). That's why in the example Base::visit is abstract, doing otherwise will only make error more likely to happen (like forgetting to override visit).

Base 层次结构中添加新类型时(例如 Derived2 类),您将需要添加两个函数: Derived2 :: visit Visitor :: visit(Derived2)(或 Visitor :: visit(Derived2&)).

When adding a new type in the Base hierarchy (for example a Derived2 class), you will need to add two functions: Derived2::visit and Visitor::visit(Derived2) (or Visitor::visit(Derived2&)).

编辑

在线示例

这篇关于C ++如何在不使用static_cast或dynamic_cast的情况下从基类指针访问派生类成员?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆