C++;-创建非局部变量指针的最佳方法 我最近重新学习C++,因为我在虚幻引擎中开发了一个游戏。自从我接触C++以来,大约有3年了,从那时起我就一直使用java。 P>由于java和C++之间的区别,我已经可以看出对于类似的概念有不同的最佳实践。

C++;-创建非局部变量指针的最佳方法 我最近重新学习C++,因为我在虚幻引擎中开发了一个游戏。自从我接触C++以来,大约有3年了,从那时起我就一直使用java。 P>由于java和C++之间的区别,我已经可以看出对于类似的概念有不同的最佳实践。,c++,pointers,memory-management,memory-leaks,C++,Pointers,Memory Management,Memory Leaks,我有两种这样的方法 void UMarchingSquares::Generate(std::map<Vector2, int> automata) { std::map<Vector2,ControlNode*> controlNodes = getControlNodes(automata); } std::map<Vector2,ControlNode*> UMarchingSquares::getControlNodes(std::map&l

我有两种这样的方法

void UMarchingSquares::Generate(std::map<Vector2, int> automata) {
    std::map<Vector2,ControlNode*> controlNodes = getControlNodes(automata);
}

std::map<Vector2,ControlNode*> UMarchingSquares::getControlNodes(std::map<Vector2, int> automata) {
    std::map<Vector2,ControlNode*> controlNodes = std::map<Vector2, ControlNode*>();
    for(pair<Vector2,int> pair : automata) {
        Vector2 pos = pair.first;
        ControlNode node = ControlNode(pos,pair.second);
        controlNodes[pos] = &node;
    }
    return controlNodes;
}
void UMarchingSquares::Generate(std::map automata){
std::map controlNodes=getControlNodes(自动机);
}
std::map UMarchingSquares::getControlNodes(std::map自动机){
std::map controlNodes=std::map();
for(成对:自动机){
Vector2位置=成对第一;
ControlNode=ControlNode(位置,第二对);
controlNodes[pos]=&node;
}
返回控制节点;
}
我可能正在打破一些不同的C++最佳实践,但我确实希望在一个特定的领域澄清。 我正在初始化
getControlNodes()
方法的
for循环中的
ControlNode
对象。我现在知道这样做是不好的,因为我存储了一个指向局部变量的指针,然后它在每次循环迭代中都会超出范围。我更喜欢存储指针,而不是实际的控制节点(尽管我可能相信不是这样,因为控制节点拥有一个位置[2个浮点]、一个材质[1个整数]和两个其他对象,它们都有自己的位置和材质。)

创建非局部变量指针的最佳方法是什么?我知道我可以只使用“
newcontrolnode()
”,但据我所知,这最终是一个相当昂贵的调用,需要清理(可能也很昂贵)。 我将相当频繁地调用代码的这一部分,因此我希望它是高效的


谢谢大家!

使用控制节点向量进行存储。每当您需要一个新的控制节点时,在该向量上附加一个控制节点。与其使用指针,不如使用指向该向量的迭代器。确保您在该向量中提前预留了足够的插槽,否则您的迭代器将失效。

C++在过去几年中发生了很大变化,使使用它的人的生活更加轻松

查看您的代码,它会引发很多问题:

  • 为什么映射的值是指向ControlNode的原始指针,而不是ControlNode的值或它的唯一指针
  • 在for循环中,为什么要编写显式类型的pair(与迭代器不同),
    auto
    可以帮助您减少副本数量
因为你的问题是关于第一个的,我将忽略第二个问题

看看这个,您有3种修复代码的方法:

std::map<Vector2,ControlNode> getControlNodes(std::map<Vector2, int> automata) {
    auto controlNodes = std::map<Vector2, ControlNode>{};
    for(auto &&pair : automata) {
        auto &&pos = pair.first;
        auto node = ControlNode(pos,pair.second);
        controlNodes[pos] = std::move(node);
    }
    return controlNodes;
}
如您所见,此代码与前面的代码非常相似,我已替换了映射中的类型,并将ControlNode的结构更改为
std::make_unique
。因此,您有一个唯一的\u ptr,其中包含对所分配内存的所有权(只要您有唯一的\u ptr,一切都将保持有效)

第三个解决方案只应用于如果你不能改变签名,并且被认为是C++中的坏实践,因为它通过原始指针传递所有权。现在,调用方负责清除内存,因为C++没有垃圾收集。

std::map<Vector2,ControlNode*> getControlNodes(std::map<Vector2, int> automata) {
    auto controlNodes = std::map<Vector2, ControlNode*>{};
    for(auto &&pair : automata) {
        auto &&pos = pair.first;
        auto node = new ControlNode(pos,pair.second);
        controlNodes[pos] = node;
    }
    return controlNodes;
}
std::map getControlNodes(std::map automata){
自动控制节点=std::map{};
用于(自动和配对:自动机){
auto&&pos=pair.first;
自动节点=新的控制节点(位置,第二对);
控制节点[pos]=节点;
}
返回控制节点;
}

PS:我在代码中添加了一些自动功能,使代码片段之间的更改最小化。

为什么需要指针?如果忘记了Java,代码会变得更简单,问题可能变得毫无意义(取决于您认为需要指针的原因)。例如:
std::映射控制节点不需要过多的初始化语法。假设您坚持使用指针,那么智能指针就是最好的选择,
std::unique\u ptr
。你可能还想看看移动语义,因为这是一点点效率。是的,你提到的前两个问题是因为我过去的C++课程从来没有经过过独特的指针,而他们希望我们知道的“自动”语法来帮助我们加快程序的速度。第二个选项似乎是最好的选项,因为传入的每个自动机中都有大约2500个项目,这将被相当频繁地调用。谢谢
std::map<Vector2,ControlNode*> getControlNodes(std::map<Vector2, int> automata) {
    auto controlNodes = std::map<Vector2, ControlNode*>{};
    for(auto &&pair : automata) {
        auto &&pos = pair.first;
        auto node = new ControlNode(pos,pair.second);
        controlNodes[pos] = node;
    }
    return controlNodes;
}