请提前为这个冗长的问题道歉。这是我能想到的最小的自包含示例...我很确定必须有一些明显的/漂亮/整洁的解决方案,但我目前无法看到它。
好的,这就是问题所在:想象一下以下情况(nb。代码的可编译版本可在http://goo.gl/dhRNex获得)。假设
struct Thing1 {
public:
void bar(class Implementation1 &i) {
i.baz();
}
// ...various other methods like bar()
};
struct Thing2 {
public:
void bar(class Implementation2 &i) {
i.qux();
}
// ...various other methods like bar()
};
给出。不幸的是,这些类是固定的,即不能改变/重构。
但是,Implementation1
和Implementation2
是可更改的。这两个类共享很多类似的代码,因此将共享代码放在一个公共基类中似乎很自然。但是,代码依赖于Thing
使用的类型,但Thing1
和Thing2
没有共同的基类,因此使用模板似乎也很自然。因此,我想出了基类
template<class T, class S>
struct ImplementationBase {
public:
S *self;
void foo() {
T thing;
thing.bar(*self);
}
// ...lots more shared code like foo()
};
和具体实施
struct Implementation1 : public ImplementationBase<class Thing1, class Implementation1> {
public:
Implementation1() {
self = this;
}
void baz() {
std::cout << "Qux!" << std::endl;
}
};
struct Implementation2 : public ImplementationBase<class Thing2, class Implementation2> {
public:
Implementation2() {
self = this;
}
void qux() {
std::cout << "Qux!" << std::endl;
}
};
理想情况下,我会在this
中使用self
代替foo
,但问题是this
的类型为ImplementationBase<class Thing1, class Implementation1>
,但{{1} }} 是必须的。显然,整个过程非常混乱,Implementation1
和Implementation
类太紧密耦合了,但是如果不能重构Thing
类,我就看不出简单的出路。所以,最后,我的问题是:
Thing
技巧是否有更好的选择?如果你已经做到这一点,非常感谢花时间阅读整个故事,并为这个冗长的问题再次道歉。
答案 0 :(得分:2)
您已经在使用CRTP,因此您根本不需要自己:
template<class T, class S>
struct ImplementationBase {
public:
S* getThis() { return static_cast<S*>(this); }
void foo() {
T thing;
thing.bar(*getThis());
}
// ...lots more shared code like foo()
};