Переопределение переменной Qt - PullRequest
1 голос
/ 06 апреля 2010

У меня есть два примера, по которым у меня есть вопрос.Позвольте мне объяснить с помощью некоторого кода:

Вопрос 1:

QStringList qsl(); // Create a list and store something in it
qsl << "foo";
QString test = "this is a test"; 
qsl = test.split(" ", QString::SkipEmptyParts); // Memory Leak?

Что происходит, когда я переназначаю переменную qsl, что происходит с "foo" и исходные данные размещаются в первой строке?

Вопрос 2:

class Foo
{
     QStringList mylist;
     void MyFunc(QStringList& mylist)
     {
           this->m_mylist = mylist;

     }

     void AddString(QString str)
     {
         mylist << str;
     }



}

int main()
{
    Foo f;
    QStringList *qsl = new QStringList();
    f.MyFunc(*qsl);
    delete qsl;
    f.AddString("this is a test"); // Segfault?
}

Здесь я передаю список по ссылке на класс, который затем сохраняется в указанном классе.Затем я удаляю исходный объект.

В основном все сводится к тому, что происходит, когда вы назначаете объект QObject объекту QObject.Я предполагаю, что копия объекта сделана, даже если объект был передан через ссылку (не через указатель, конечно, это будет просто копия указателя).

Я также предполагаю, что что-то вроде QStringList выполняетDeepcopy ... это правильно?

Ответы [ 2 ]

1 голос
/ 06 апреля 2010

Назначение переменной QStringList работает так же, как назначение любой другой переменной в C ++. Для объектов оператор присваивания объекта слева вызывается для копирования содержимого объекта справа в объект слева. Обычно это делается только для членов:

struct A {
  int x;
  QString y;

  A& operator=(const A &other) {
    // do the assignment:
    x = other.x;
    y = other.y;

    return *this;
  }
};

Объект слева от назначения «приспосабливается» к тому же предмету, что и объект справа. Новый объект не выделен, только существующий изменен.

Если класс более сложный и, например, содержит указатели на динамически распределяемые данные (как это, вероятно, имеет место для QStringList), оператор присваивания может быть более сложным для реализации. Но это деталь реализации класса QStringList, и вам не нужно об этом беспокоиться. Объект QStringList слева от назначения будет изменен, чтобы быть равным объекту справа.

В вопросе 2 вы назначаете объект переменной-члену, что приводит к изменению объекта в переменной-члене так, чтобы он содержал те же вещи, что и объект, который ему назначен. То, что этот другой объект позже будет удален, не имеет значения для переменной-члена.

Семантически это то же самое, что и при назначении простых целых чисел:

int i, j;
i = j;

Память, в которой хранится i, изменяется, поэтому в ней содержится то же значение, что и j. То, что произойдет с j позже, не имеет значения для i.

0 голосов
/ 06 апреля 2010

Что происходит, когда я переназначаю переменную qsl, что происходит с "foo" и исходными данными, расположенными в первой строке?

Вы не можете переназначить qsl чему-то другому в той же области видимости.
Как только он выйдет из области видимости, память будет восстановлена ​​в его деструкторе.
Вы можете поместить различные данные в qsl, и в этом случае он заменит «foo», при необходимости может быть выделено больше памяти

редактировать: напр. ты не можешь иметь "QStringlist qsl;" Тогда в том же блоке кода есть "int qsl;"
Вы можете заменить строки в qsl другим списком, и контейнер будет обрабатывать память для вас

Я также предполагаю, что что-то вроде QStringList выполняет глубокую копию

Да, - на самом деле это немного сложнее, чтобы сэкономить время / память, Qt сделает копию только тогда, когда это необходимо, то есть, когда она изменится. Если вы копируете «строку» во множество различных списков строк, Qt просто сохранит одну копию и поделится ею с другими, когда она будет изменена, она выделит новую копию для измененной - это называется «копировать при записи», но происходит автоматически вам не нужно заботиться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...