C++ 我必须删除此对象吗?(如果我不打算被删除)
我编写了一个小软件,想在堆上创建一个新对象。在类成员函数中,我有C++ 我必须删除此对象吗?(如果我不打算被删除),c++,memory-leaks,heap,C++,Memory Leaks,Heap,我编写了一个小软件,想在堆上创建一个新对象。在类成员函数中,我有 void gShop::CreateCustomer(int type, int number) { vSlot[number] = new gCustopmer(type); vSlot[number]->itsContactToShop=itsShopNumber; vSlot[number]->itsNumber=number; } 其中vSlot是指向客户对象的指针向
void gShop::CreateCustomer(int type, int number)
{
vSlot[number] = new gCustopmer(type);
vSlot[number]->itsContactToShop=itsShopNumber;
vSlot[number]->itsNumber=number;
}
其中vSlot是指向客户对象的指针向量。我有一个(此处简称)gShop类,本质上:
class gShop : public gBranch
{
public:
gShop(): vSlot(100){}
~gShop(){}
std::vector <gCustomer*> vSlot;
...
}
class-gShop:public-gBranch
{
公众:
gShop():vSlot(100){}
~gShop(){}
std::矢量vSlot;
...
}
我主要调用成员函数来创建新客户
vShop[0].CreateCustomer(TYPE_M20, 1);
vShop[0].CreateCustomer(TYPE_F40, **2**);//EDIT:typo previously here. I intend to create customers by reading a file later on.
std::cout<< "1" << vShop[0].vSlot[1]->itsTypeString << std::endl;
std::cout<< "2" << vShop[0].vSlot[2]->itsTypeString << std::endl;
vShop[0].CreateCustomer(类型_M20,1);
vShop[0].CreateCustomer(类型为_F40,**2**)//编辑:以前在这里输入错误。我打算稍后通过阅读一个文件来创建客户。
std::cout按照编写代码的方式,您应该为gShop
扩展析构函数实现,以迭代向量vSlot
和删除
每个元素。由于您的内存必须以这种方式进行管理以防止内存泄漏,因此还需要遵循以下步骤。因此,您还需要在复制构造期间执行一些操作(深度复制),并且必须为赋值运算符执行一些操作(清理即将复制的向量,然后执行深度复制)
通过使用智能指针,可以避免这些问题,并允许对象使用默认析构函数、复制构造函数和赋值运算符。例如:
std::vector<std::shared_ptr<gCustomer>> vSlot;
当不再有对内存的引用时,智能指针将为您删除内存。如果你没有C++ 11,你可以使用它。
智能指针将使您的gShop
副本与从中复制的原始gShop
共享相同的指针。智能指针使这种情况正常,因为在同一内存上不会有多个delete
调用。但是,如果您需要深度复制语义,那么您仍然需要实现自己的复制构造函数和赋值操作符来创建深度复制
如果您想要像智能指针一样自动清理的东西,但仍然使用默认的复制构造函数和默认的赋值运算符为您提供深度复制,那么您可以尝试使用
如果您使用的是<代码> g++< /COD>版本4.4或更高版本,那么如果您不需要GNU扩展,则应该能够使用“代码> -STD= GNU+0xx<代码>,或者<代码> -STD= C++ C++ 0x<代码>。如果您有g++
4.7或更高版本,那么选项是-std=gnu++11
或-std=c++11
按照编写代码的方式,您应该扩展gShop
的析构函数实现,以迭代向量vSlot
和删除每个元素。由于您的内存必须以这种方式进行管理以防止内存泄漏,因此还需要遵循以下步骤。因此,您还需要在复制构造期间执行一些操作(深度复制),并且必须为赋值运算符执行一些操作(清理即将复制的向量,然后执行深度复制)
通过使用智能指针,可以避免这些问题,并允许对象使用默认析构函数、复制构造函数和赋值运算符。例如:
std::vector<std::shared_ptr<gCustomer>> vSlot;
当不再有对内存的引用时,智能指针将为您删除内存。如果你没有C++ 11,你可以使用它。
智能指针将使您的gShop
副本与从中复制的原始gShop
共享相同的指针。智能指针使这种情况正常,因为在同一内存上不会有多个delete
调用。但是,如果您需要深度复制语义,那么您仍然需要实现自己的复制构造函数和赋值操作符来创建深度复制
如果您想要像智能指针一样自动清理的东西,但仍然使用默认的复制构造函数和默认的赋值运算符为您提供深度复制,那么您可以尝试使用
如果您使用的是<代码> g++< /COD>版本4.4或更高版本,那么如果您不需要GNU扩展,则应该能够使用“代码> -STD= GNU+0xx<代码>,或者<代码> -STD= C++ C++ 0x<代码>。如果您有g++
4.7或更高版本,那么选项是-std=gnu++11
或-std=c++11
按照编写代码的方式,您应该扩展gShop
的析构函数实现,以迭代向量vSlot
和删除每个元素。由于您的内存必须以这种方式进行管理以防止内存泄漏,因此还需要遵循以下步骤。因此,您还需要在复制构造期间执行一些操作(深度复制),并且必须为赋值运算符执行一些操作(清理即将复制的向量,然后执行深度复制)
通过使用智能指针,可以避免这些问题,并允许对象使用默认析构函数、复制构造函数和赋值运算符。例如:
std::vector<std::shared_ptr<gCustomer>> vSlot;
当不再有对内存的引用时,智能指针将为您删除内存。如果你没有C++ 11,你可以使用它。
智能指针将使您的gShop
副本与从中复制的原始gShop
共享相同的指针。智能指针使这种情况正常,因为在同一内存上不会有多个delete
调用。但是,如果您需要深度复制语义,那么您仍然需要实现自己的复制构造函数和赋值操作符来创建深度复制
如果您想要像智能指针一样自动清理的东西,但仍然使用默认的复制构造函数和默认的赋值运算符为您提供深度复制,那么您可以
gShop::~gShop() {
for(int i = 0; i < (int)vSlot.size(); ++i) {
delete vSlot[i];
}
}
class gShop : public gBranch
{
public:
...
~gShop()
...
};
gShop::~gShop()
{
std::vector<gCustomer*>::iterator iter = vSlot.begin();
std::vector<gCustomer*>::iterator end = vSlot.end();
while (iter != end)
{
delete *iter;
++iter
}
}
void deleteCustomer(gCustomer *customer)
{
delete customer;
}
gShop::~gShop()
{
std::for_each(vSlot.begin(), vSlot.end(), deleteCustomer);
}
vShop[0].CreateCustomer(TYPE_M20, 1);
vShop[0].CreateCustomer(TYPE_F40, 2); // <-- was previously 1
std::cout<< "1" << vShop[0].vSlot[1]->itsTypeString << std::endl;
std::cout<< "2" << vShop[0].vSlot[2]->itsTypeString << std::endl;
class gShop : public gBranch
{
public:
std::vector <gCustomer> vSlot;
...
};
void gShop::CreateCustomer(int type)
{
vSlot.push_back(type);
gCustomer &cust = vSlot.back();
cust.itsContactToShop = itsShopNumber;
cust.itsNumber = vSlot.size()-1;
}
vShop[0].CreateCustomer(TYPE_M20);
vShop[0].CreateCustomer(TYPE_F40);
// remember that vectors are 0-indexed
std::cout<< "0" << vShop[0].vSlot[0].itsTypeString << std::endl;
std::cout<< "1" << vShop[0].vSlot[1].itsTypeString << std::endl;
class gShop : public gBranch
{
public:
std::vector <std::shared_ptr<gCustomer> > vSlot;
...
};
void gShop::CreateCustomer(int type)
{
std::shared_ptr customer = std::make_shared<gCustomer>(type);
customer->itsContactToShop = itsShopNumber;
customer->itsNumber = vSlot.size();
vSlot.push_back(customer);
}
vShop[0].CreateCustomer(TYPE_M20);
vShop[0].CreateCustomer(TYPE_F40);
std::cout<< "0" << vShop[0].vSlot[0]->itsTypeString << std::endl;
std::cout<< "1" << vShop[0].vSlot[1]->itsTypeString << std::endl;