![](/img/trans.png)
[英]C++: Use pointer from abstract class for accessing method of derived classes; derived class apears to be abstract as well
[英]c++ - Use derived class as parameter in function from container of abstract class
我有以下类层次结构和一个包装类:
struct Base {
virtual ~Base() = default;
virtual void init() = 0;
};
struct DerivedA : Base {
void init() override {
// do something specific to DerivedA
}
};
struct DerivedB : Base {
void init() override {
// do something specific to DerivedB
}
};
struct Wrapper{
Base* _item;
};
现在,我想要一个Wrapper
容器(例如std::vector<Wrapper>
)和一个函数f
,它需要两个派生类作为参数,如下所示:
void f(DerivedA* d1, DerivedA* d2) {
std::cout << "A vs A" << std::endl;
}
void f(DerivedA* d1, DerivedB* d2) {
std::cout << "A vs B" << std::endl;
}
void f(DerivedB* d1, DerivedB* d2) {
std::cout << "B vs B" << std::endl;
}
void f(DerivedB* d1, DerivedA* d2) {
std::cout << "B vs A" << std::endl;
}
int main() {
std::vector<Wrapper> items;
items.emplace_back(new DerivedA());
items.emplace_back(new DerivedB());
items.emplace_back(new DerivedB());
items.emplace_back(new DerivedA());
for (auto i = 0; i < items.size(); i++) {
for (auto j = i+1; j < items.size(); j++) {
// do something wizh all item pairs
f(items[i]._item, items[j]._item);
}
}
return 0;
}
这不会编译,因为编译器确实需要f(Base* b1, Base* b2)
,这当然是有道理的。
到目前为止我尝试过的:
enum class DerivedType { A, B, C };
解密派生类的类型。 这有效,但似乎很笨拙。Wrapper
的模板化版本并将每个模板类型存储在不同的容器中,例如std::vector<Wrapper<DerivedX>>
。 再次,这感觉就像我做错了什么。std::variant<DerivedA, DerivedB> _item
代替Wrapper
的Base* _item
。 但是我无法让std::visit
以我要求f
的方式返回指向派生类的指针(因为operator()(DerivedX* d)
期望对任何X
返回相同的返回值)。有哪些可能的方法来实现这一点? 我正在寻找的解决方案是否存在?
使用基于 RTTI 的解决方案也是一种选择:
void f1(Base* d1, Base* d2) {
const auto& t1 = typeid(*d1);
const auto& t2 = typeid(*d2);
if (t1 == typeid (DerivedA) && t2 == typeid (DerivedA)) {
std::cout << "A vs A" << std::endl;
}
if (t1 == typeid (DerivedA) && t2 == typeid (DerivedB)) {
std::cout << "A vs B" << std::endl;
}
if (t1 == typeid (DerivedB) && t2 == typeid (DerivedA)) {
std::cout << "B vs A" << std::endl;
}
if (t1 == typeid (DerivedB) && t2 == typeid (DerivedB)) {
std::cout << "B vs B" << std::endl;
}
}
使用std::variant
,它将是:
struct Wrapper{
std::variant<DerivedA, DerivedB> _item;
};
int main() {
std::vector<Wrapper> items {
{ DerivedA()},
{ DerivedB()},
{ DerivedB()},
{ DerivedA()}
};
for (auto i = 0; i < items.size(); i++) {
for (auto j = i+1; j < items.size(); j++) {
// do something with all item pairs here
std::visit([] (auto& lhs, auto& rhs) { f(&lhs, &rhs); }, items[i]._item, items[j]._item);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.