【问题标题】:C++ classes that need to refer to each other both in generic and subclass code需要在泛型和子类代码中相互引用的 C++ 类
【发布时间】:2011-12-02 03:53:02
【问题描述】:

我有三个类,configcircuitconn,它们相互保存指针,如下所示:

struct config { /* ... */ };
struct circuit {
    config *cfg;
    /* ... */
};
struct conn {
    config *cfg;
    circuit *ckt;
    /* ... */
}

(没有访问控制和指针智能,因为这个程序大约从 C 转换到 C++ 的一半。现在这并不重要。)

当这些类被子类化时,它们三个都总是在一个组中被子类化:

struct foo_config  : config  { /* ... */ };
struct foo_circuit : circuit { /* ... */ };
struct foo_conn    : conn    { /* ... */ };

此外,cfg 指针在foo_circuitfoo_conn 中将始终 指向foo_config 的实例,而ckt 指针是运行时不变的在foo_conn 中将始终 指向foo_circuit 的实例。这目前正在通过dynamic_cast 和断言强制执行。目前有两个不同的foos,但未来可能会更多。

是否有可能安排事情使cfgckt 指针仍然可以访问泛型circuitconn 类的方法,并且在那里具有泛型类型,但是在子类的方法中,这些指针具有适当的子类类型,并且上述不变量成为编译时强制执行的?如果是这样,怎么做?如果没有,你会建议我做什么?

我更喜欢能够最大限度地减少我必须为每组子类编写的样板数量的答案。如果子类在匿名命名空间中定义并且在任何标题中不可见,我也更喜欢仍然有效的答案。

【问题讨论】:

    标签: c++ inheritance


    【解决方案1】:

    如果您将所有对数据成员的直接访问替换为 getter 和 setter,那么您可以为每个子类定义特定于类型的 getter 和 setter,并且编译器可以强制使用这些类型。下面是一个例子,注意我定义了一个模板类来简化子类的创建。

    struct config { /* ... */ };
    
    struct circuit {
    private: 
        config *cfg;
    protected:
        void set_cfg(config* _cfg) { cfg = _cfg; }
        config* get_cfg() { return cfg; }
    };
    
    template <typename CFG>
    struct my_circuit : circuit {
    public:
        // type specific setters/getters
        void set_cfg(CFG* _cfg) { circuit::set_cfg(_cfg); }
        CFG* get_cfg() { return dynamic_cast<CFG*>(circuit::get_cfg()); }
    };
    
    // below is how you define two different sets of subclasses:
    struct foo_config  : config  { /* ... */ };
    typedef my_circuit<foo_config> foo_circuit;
    
    struct bar_config  : config  { /* ... */ };
    typedef my_circuit<bar_config> bar_circuit;
    
    // example usage
    foo_config foo_cfg;
    foo_circuit foo_ckt;
    bar_config bar_cfg;
    
    foo_ckt.set_cfg(&foo_cfg); // okay
    foo_ckt.set_cfg(&bar_cfg); // not okay, compiler error!
    

    在基类中,您无需更改任何内容。在子类中,您必须用相应的 getter 替换对这些成员变量的直接访问,以便获得正确的类型转换。请注意,我将基类中的数据成员转换为私有,以便编译器帮助检测子类中对这些数据成员的所有直接引用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-20
      • 1970-01-01
      • 2010-10-15
      • 1970-01-01
      • 2021-11-11
      • 1970-01-01
      • 2019-05-03
      相关资源
      最近更新 更多