当我返回其引用时,如果超出范围,静态 std::vector 将取消

Posted

技术标签:

【中文标题】当我返回其引用时,如果超出范围,静态 std::vector 将取消【英文标题】:Static std::vector cancels out if out of scope when I returned its reference 【发布时间】:2014-11-07 02:00:29 【问题描述】:

现在我遇到了这个奇怪的错误。我有一个名为 ENGComponent 的类,它将根据其优先级将自身推入 5 个私有静态向量之一。向量是通过调用 GetComponentList(priority) 获得的。这是在构造函数中完成的。但是在我们离开构造函数之后,推回被忽略并且向量在其中得到了 0 项。代码如下:

ENG组件:

#include "../../inc/engine/eng_component.h"

#include <vector>
#include <iostream>
#include <string>

#include "../../inc/engine/eng_logger.h"

//Static member var inits
std::vector<ENGComponent*> ENGComponent::m_ComponentList_1 = std::vector<ENGComponent*>();
std::vector<ENGComponent*> ENGComponent::m_ComponentList_2 = std::vector<ENGComponent*>();
std::vector<ENGComponent*> ENGComponent::m_ComponentList_3 = std::vector<ENGComponent*>();
std::vector<ENGComponent*> ENGComponent::m_ComponentList_4 = std::vector<ENGComponent*>();
std::vector<ENGComponent*> ENGComponent::m_ComponentList_5 = std::vector<ENGComponent*>();

ENGComponent::ENGComponent( const std::string& name, 
                            Priority priority, 
                            ENGObject* owner): m_Name(name),
                                               m_Priority(priority),
                                               m_pOwnerObject(owner)


    std::vector<ENGComponent*> compList = GetComponentList(m_Priority);

    if (compList == m_ComponentList_5)
        m_Priority = PRIORITY_5;

    compList.push_back(this);



std::vector<ENGComponent*>& ENGComponent::GetComponentList(Priority priority)

    switch(priority)
    
        case PRIORITY_1:
            return m_ComponentList_1;
        case PRIORITY_2:
            return m_ComponentList_2;
            break;
        case PRIORITY_3:
            return m_ComponentList_3;
            break;
        case PRIORITY_4:
            return m_ComponentList_4;
            break;
        case PRIORITY_5:
            return m_ComponentList_5;
            break;
        default:
            //Error! TODO: Log error, change to priority 5 and move on
            //TODO: LOG error
            std::string errMessage = "Component priority unknown! Returning priority 5...";
            ENGLogger::Log(errMessage, ENGLogger::LogLevel::ERROR);

            return m_ComponentList_5;
    
 

现在,如果在实例化 ENGComponent 对象后,我在其他任何地方调用了 ENGComponent::GetComponentList(priority),则返回的 m_ComponentList_X 的大小始终为 0,即使我已将对象推回。现在奇怪的事情来了。如果我跳过了整个优先级,直接推送到向量,它工作得很好(即向量的大小增加一并且对象被成功推回)。即使我从对象外部调用 GetComponentList()。像这样:

ENGComponent::ENGComponent( const std::string& name, 
                            Priority priority, 
                            ENGObject* owner): m_Name(name),
                                               m_Priority(priority),
                                               m_pOwnerObject(owner)

    
    m_ComponentList_5.push_back(this);

那么我在这里做错了什么?有人可以告诉我吗?提前致谢。

【问题讨论】:

PS = std::vector&lt;ENGComponent*&gt;() 位是不必要的。 std::vector&lt;ENGComponent*&gt; compList = GetComponentList(m_Priority); 这是干什么用的?您创建一个本地副本,该副本在构造函数返回时被销毁。 您的意思是compList 是对您的向量的引用还是它的副本?因为现在是后者。 为什么没有你的向量的向量而不是组件 1、组件 2 等?优先级现在可以是索引的整数。 @NeilKirk 是的,我知道这有点必要。如果它是一个指针,我只是想让它与默认值一致(即 = new std::vector())。而且我没有使用向量的向量,因为它最终变得令人困惑。 【参考方案1】:

虽然GetComponentList 正在返回向量的引用,但您将它作为单独的副本存储到compList 中。因此,添加到compList 中的任何元素都不会添加到原始向量中。

您需要将向量存储到引用中:

std::vector<ENGComponent*>& compList = GetComponentList(m_Priority);

因此对compList 的任何修改都会反映到原始向量。

没有什么奇怪的:

m_ComponentList_5.push_back(this);

这里你直接使用向量进行修改。因此,这工作正常。

【讨论】:

IC。感谢你的回答。我承认,我不擅长参考。更糟糕的是,我现在正在使用 C#/Objective C/javascript。他们的指针和引用概念搞砸了我的 C++。 :P【参考方案2】:

你应该使用参考:

std::vector<ENGComponent*>& compList = GetComponentList(m_Priority);

【讨论】:

以上是关于当我返回其引用时,如果超出范围,静态 std::vector 将取消的主要内容,如果未能解决你的问题,请参考以下文章

分配对局部变量的引用,如果局部变量超出范围,它会超出范围吗?

Python中列表超出范围时返回特定值

如何通过引用或值返回智能指针(shared_ptr)?

cppcheck 超出范围

超出范围后,在Lambda中设置共享指针

当我超出父图像的范围时,iOS/Objective C 图像 alpha 低