如何从模板派生两次,并让子类进行交互?

时间:2011-05-07 16:06:55

标签: c++ templates inheritance

这是我的问题:我写了两个基类:Wire和CircuitComponent。这两者几乎相似,足以衍生出一个共同的超类,但不是。 Wire只能与CircuitComponent连接,而CircuitComponent只能与wire连接。除了类型之外,实现是相同的,所以我自然认为模板就是答案。

这是模板,我有一个派生自TwoTypeMesh<Wire, CircuitComponent>的Wire类和一个派生自TwoTypeMesh<CircuitComponent, Wire>的CircuitComponent类:

template <class thisType, class otherType>
class TwoTypeMesh {
    std::set<otherType *> neighbors;
public:
    void join(otherType * n){
        if (neighbors.find(n) != neighbors.end()) {
            return;
        } else {
            neighbors.insert(n);
            n->join(this);
        }
    }

    void disconnect(otherType * n){
        if (neighbors.find(n) == neighbors.end()) {
            return;
        } else {
            neighbors.erase(n);
            n->disconnect(this);
        }
    }
};

问题是我无法将其编译,它抱怨n->join(this)因为this的行是TwoTypeMesh<Wire, CircuitComponent>类型(Wire的超类)但是join仅针对wire定义。

到目前为止,我最好的理论是我不应该是子类,也许是typedef,但我还没有设法让它工作。

3 个答案:

答案 0 :(得分:1)

将join()移到类外:

void join(Wire &w, CircuitComponent &j);
void join(CircuitComponent &j, Wire &w);

您可能需要使该类的函数成为访问私有数据成员的朋友。

答案 1 :(得分:1)

使代码编译的微创方式确实是使用typedef,tag classes或简单的Enumerations:

enum MeshType { MeshTypeWire, MeshTypeCircuitComponent };

template <MeshType thisType>
class TwoTypeMesh {
    // calculate 'otherType' from 'thisType' (prevents usage mistakes):
    static const MeshType otherType =
        thisType == MeshTypeWire ? MeshTypeCircuitComponent :
        /* else */                 MeshTypeWire ;
    std::set< TypeTwoMesh<otherType> *> neighbors;
public:
    void join(TypeTwoMesh<otherType> * n){
        if (neighbors.find(n) != neighbors.end()) {
            return;
        } else {
            neighbors.insert(n);
            n->join(this);
        }
    }

    void disconnect(TypeTwoMesh<otherType> * n){
        if (neighbors.find(n) == neighbors.end()) {
            return;
        } else {
            neighbors.erase(n);
            n->disconnect(this);
        }
    }
};

typedef TwoTypeMesh<MeshTypeWire> Wire;
typedef TwoTypeMesh<CircuitComponent> CircuitComponent;

答案 2 :(得分:0)

要解决您的特定编译错误,您应该可以在this的调用中将static_cast thisType*改为n->join

您似乎意外地重新发明了CRTP:一个模板基类,它将派生类作为模板参数。只是不要在除T之外的任何类中继承TwoTypeMesh<T,U>,并使TwoTypeMesh的构造函数受到保护以防止直接实例化。然后,您可以确定TwoTypeMesh<T, something>的任何实例都是T实例(或T的派生类)的基类子对象,因此static_cast到{ {1}}有效。