C ++:使用基类中的仅派生类变量

新郎

想象一下,我有两个相似的结构A和B。A和B都具有指向A的指针,但是A具有指向A或B的附加指针。

我想到了这样的基类和派生类

template <bool T> struct Derived;
struct Base { Derived<0> *p1; };
template <> struct Derived<0> : public Base { Base *p2; };
template <> struct Derived<1> : public Base {};

其中A是Derived<0>,B是Derived <1>

这里的问题是,当通过访问一个类时p2,编译器不知道它是哪个派生类,而这样的操作会产生错误。

Derived<0> x, y, z;
x.p2 = &y;
y.p2 = &z;
x.p2->p2; // Error

你们是否知道任何神奇的解决方法,最好仅使用编译时功能?

我还需要知道我使用的是哪种类型的“派生”,以便知道我是否可以使用p2。

如果有帮助,你可以想像的事情作为一个双链表,这里Derived<0>是一个正常的节点,Derived<1>是终端节点,p1上一个指针,p2下一个指针。

编辑:它不需要使用基类和派生类类型的结构,它可以是任何东西。

天顶

一种可能的解决方案是基于双重调度,即最知名的访客模式背后的想法。

它遵循一个最小的有效示例:

#include<iostream>

template<int>
struct Derived;

struct Visitor {
    template<int N>
    void visit(Derived<N> &);
};

struct Base {
    Derived<0> *p1;
    virtual void accept(Visitor &) = 0;
};

template<>
struct Derived<0>: public Base {
    void accept(Visitor &) override;
    Base *p2;
};

template<>
struct Derived<1>: public Base {
    void accept(Visitor &) override;
};

template<>
void Visitor::visit(Derived<0> &d) {
    std::cout << "Derived<0>" << std::endl;
    d.p2->accept(*this);
}

template<>
void Visitor::visit(Derived<1> &) {
    std::cout << "Derived<1>" << std::endl;
}

void Derived<0>::accept(Visitor &v) {
    v.visit(*this);
}

void Derived<1>::accept(Visitor &v) {
    v.visit(*this);
}

int main() {
    Visitor v;
    Derived<0> x, y;
    Derived<1> z;
    x.p2 = &y;
    y.p2 = &z;
    x.p2->accept(v);
}

看到它并在wandbox上运行

如果可以使用C ++ 17,则可以std::variant轻松得多:

#include<iostream>
#include<variant>

template<int>
struct Derived;

struct Base {
    Derived<0> *p1;
};

template<>
struct Derived<0>: public Base {
    std::variant<Derived<0> *, Derived<1> *> p2;
};

template<>
struct Derived<1>: public Base {};

struct Visitor {
    void operator()(Derived<0> *d) {
        std::cout << "Derived<0>" <<std::endl;
        std::visit(*this, d->p2);
    }

    void operator()(Derived<1> *) {
        std::cout << "Derived<1>" <<std::endl;
    }
};

int main() {
    Visitor v;
    Derived<0> x, y;
    Derived<1> z;
    x.p2 = &y;
    y.p2 = &z;
    std::visit(v, x.p2);
}

看到它并在wandbox上运行

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

C#-在派生类中调用基类和类构造函数

基类和派生类C ++

如果只有C ++中的基类指针,则使用派生类参数重载函数

C ++实现对派生类的实例进行计数的基类

从派生类C ++获取变量

C ++替换派生类中的基类

通过派生类C ++访问派生类的基类

使用抽象基类C ++中的变量派生的类

返回派生类型的基类中的C#方法

C ++-在派生类中静态初始化基类保护的成员变量

在C#中的基类中使用泛型:如何确保基类中的方法返回派生类的类型?

C ++在派生类和基类中使用两个相同名称的变量

在基类中声明的C#接口方法无需在派生类中再次实现

是否可以在接口的派生类中仅使用C#中的该接口的某些方法?

无法在C ++的派生类中重载基类方法

C ++如何从多个派生类调用基类方法?

创建类型为<派生类>的变量以将<基类>对象存储在C#中

您能否将派生类添加到其基类的列表中,然后从C#中的基类列表中调用派生类的方法

C#:在基类中定义方法实现,在派生类中定义属性

C ++派生类

C ++继承:指向基类的派生类指针调用派生类方法

派生类C ++

如何在C ++中的基类中创建派生类的对象

在 C# 中使用基类和派生类实例化数组中的对象

如何使用基类的数据成员作为派生类的构造函数?(在 C++ 中)

c#实现派生类中使用的接口变量

在 C++ 中,如何使用向量调用派生类?

嵌套在基类中的派生类 - C++

C#从基类访问派生类变量