C++ 用一个很好的理由选兄弟姐妹班?
我有一个基本类和许多派生类(即DerivedX)作为生产代码。 在不涉及这些类的情况下,我创建了一个从Base派生的BaseExt类,以便为测试目的操作内部数据C++ 用一个很好的理由选兄弟姐妹班?,c++,polymorphism,siblings,static-cast,C++,Polymorphism,Siblings,Static Cast,我有一个基本类和许多派生类(即DerivedX)作为生产代码。 在不涉及这些类的情况下,我创建了一个从Base派生的BaseExt类,以便为测试目的操作内部数据 +-----------+ +-----------+ | Base + <- - - - - | BaseExt | +-----------+ +-----------+ /|\ | +-----------+ | DerivedX + +-------
+-----------+ +-----------+
| Base + <- - - - - | BaseExt |
+-----------+ +-----------+
/|\
|
+-----------+
| DerivedX +
+-----------+
这对我来说很直观
std::shared_ptr<Base> p = std::make_shared<Derived1>();
auto d1 = p->data(); // 0
std::static_pointer_cast<BaseExt, Base>(p)->inject_data(10);
auto d2 = p->data(); // 10
std::shared_ptr p=std::make_shared();
自动d1=p->data();//0
std::static_pointer_cast(p)->inject_data(10);
自动d2=p->data();//10
基线:我不想更改我的生产代码(即Base和DerivedX)
当然,我可以扩展Derived1来做同样的工作,但是我有很多这样的派生类,它们为一个简单的任务添加了太多的代码
问题是
- 对于这个用例,将其转换为兄弟类是否合理
- 如何使它安全?(例如,同级类中没有属性)
- 任何更好、更简洁的解决方案(除了修改基类和Derievedx类)
- 模板呢
template<typename T>
struct TestableDerived : T {
inject_data(int data) {
_data = data;
}
static std::shared_ptr<Base> createAndInjectData(int data) {
std::shared_ptr<TestableDerived<T>> ptr = std::make_shared<TestableDerived<T>>();
ptr->inject_data(data);
return ptr;
}
}
更安全的方法是为此创建一个
friend
函数。为什么您将类型为Derived1的实例强制转换为其他类型的BaseExt很直观。如果BaseExt有一些数据成员呢?@Zefick基类中有一个friend函数?但是修改基类和Derievedx类将是最后的选择option@marcinj是的,这正是我的问题!在一定条件下进行此类铸造是否合理?i、 e.兄弟类中没有额外的属性。我认为没有一种安全的方法可以在不修改Base
/DerivedX
的情况下进行黑客攻击。
template<typename T>
struct TestableDerived : T {
inject_data(int data) {
_data = data;
}
static std::shared_ptr<Base> createAndInjectData(int data) {
std::shared_ptr<TestableDerived<T>> ptr = std::make_shared<TestableDerived<T>>();
ptr->inject_data(data);
return ptr;
}
}
struct BaseExt : virtual Base {
void inject_data(int data) { _data = data; }
}
template<typename T>
struct TestDerived<T> : virtual T, virtual BaseExt {}
void doSomeTesting() {
std::shared_ptr<TestDerived<DerivedX>> p1 = std::make_shared<TestDerived<DerivedX>>();
std::shared_ptr<DerivedX> p2 = p1;
std::shared_ptr<BaseExt> p3 = p1;
assert(p1->data()==0);
assert(p2->data()==0);
assert(p3->data()==0);
p3->inject_data(10);
assert(p1->data()==10);
assert(p2->data()==10);
assert(p3->data()==10);
}