使用默认和重写的复制构造函数时的两种不同行为

时间:2013-05-10 15:32:22

标签: c++ copy-constructor

当我覆盖复制构造函数时,为什么它首先删除segfaults本身。     输出:

$./a.out
inside ctor
inside copy-ctor
Say i am in someFunc
inside dtor
*** glibc detected *** ./a.out: free(): invalid pointer: 0xb75f3000 ***

如果我不覆盖copy-ctor,那么我可以看到s1.PrintVal()被调用,然后在* ptr中出现了预期的seg错误。

为什么有两种不同的行为有和没有默认和重写的copy-ctor?

#include<iostream>
using namespace std;
class Sample
{
public:
    int *ptr;
    Sample(int i)
    {
        cout << "inside ctor" << endl;
        ptr = new int(i);
    }
    Sample(const Sample &rhs)
    {
        cout << "inside copy-ctor" << endl;
    }
    ~Sample()
    {
        cout << "inside dtor" << endl;
        delete ptr;
    }
    void PrintVal()
    {
        cout <<" inside PrintVal()."<<endl;
        cout << "The value is " << *ptr<<endl;
    }
};
void SomeFunc(Sample x)
{
    cout << "Say i am in someFunc " << endl;
}

int main()
{
    Sample s1= 10;
    SomeFunc(s1);
    s1.PrintVal();
    return 0;
}

2 个答案:

答案 0 :(得分:3)

在你的copy-ctor中,你实际上并没有复制ptr,这意味着它的值将是未指定的,你将删除一个未指定的指针(而不是像你一样删除一个普通的指针) defauly copy-ctor)。

答案 1 :(得分:0)

默认复制ctor按值复制每个成员。这将为指针创建一个别名,因此每个类在调用其dtor时都会删除指针并导致错误。

在几乎任何有指针分配的类中,您需要编写自定义复制构造函数来分配指针然后复制该值。

class Sample
    {
            public:
                            int *ptr;
                            Sample(int i)
                            {
                                    cout << "inside ctor" << endl;
                                    ptr = new int(i);
                            }
                            Sample(const Sample &rhs)
                            {
                                    ptr = new int(*rhs.ptr);
                            }
                            Sample & operator=(const Sample& other)
                            {
                                // You should also override copy assignment if you overide copy 
                                // you don't need to allocate in this case just copy the value 
                                *ptr = *other.ptr;
                            }
                            ~Sample()
                            {
                                    cout << "inside dtor" << endl;
                                    delete ptr;
                            }
                            void PrintVal()
                            {
                                    cout <<" inside PrintVal()."<<endl;
                                    cout << "The value is " << *ptr<<endl;
                            }
    };

你应该查看rule of three,如果你的c ++ 11是五的规则