STL Векторы, указатели и классы - PullRequest
2 голосов
/ 20 марта 2010

Допустим, у меня есть 2 класса:

class Class1
{
public:
  std::vector<CustomClass3*> mVec;
public:
  Class1();
  ~Class1()
  {
    //iterate over all the members of the vector and delete the objects
  }
};

class InitializerClass2
{
private:
  Class1 * mPtrToClass1;
public:
  InitializerClass2();
  void Initialize()
  {
    mPtrToClass1->mVec.push_back(new CustomClass3(bla bla parameters));
  }
};

Будет ли это работать? Или память, выделенная в методе InitializerClass2 :: Initialize (), может быть повреждена после завершения метода?

Спасибо!

Ответы [ 4 ]

2 голосов
/ 20 марта 2010

Одна проблема, которую я вижу с Class1, заключается в том, что она не защищена от копирования, но конструкторы копирования и присваивания не были подавлены.

Это может вызвать проблему, поскольку деструктор Class1 отмечен как освобождение памяти для всех элементов в mVec. Использование неявного оператора означает, что в итоге вы получите 2 экземпляра Class1, указывающих на те же экземпляры CustomClass3, а вторым деструктором будет двойное удаление памяти. Например

Class c1;
c1.mVec.push_back(new CustomClass3(...));
Class c2 = c1;

В этом случае второй запущенный деструктор (c1) освободит уже удаленный экземпляр CustomClass3. Вы должны отключить конструкцию и назначение копирования для Class1, чтобы предотвратить это

class Class1 { 
  ...
private:
  Class1(const Class1&);
  Class1& operator=(const Class1&);
};
2 голосов
/ 20 марта 2010

Короче говоря, это будет работать нормально.

Память, выделяемая при инициализации, находится в куче.Это означает, что изменения в стеке не влияют на содержимое этой памяти.

1 голос
/ 20 марта 2010

Могу ли я предложить, чтобы в вашем InitializerClass2 вы изменили конструктор следующим образом:

InitializerClass2() : mPtrToClass1(NULL){}
~InitializerClass2(){
    if( mPtrToClass1 != NULL) delete mPtrToClass1;
}

void Initialize(){
    if( mPtrToClass1 == NULL){
        mPtrToClass1 = new InitializerClass1();
    }

    mPtrToClass1->mVec.push_back(new CustomClass3(bla bla parameters) );
}

если вы не собираетесь использовать RAII, чтобы у вас не возникало проблем с проверкой деструктора.

Что касается вашего вопроса, посмотрите, куда я добавил новый оператор. Вы не инициализируете свою переменную.

1 голос
/ 20 марта 2010

Должно работать (при условии, что mPtrClass1 - верный указатель, конечно).

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