我的复制构造函数失败..如何复制指向对象的指针

时间:2013-10-12 06:04:20

标签: c++ copy-constructor

我尝试为我在类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];
        }
    }

3 个答案:

答案 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的教科书。