3

我刚刚创建了一个带有整数变量和指针变量的类。创建它的对象后,我将它传递给一个函数。即使在返回函数后,程序也不会抛出异常

#include"iostream"
using namespace std;

class A
{

public :

    int i;

    char *c;

    void show();

};

void func(A obj);

int main()
{

    A a;

    a.i = 10;

    a.c = "string";

    cout << " Before Fun " << endl;

    a.show();

    cout << " Going To Call func " << endl;

    func(a);

    cout << " After func " << endl;

    a.show();

    return 0;

}


void A::show()
{
    cout << " The valuses in Object are " << i << '\t' << c  << endl;
}

void func(A aa)
{       
    cout << " The valuses in Object are " << aa.i << '\t' << aa.c  << endl;  
}

在 The Func 中,我正在传递对象 a(来自 main),它将被复制到 aa(func 堆栈)中。所以从func返回后,如果我调用show(指针c将为a的null),它会给我异常但它没有发生。请帮我证明复制构造函数的要求

4

6 回答 6

7

隐藏复制构造函数。这将在任何地方隐式调用它都会导致编译错误。

class A
{

public :

    int i;

    char *c;
private:
    A(const A& _other);
};
于 2013-05-19T11:46:15.477 回答
1

如果没有为对象声明复制构造函数,则隐式定义一个。此复制构造函数复制对象的每个元素。

在您的示例中,调用func(a)将调用此复制构造函数,因此(将是并且将指向 ) 的第一个元素的aa副本。aaa.i10aa.c"string"

于 2013-05-19T11:48:15.647 回答
1

如果您使用的是 C++11,您可以执行以下操作来删除复制构造函数

class A
{

public :

   int i;

   char *c;
   void operator=(const A& _other) = delete;
   A(const A& _other) = delete;

};

甚至更好:

class A : public NonCopyable   // perhaps std:: or if you prefer boost, boost::
{

public :

   int i;

   char *c;
};

http://en.wikipedia.org/wiki/C++11#Explicitly_defaulted_and_deleted_special_member_functions

于 2013-05-19T11:52:35.480 回答
0

如果您没有显式定义一个隐式复制构造函数,则确实存在。它在您的func()函数中调用。Aobject 被复制并为其成员分配一个值i

结果将是:您确实获得show()i调用func. 这并不奇怪,因为您没有对 A inside 的成员执行任何任务A

编译器的隐式复制构造函数提供了成员方式的复制。这是您在大多数情况下可能需要的。

什么时候默认构造函数不够用?您有类似成员的指针,并且需要它的深层副本。您不想复制指针(复制构造函数会做什么),而是要复制指向的对象。但是为什么需要深拷贝?您不想复制指针(由类的任何实例拥有),并最终在同一个指针上调用两次析构函数。从第二次调用delete此指针开始,堆损坏随之而来。您可能还需要为 shared_pointers 明确复制构造函数。

请注意,出于性能原因,最好通过 const 引用而不是按值传递对象。

于 2013-05-19T11:54:36.340 回答
0

在您的情况下,存在编译器提供的复制构造函数。

修改您的代码并将复制构造函数编写为:

//Default and copy constructor

A()
{
    i = 0;
    c = NULL;
}

A(const A& _other)
{
    cout<<"In copy cons"<<endl;
}

当您在调用func时按照上述修改代码时,在这种情况下会调用您自己的复制构造函数,您将获得垃圾值(无法预测) 在此处输入图像描述

如果您将复制构造函数代码修改为

A(const A& _other)
{
    cout<<"In copy cons"<<endl;

    i = _other.i;

    c = new char [(strlen(_other.c) +1)];

    strcpy(c,_other.c);

}

在此处输入图像描述

现在您可以看到输出和 Copy 构造函数的使用方式和使用位置的差异。

于 2013-05-19T12:07:44.767 回答
0

当你创建一个类时,一个空构造函数和复制构造函数隐式存在。所以这就是它不抛出异常的原因。但是,如果您定义了 ANY 构造函数,则需要定义其他构造函数,否则其余的构造函数将被覆盖。例如,您只定义了一个空构造函数。然后它会抛出异常。因为隐式定义的复制构造函数将被覆盖。这是证明需要复制构造函数的一种方法。

于 2013-05-19T12:12:37.047 回答