gpt4 book ai didi

C++ - 希望虚拟仅作为重定向

转载 作者:行者123 更新时间:2023-11-30 02:10:57 24 4
gpt4 key购买 nike

假设我有一个模板:

template <class N, class I>
void add(N* element, std::list<N*> & container, I (N::*f)() const,
std::string successmsg, std::string exceptmsg) {
//...
}

我想调用它以获得指向派生类的基类指针列表。

add(newAirplane, airplanes, &Airplane::getRegistration,
"Added!", "Error: Existent!");

Airplane 继承自 AirplaneType

当然,它不编译,N首先定义为AirplaneType,然后定义为Airplane

我添加了一个虚拟的 getRegistration @AirplaneType 但当然,编译器给出了一个 vtable 错误。

解决这个问题的正确方法是什么? AirplaneType 没有 registration 属性,我对它有没有兴趣。我还想避免 virtual getRegistration() const {return "";}

有什么好的实践建议吗?

编辑:

感谢您的回答,但仍然无法正常工作。我想我找到了剩下的问题,但没有找到它的解决方案:

void Airline::addAirplane(AirplaneType* airplane) {
add(newAirplane, airplanes, &Airplane::getRegistration,
"Added!", "Error: Existent!");

}

接收到的指针类型是AirplaneType,而不是Airplane

airplanesAirplaneType 指针的列表。

最佳答案

您需要另一个模板参数,因为您关心两个不同的类 - 指针的类型(以及您将使用它调用的成员函数)和容器的类型:

#include <list>

struct AirplaneType {
};

struct Airplane : AirplaneType {
int check() const { return 3; }
};

template <typename T, typename U, typename I>
void add(T* element, std::list<U*> & container, I (T::*f)() const) {
container.push_back(element);
I i = (element->*f)();
}

int main() {
std::list<AirplaneType*> ls;
Airplane a;
add(&a, ls, &Airplane::check);
}

在这种情况下,我的 add 函数并没有真正使用 container 是一个 list 这一事实,因此更合理的版本可能是:

template <typename T, typename U, typename I>
void add(T* element, U & container, I (T::*f)() const) {
container.push_back(element);
I i = (element->*f)();
}

再一次,你可以进一步抽象:

template <typename T, typename U, typename AUF>
void add(T element, U & container, AUF func) {
container.push_back(element);
typename AUF::result_type i = func(element);
}

...但这对调用者来说不太方便:

#include <functional>

add(&a, ls, std::mem_fun(&Airplane::check));

有什么好的实践建议吗?

不要创建原始指针的容器。

编辑:让这个与虚拟函数一起工作,以及我的每个选项:

#include <list>
#include <functional>
#include <iostream>

struct AirplaneType {
virtual int check() const { return 0; }
};

struct Airplane : AirplaneType {
int check() const { std::cout << "check\n"; return 3; }
};

template <typename T, typename U, typename I>
void add(U* element, std::list<T*> & container, I (U::*f)() const) {
container.push_back(element);
I i = (element->*f)();
}

template <typename T, typename U, typename AUF>
void add2(T element, U & container, AUF func) {
container.push_back(element);
typename AUF::result_type i = func(element);
}

int main() {
std::list<AirplaneType*> ls;
Airplane a;
add(static_cast<AirplaneType*>(&a), ls, &AirplaneType::check);
add2(&a, ls, std::mem_fun(&AirplaneType::check));
}

输出是:

check
check

这表明即使函数指针指向 AirplaneType::check 而不是 Airplane::check 也正确调用了覆盖。

关于C++ - 希望虚拟仅作为重定向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4093024/

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