我怎样才能从模板派生两次,并让子类交互
How can I derive from a template twice, and have the subclasses interact?
这是我的问题:我写了两个基类: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,但我还没有设法让它工作。
使代码编译的微创方法确实是使用 typedef,标记类或简单的枚举:
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;
将 join() 移到类之外:
void join(Wire &w, CircuitComponent &j);
void join(CircuitComponent &j, Wire &w);
您可能需要使函数成为类的好友才能访问私有数据成员。
为了解决您的特定编译错误,您应该能够在调用n->join
中static_cast this
thisType*
。
您似乎不小心重新发明了 CRTP:一个将派生类作为模板参数的模板基类。只是永远不要从 T 以外的任何类中的 TwoTypeMesh<T,U>
继承,并使 TwoTypeMesh
的构造函数受到保护以防止直接实例化。然后,您可以确定 TwoTypeMesh<T, something>
的任何实例都是 T
实例(或 T
的派生类)的基类子对象,因此T*
static_cast
是有效的。
- g++的分段错误(在NaN上使用to_string两次时)
- 蛇在C++不会连续转两次
- 检查一个数组是否包含在另一个数组中,以相反的顺序,至少两次
- 从具有按值捕获的 lambda 移动构造 std::函数时,移动构造函数调用两次
- 我应该如何去缓解两次出现的cin?
- Realloc 两次无法在 Visual Studio 上运行
- 使用 getline(cin, var) 两次在进行字符串比较时会产生错误 (==)
- 为什么映射插入和 map.find() 的单次迭代比插入和 map.find() 的两次单独迭代慢得多
- C++析构函数调用两次,堆栈分配的复合对象
- 为什么参数在构造 std::thread 时移动两次
- Qt插槽调用了两次
- 做 std::用相同的unique_ptr移动两次
- C++两次定义相同的函数会导致错误
- 为什么具有静态存储持续时间的同一内联变量在包含在 VS2017 编译的两个翻译单元中时会构造和销毁两次
- 对于优化级别为 0 的 std::vector,析构函数被调用两次
- 使用柯南打包时如何避免列出两次依赖?
- 为什么要执行两次位移((x >> 4)<< 4)?
- 对结构向量进行两次排序
- 如果我使用同一个密钥推送用户数据两次,会发生什么
- 我怎样才能从模板派生两次,并让子类交互