gpt4 book ai didi

c++ - std::find 返回一个我无法访问函数的类

转载 作者:太空狗 更新时间:2023-10-29 20:01:44 25 4
gpt4 key购买 nike

我来自 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()

你也在泄漏内存。您没有删除新建的对象。在处理通过指向基类的指针删除的多态类型时,基类需要一个 virtual 析构函数来确保正确调用所有派生的析构函数。

话虽如此,您显然正在使用 C++11 或更高版本(因为您正在使用 vector::emplace_back()),因此您应该使用 C++11 功能来帮助您更好地管理代码:

  • 您应该使用 std::unique_ptr 来包装您的怪物对象,这样您就不需要手动删除它们。

  • 在覆盖虚拟方法时,您应该始终使用 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;
}

关于c++ - std::find 返回一个我无法访问函数的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53600941/

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