我尝试为我在类Shop中初始化和声明的对象的指针向量编写一个复制构造函数。考虑的向量是:
std::vector <gCustomer*> vCustomer;
它也在gShop的构造函数中声明,并在析构函数中通过循环删除。
现在我希望在复制构造函数中有一个指针向量的深层副本。但实际上没有任何内容被复制,如果我设法运行程序并访问vCustomer,则检查其大小是否为零或者崩溃程序。 (注意,如果我将复制构造函数保留在外,以便使用默认的复制构造函数,则程序运行正常)
gShop::gShop(const gShop & cShop)
{
for(int i = 0; i < (int)vCustomer.size(); ++i)
{
vCustomer[i] = cShop.vCustomer[i];
}
}
由于
注意我也有一个指定的运算符
gShop gShop::operator=(const gShop & rhs)
{
if (this == &rhs) return *this;
for(int i = 0; i < (int)vCustomer.size(); ++i)
{
delete vcustomer[i];
vCustomer[i] = new gCustomer;
vCustomer[i]= rhs.vCustomer[i];
}
}
答案 0 :(得分:1)
循环
gShop::gShop(const gShop & cShop)
{
for(int i = 0; i < (int)vCustomer.size(); ++i)
{
vCustomer[i] = cShop.vCustomer[i];
}
}
使用了错误的限制。它应该从0到现有对象的长度:
i < (int)cShop.vCustomer.size()
答案 1 :(得分:1)
您错误地实现了复制构造函数和赋值运算符,它们正在执行浅拷贝而不是深拷贝,并且它们不会调整目标向量的大小。这是一个深拷贝复制构造函数
gShop::gShop(const gShop & cShop)
{
for(int i = 0; i < (int)cShop.vCustomer.size(); ++i)
{
if (cShop.vCustomer[i])
vCustomer.push_back(new gCustomer(*cShop.vCustomer[i]));
else
vCustomer.push_back(NULL);
}
}
这是一个深拷贝赋值运算符
gShop& gShop::operator=(const gShop & rhs)
{
if (this == &rhs) return *this;
// clear any existing data
for(int i = 0; i < (int)vCustomer.size(); ++i)
delete vcustomer[i];
vcustomer.clear();
// add the new data
for(int i = 0; i < (int)rhs.vCustomer.size(); ++i)
{
if (rhs.vCustomer[i])
vCustomer.push_back(new gCustomer(*rhs.vCustomer[i]));
else
vCustomer.push_back(NULL);
}
return *this;
}
基本上问题是你是在复制指针而不是分配新的内存。如果你想要一个深层复制,你必须分配新的内存。
当然还有更大的问题,为什么你要使用指针向量。向量的一大优势是,您不再需要通过使用已丢失该优势的指针向量来显式管理内存。我不认识你的节目,但在我看来,std::vector<gCustomer>
会比std::vector<gCustomer*>
更好。使用std::vector<gCustomer>
,您不需要编写复制构造函数或赋值运算符,深层复制将自动发生(假设gCustomer
执行深层复制)。
答案 2 :(得分:-1)
的std ::矢量&lt;&GT;有拷贝构造函数本身来做深拷贝。 因此编译器提供的复制构造函数将完成您想要的工作。 如果你想自己实现它,那么在gShop的构造函数的init列表中会更好。
gShop::gShop(const gShop & cShop):vCustomer(cShop.vCustomer)
{
}
vCustomer的大小在复制文件中始终为零。
我对你的operator =()感到困惑。你想要什么? 我建议你阅读一些关于c ++ primer的教科书。