简体   繁体   English

STL向量,指针和类

[英]STL Vectors, pointers and classes

Let's say i have 2 classes: 假设我有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));
  }
};

Will this work? 这样行吗? Or the memory allocated in the InitializerClass2::Initialize() method might get corrupted after the method terminates? 还是在方法终止后在InitializerClass2 :: Initialize()方法中分配的内存可能会损坏?

Thanks! 谢谢!

In short this will work fine. 简而言之,这可以正常工作。

The memory being allocated in Initialize is on the heap. 在Initialize中分配的内存在堆上。 This means that changes in the stack do not affect the contents of this memory. 这意味着堆栈中的更改不会影响此存储器的内容。

One issue I see with Class1 is that it is not copy safe yet the copy and assignment constructors have not been suppressed. 我对Class1看到的一个问题是,它不是复制安全的,但是复制和赋值构造函数尚未被禁止。

This can cause a problem because the destructor of Class1 is noted as freeing the memory for all items in mVec . 这可能会引起问题,因为Class1的析构函数被标记为释放mVec所有项目的mVec Using the implicit operator this means that you'd end up with 2 instances of Class1 pointing to the same CustomClass3 instances and the second destructor would be double deleting memory. 使用隐式运算符,这意味着您最终将有两个Class1实例指向相同的CustomClass3实例,而第二个析构函数将是删除内存的两倍。 For example 例如

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

In this case the second destructor to run (c1) will be freeing an already deleted CustomClass3 instance. 在这种情况下,要运行的第二个析构函数(c1)将释放已经删除的CustomClass3实例。 You should disable copy construction and assignment for Class1 to prevent this 您应该为Class1禁用复制构造和分配,以防止出现这种情况

class Class1 { 
  ...
private:
  Class1(const Class1&);
  Class1& operator=(const Class1&);
};

它应该可以工作(当然, mPtrClass1mPtrClass1是有效的指针)。

May I suggest that in your InitializerClass2 that you change the constructor to the following: 我可以建议您在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) );
}

if you're not going to use RAII, so that you don't get issues with checking the destructor. 如果您不打算使用RAII,则不会在检查析构函数时遇到问题。

As to your question, see where I added in the new operator. 关于您的问题,请参阅我在新运算符中添加的位置。 YOu're not initializing your variable. 您尚未初始化变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM