在值类型列表中保留引用类型?

时间:2016-06-09 09:21:55

标签: c++ qt pointers

在本讨论What and where are the stack and heap?中,我了解到值类型保存在堆栈中,指针位于堆中。在我的应用程序中,我有一些QList<T*>QMap<QString,QList<QString>>持有一些对象的指针。

现在我知道,引用类型保存在堆(应用程序)中。但是我的列表,包含这些引用,是值类型,所以它们在堆栈中。它们仅在创建它们的线程中可用。但是我怎么知道,当一个线程死了,或者我调用的函数/方法是在另一个线程中?我需要整个应用程序中的列表。是一个有点愚蠢的问题,但我填写我的列表,如果对象可用,它只是一个机会。

编辑:

  

@ coyotte508

     

堆栈中唯一的东西是指向它的成员指针   记忆。也就是说,如果它们是在堆栈中创建的,那只是   如果它们是函数的局部变量或声明的另一个类的局部变量   在堆栈上。

在我的主要课程中,我有一个列表:QList<Fachbereich *> lFBs;

在我的主类的构造函数中,我创建了列表:

lFBs=QList<Fachbereich *> ();

..-然后我调用方法ReadConfig();

其中一个子程序:

void AppConfig::ReadFachbereiche(QXmlStreamReader &reader)
{
    Fachbereich* fb(0);
    while(!reader.atEnd())
    {
        reader.readNext();
        if (reader.error())
        {
            bla bla

        }
        else
        {
            if (reader.isStartElement())
            {
                if (reader.name().toString().toLower() == "fb")
                {
                    QString sFB="";

                    try{ sFB=reader.attributes().value("name").toString();}
                    catch(...){}

                    if (sFB !="")
                    {
                        fb=new Fachbereich();
                        fb->Name=sFB;
                    }
                }
                else if (reader.name().toString().toLower() == "stddir")
                {
                    if (fb!=0) fb->stdDir=reader.readElementText().replace("\\", "/").toLower();
                }
            }
            else if (reader.isEndElement())
            {
                if (reader.name().toString().toLower() == "fb")
                {
                    if (fb!=0){
                        if (!lFBs.contains(fb))
                            lFBs.append(fb);
                    }
                }
                else if (reader.name().toString().toLower() == "fachbereiche") return;
            }
        }
    }
}

所以fb是这个函数的局部变量。我想,通过使用new创建一个对象,内存将在堆中分配,但不是。离开函数时,新创建的,我的listappended引用类型已经消失了。

我应该将对象存储在QSharedPointer吗? STH。像这样?

QList<QSharedPointer> lFBs;

...

QSharedPointer<Fachbereich> fb= QSharedPointer<Fachbereich>(new Fachbereich);

1 个答案:

答案 0 :(得分:0)

您的代码与线程没有太大关系。

你想要的是将fb变量保留在函数之外。

然后将其添加到列表中,这很好。

if (reader.name().toString().toLower() == "fb")
{
    if (fb!=0){
        if (!lFBs.contains(fb))
            lFBs.append(fb);
    }
}
else if (reader.name().toString().toLower() == "fachbereiche") return;

但是你只在某些情况下这样做,有时(当名称是“fachbereiche”时)你直接返回。我认为你甚至不需要把它放在指针中。 QList<Fachbereich>保存数据,因为它是您班级的成员,所以数据将被保存,直到您的班级被销毁。

我会做什么:

  • 停止使用指针或new。这取决于Fachbereich是如何创建的,但它不应该造成问题
  • 如果需要,请确保元素始终添加到列表中。

为此,在函数的开头:

Fachbereich fb;
bool somethingRead = false;

在决定“创建”fb时,只需将布尔值设置为true:

if (sFB !="")
{
    /* Maybe add a debugging message here to say it was created */
    somethingRead = true;
    fb.Name=sFB;
}

替换此代码:

            if (reader.name().toString().toLower() == "fb")
            {
                if (fb!=0){
                    if (!lFBs.contains(fb))
                        lFBs.append(fb);
                }
            }
            else if (reader.name().toString().toLower() == "fachbereiche") return;

由:

break; //leave the loop

最后,在函数结束时,循环之后:

/* The boolean is true if fb was initialized */
if (somethingRead) {
    lFb.push_back(fb);
}

然后在调用函数后,您的类的lFb.size()应该大于0,而lFb.last()应该包含您的元素。

QList在使用new分配对象后在内部存储对象,因此您无需担心。