我有以下课程:
class Karen
{
public:
Karen(void);
~Karen(void);
void complain(std::string level);
private:
void debug(void) const;
void info(void) const;
void warning(void) const;
void error(void) const;
};
该complain
函数接收一个字符串,其中可以包含 debug、info、warning 或 error 等词,并且它必须在不使用 if/elseif/else 森林的情况下调用适当的函数,而是使用指向成员函数的指针。的原型complain
是给我的。我是成员函数指针的新手,我不确定如何管理它。我的尝试之一是这样的:
void Karen::complain(std::string level)
{
std::string *p = &level;
void (Karen::*f)(void) const;
(this->*(*p))();
}
最后一行的语法不正确,但我正在尝试这样做,但我(this->*(content of pointer p))()
不知道如何编写。有人能帮我吗?
编辑我只允许使用 C++98
通过成员函数指针调用成员函数的语法是
(this->*memf)();
您不能神奇地将字符串转换为成员函数指针。马虎地说,运行时不存在函数名称。如果你想要这样的映射,你需要自己提供。没办法。您可以通过使用以下命令来避免“if-else 森林” std::unordered_map
:
#include <unordered_map>
#include <string>
#include <iostream>
class Karen
{
public:
void complain(std::string level) {
static const std::unordered_map<std::string, void(Karen::*)() const> m{
{"debug",&Karen::debug},
{"info",&Karen::info},
{"warning",&Karen::warning},
{"error",&Karen::error}
};
auto it = m.find(level);
if (it == m.end()) return;
(this->*(it->second))();
}
private:
void debug(void) const { std::cout << "debug\n"; }
void info(void) const { std::cout << "info\n"; }
void warning(void) const { std::cout << "warning\n"; }
void error(void) const { std::cout << "error\n"; }
};
int main() {
Karen k;
k.complain("info");
}
如评论中所述,您可以使用枚举代替字符串。如果可能,您应该使用编译器的帮助,它可以诊断枚举中的拼写错误,但不能诊断字符串中的拼写错误。或者,您可以直接将成员函数指针传递给complain
. 那么实现complain
将是微不足道的,不需要分支。尽管这将要求方法是公开的,并且调用者必须处理成员函数指针。
如果你不被允许使用 C++11 或更高版本,你应该和你的老师认真谈谈。很快 C++20 将成为事实上的标准,并且情况发生了很大变化。我不再精通 C++98,所以这里只是对上述内容的快速修复,以使其以某种方式工作。您不能使用std::unordered_map
但是有std::map
并且地图的初始化相当麻烦:
#include <map>
#include <string>
#include <iostream>
class Karen
{
typedef void(Karen::*memf_t)() const;
typedef std::map<std::string,void(Karen::*)() const> map_t;
public:
void complain(std::string level) {
map_t::const_iterator it = get_map().find(level);
if (it == get_map().end()) return;
(this->*(it->second))();
}
private:
const map_t& get_map(){
static const map_t m = construct_map();
return m;
}
const map_t construct_map() {
map_t m;
m["debug"] = &Karen::debug;
m["info"] = &Karen::info;
m["warning"] = &Karen::warning;
m["error"] = &Karen::error;
return m;
}
void debug(void) const { std::cout << "debug\n"; }
void info(void) const { std::cout << "info\n"; }
void warning(void) const { std::cout << "warning\n"; }
void error(void) const { std::cout << "error\n"; }
};
int main() {
Karen k;
k.complain("info");
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句