gpt4 book ai didi

C++ 库 : application inserts a class in inheritance hierarchy

转载 作者:行者123 更新时间:2023-11-30 05:46:05 25 4
gpt4 key购买 nike

我有一个具有以下继承层次结构的库(模型):

struct Xbase {
virtual void f() = 0;
};

struct Derived1 : public Xbase {
void f() { std::cerr << "Derived1::f\n"; }
};

struct Derived2 : public Xbase {
void f() { std::cerr << "Derived2::f\n"; }
};
struct Storage {
std::map<int, Xbase*> data;
Xbase* get(int i) {
auto it = data.find(i);
return (it == data.end() ) ? nullptr : it->second;
}
};

该库跟踪指向基本结构的指针,并允许检索它们,在这个小例子中是通过一个整数 id。有一个使用该库的应用程序,并希望通过引入第二个基类 Ybase 来提供一些功能:

struct Ybase {
virtual void g() { std::cerr << "Ybase::g\n"; }
};

struct AppDerived1 : public Derived1, public Ybase {
void f() { std::cerr << "AppDerived1::f\n"; }
};

struct AppDerived2 : public Derived2, public Ybase {
void f() { std::cerr << "AppDerived2::f\n"; }
};

当然是这样

int i = 5;
Storage storage;
Xbase* xbase = storage.get(i);
Ybase* ybase = static_cast<Ybase *>(xbase);

工作不是很好

$ g++ -std=c++11 t.cpp
t.cpp: In function ‘int main()’:
t.cpp:21:45: error: invalid static_cast from type ‘Xbase*’ to type ‘Ybase*’

我想提供派生类的模板版本,以便应用程序开发人员可以将他的类插入到库层次结构中。

图书馆:

template<typename T>
struct Derived1 : public T {
void f() { std::cerr << "Derived1::f\n"; }
};

应用所有者:

struct Ybase : public Xbase {
virtual void g() { std::cerr << "Ybase::g\n"; }
};

struct AppDerived1 : public Derived1<Ybase> {
...
};
/* same for AppDerived2 */
Xbase* xbase = storage.get(i);
Ybase* ybase = static_cast<Ybase *>(xbase);
ybase->g();

这会创建一个单一的继承线,并且转换应该有效。

我想知道这是好主意还是坏主意,还有什么可以替代。请注意,我确实需要层次结构中的公共(public)基类 Xbase,因为我必须能够从名称和 ID 等外部数据中检索基类指针。应用程序开发人员的问题是应用程序还需要其基指针,因为应用程序不知道它接收到的对象的类型(AppDerived1 或 2)。感谢阅读。

最佳答案

初步说明:

您不能将 Xbase* 转换为 Ybase*,因为它们是不相关的类。
但是,由于多重继承和动态转换,如果您知道可以使用的最多派生类,则可以安全地从 Xbase 转换为 Ybase:

Ybase* ybase{};
Derived1 *pd1 = dynamic_cast<Derived1*>(xbase); // is it a Derived 1 ?
if (pd1) { // if yes
AppDerived1 *app = dynamic_cast<AppDerived1*>(pd1); // Then look for an AppDerived 1
if (app) // If valid cast
ybase = app; // we can cass the AppDerived1 to an Ybase
}
else { // same approach for the second type
Derived2 *pd2 = dynamic_cast<Derived2*>(xbase); // is it a Derived 2 ?
if (pd2) { // if yes
AppDerived2 *app = dynamic_cast<AppDerived2*>(pd2);
if (app)
ybase = app;
}
} // if ybase is still nullptr here, it means that we couldn't find a valid conversion path
cout << (ybase ? "Success " : "Fail ") << (void*)ybase << endl;

这可以利用您的对象结构和合法的上下转换:
AppDerived1-structure

评估您的备选方案:

您的替代方案建立在将自己限制在单一继承层次结构的原则之上。您类(class)的设计完全不同。你假设一个 Ybase 是一个 Xbase(总是):

Single-inheritance-alternative

这是否好完全取决于您尝试表示的应用程序域。如果在现实中 Ybase 始终是 Xbase,这将非常有意义。

这里我只能引用 Bjarne Stroustrup:

Independent concepts should be independently represented and should becombined only when needed. Where this principle is violated, youeither bundle unrelated concepts together, or create unnecessarydependencies. Either way you get less flexible set of components.

关于C++ 库 : application inserts a class in inheritance hierarchy,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29113952/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com