c++ - std::find 返回一个我无法访问函数的类
问题描述
我来自 C/C# 语言,现在我正在尝试学习 C++ 和他的标准函数。
现在,我正在创建一个名为IMonsterDead
. 我将有一个std::vector<IMonsterDead*>
怪物N
。
例子:
class IMonsterDead {
public:
IMonsterDead(int Id)
{
this->_Id = Id;
}
virtual void OnDead() = 0;
int Id() const {
return _Id;
}
private:
int _Id;
};
一个实现该类的类:
class MonsterTest : public IMonsterDead {
public:
MonsterTest(int generId)
: IMonsterDead(generId)
{
}
virtual void OnDead()
{
std::cout << "MonsterTesd died" << std::endl;
}
};
好的,如果我直接访问一切正常。但我正在尝试使用std::find
.
完整程序测试:
int main()
{
std::vector<IMonsterDead*> monsters;
for (int i = 0; i < 1000; i++)
{
monsters.emplace_back(new MonsterTest(1000 + i));
}
int id = 1033;
std::vector<IMonsterDead*>::iterator result = std::find(monsters.begin(), monsters.end(), [id]( IMonsterDead const* l) {
return l->Id() == id;
});
if (result == monsters.end())
std::cout << "Not found" << std::endl;
else
{
// Here I want to access OnDead function from result
}
return 0;
}
所以我需要访问OnDead
功能,result
但我不能。Intellisense 没有为我显示任何内容。结果存在。
如何访问该功能?还有另一种更好的方法吗?
解决方案
您需要使用std::find_if()
而不是std::find()
. std::find()
用于查找具有特定值的元素,因此您必须将实际值传递给它才能找到,而不是用户定义的谓词。 std::find_if()
用于根据谓词查找元素。
无论哪种方式,如果找到匹配项,取消引用返回的迭代器会给你一个IMonsterDead*
指针(更准确地说,它会给你一个IMonsterDead*&
指向指针的引用)。然后,您需要取消引用该指针才能访问任何成员,例如OnDead()
.
你也在泄漏内存。你不是delete
你的对象new
。在处理通过指向基类的指针删除的多态类型时,基类需要一个virtual
析构函数来确保正确调用所有派生析构函数。
话虽如此,您显然正在使用 C++11 或更高版本(事实上您正在使用vector::emplace_back()
),因此您应该使用 C++11 功能来帮助您更好地管理代码:
你应该用它
std::unique_ptr
来包装你的怪物对象,这样你就不需要delete
手动处理它们了。在覆盖虚拟方法时,您应该始终使用
override
关键字,以确保正确覆盖它。编译器在使用时override
比不使用时可以捕获更多的语法错误。auto
每当您声明编译器可以为您推断其类型的变量时,您都应该使用它。在处理模板化代码时特别有用。
尝试更多类似的东西:
#include <iostream>
#include <vector>
#include <memory>
#include <algorithm>
class IMonsterDead {
public:
IMonsterDead(int Id)
: m_Id(Id)
{
}
virtual ~IMonsterDead() {}
virtual void OnDead() = 0;
int Id() const {
return m_Id;
}
private:
int m_Id;
};
class MonsterTest : public IMonsterDead {
public:
MonsterTest(int generId)
: IMonsterDead(generId)
{
}
void OnDead() override
{
std::cout << "MonsterTest died" << std::endl;
}
};
int main()
{
std::vector<std::unique_ptr<IMonsterDead>> monsters;
for (int i = 0; i < 1000; i++)
{
// using emplace_back() with a raw pointer risks leaking memory
// if the emplacement fails, so push a fully-constructed
// std::unique_ptr instead, to maintain ownership at all times...
monsters.push_back(std::unique_ptr<IMonsterDead>(new MonsterTest(1000 + i)));
// or:
// std::unique_ptr<IMonsterDead> monster(new MonsterTest(1000 + i));
// monsters.push_back(std::move(monster));
// or, if you are using C++14 or later:
// monsters.push_back(std::make_unique<MonsterTest>(1000 + i));
}
int id = 1033;
auto result = std::find_if(monsters.begin(), monsters.end(),
[id](decltype(monsters)::value_type &l) // or: (decltype(*monsters.begin()) l)
{
return (l->Id() == id);
}
// or, if you are using C++14 or later:
// [id](auto &l) { return (l->Id() == id); }
);
if (result == monsters.end())
std::cout << "Not found" << std::endl;
else
{
auto &monster = *result; // monster is 'std::unique_ptr<IMonsterDead>&'
monster->OnDead();
}
return 0;
}
推荐阅读
- typescript - 使用字符串文字作为计算属性名称的模板参数
- python - 如何修补从另一个模块导入的函数
- android - 将flutter模块添加到android项目时无法触发onActivityResult
- c# - C# BigInteger 按位异或返回额外的数字
- javascript - 更改上下文后使用新数据渲染页面
- php - 未定义的变量,而我定义它
- php - 将库中的变量加载到控制器文件中?
- ios - 从其他屏幕返回时,屏幕从纵向旋转到横向
- spring - 如何按优先级顺序获取mongoDB文档
- elixir - String.replace/4 和 Regex.replace/4 有什么区别?