需要在泛型和子类代码中相互引用的 C++ 类

Posted

技术标签:

【中文标题】需要在泛型和子类代码中相互引用的 C++ 类【英文标题】:C++ classes that need to refer to each other both in generic and subclass code 【发布时间】: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 类的方法,并且在那里具有泛型类型,但是在子类的方法中,这些指针具有适当的子类类型,并且上述不变量成为编译时强制执行的?如果是这样,怎么做?如果没有,你会建议我做什么?

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

【问题讨论】:

【参考方案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 替换对这些成员变量的直接访问,以便获得正确的类型转换。请注意,我将基类中的数据成员转换为私有,以便编译器帮助检测子类中对这些数据成员的所有直接引用。

【讨论】:

以上是关于需要在泛型和子类代码中相互引用的 C++ 类的主要内容,如果未能解决你的问题,请参考以下文章

Java泛型学习笔记 - 泛型的继承

iPhone - 在泛型类中引用应用程序委托

关于泛型那些事?

JAVA在泛型基类中获取子类传递的泛型参数

为什么要使用泛型和迭代器

泛型和枚举