何时需要自定义拷贝构造函数

包含动态内存分配的类需要自定义拷贝构造函数。

无定义默认为浅拷贝,此时参数对象和创建对象的指针成员指向同一块内存,调用二者的析构函数时第一对象调用释放内存成功,第二个对象会再次进行释放内存,此时运行时出错double free

故:应定义,且为深拷贝

浅拷贝实例代码:

 1 #include<iostream>
 2
 3 class A
 4 {
 5     public:
 6         A()
 7         {
 8             std::cout << "constructor is called" << std::endl;
 9             n = new int[10];
10             n[0] = 1;
11         }
12         // 默认拷贝构造函数
13         /*A(const A &t)
14         {
15             std::cout << "copy constructor is called" << std::endl;
16             n = t.n;
17         }
18         */
19
20         ~A()
21         {
22             std::cout << "destructor is called" << std::endl;
23             delete n;
24         }
25
26         void get() { std::cout << "n[0]: " << n[0] << std::endl; }
27     private:
28         int *n;
29 };
30
31 int main(void)
32 {
33     A a;
34     A b(a);
35     b.get();
36
37     return 0;
38 }

编译运行后结果:

深拷贝实例代码:

 1 #include<iostream>
 2 #include<string.h>
 3
 4 class A
 5 {
 6     public:
 7         A()
 8         {
 9             std::cout << "constructor is called" << std::endl;
10             n = new int[10];
11             n[0] = 1;
12         }
13         // 深拷贝
14         A(const A &t)
15         {
16             std::cout << "copy constructor is called" << std::endl;
17             n = new int[10];
18             memcpy(n, t.n, 10);
19         }
20
21         ~A()
22         {
23             std::cout << "destructor is called" << std::endl;
24             delete n;
25         }
26
27         void get() { std::cout << "n[0]: " << n[0] << std::endl; }
28     private:
29         int *n;
30 };
31
32 int main(void)
33 {
34     A a;
35     A b(a);
36     b.get();
37
38     return 0;
39 } 

编译运行结果:

时间: 2024-09-29 19:38:33

何时需要自定义拷贝构造函数的相关文章

【转载】C++拷贝构造函数(深拷贝,浅拷贝)

对于普通类型的对象来说,它们之间的复制是很简单的,例如:int a=88;int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量.下面看一个类对象拷贝的简单例子. #include <iostream>using namespace std;class CExample {private:     int a;public:     CExample(int b)     { a=b;}     void Show ()     {        cout<

C++拷贝构造函数(深拷贝,浅拷贝)

http://www.cnblogs.com/BlueTzar/articles/1223313.html 对于普通类型的对象来说,它们之间的复制是很简单的,例如:int a=88;int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量.下面看一个类对象拷贝的简单例子. 1 #include <iostream> 2 using namespace std; 3 4 class CExample { 5 private: 6 int a; 7 public: 8

C++的拷贝构造函数

1?  类会提供默认的拷贝构造函数 –默认的拷贝构造函数会完成所有成员的逐个复制 2?  拷贝构造的调用时机: –函数值传递时 –函数返回时 –用同类型的对象初始时 3?  何时需要自定义拷贝构造函数? –类中有指针(或引用 )成员时 –希望自定义对象的拷贝过程时 4?  使用匿名对象简化编程 // // main.cpp // 拷贝构造函数 // // Created by 06 on 15/1/26. // Copyright (c) 2015年 黄永锐. All rights reserv

C++拷贝构造函数(浅拷贝、深拷贝)

下面举一个简单的例子说明对象之间的拷贝(此例中没有自定义拷贝构造函数,在调用拷贝构造函数的时候,编译器会自动生成一个默认的拷贝构造函数,该构造函数完成对象之间的位拷贝)浅拷贝: #include<iostream> using namespace std; class CExample { private:int a; public: CExample(int b) { a=b; } void Show() { cout<<a<<endl; } }; int main(

C++类对象的复制-拷贝构造函数

在学习这一章内容前我们已经学习过了类的构造函数和析构函数的相关知识,对于普通类型的对象来说,他们之间的复制是很简单的,例如: int a = 10; int b =a; 自己定义的类的对象同样是对象,谁也不能阻止我们用以下的方式进行复制,例如: #include <iostream>  using namespace std;    class Test  {  public:      Test(int temp)      {          p1=temp;      }  prote

拷贝构造函数的用法

1.拷贝构造函数是与类名相同,其形参是本类的对象的引用. 2.拷贝构造函数会在以下三种情况下被调用: 1).当用类的一个对象去初始化该类的另一个对象时. 2).如果函数的形参是类的对象,调用该函数,将对象作为函数实参传递给函数的形参时. 3).如果函数的返回值是类的对象,函数执行完成,将返回值返回时. 3.浅拷贝的失败例子: 1 #include <iostream> 2 #include <cstring> 3 4 using namespace std; 5 6 7 class

拷贝构造函数与赋值函数的区别

1.从概念上区分:复制构造函数是构造函数,而赋值操作符属于操作符重载范畴,它通常是类的成员函数 2.从原型上来区分:复制构造函数原型ClassType(const ClassType &);无返回值赋值操作符原型ClassType& operator=(const ClassType &);返回值为ClassType的引用,便于连续赋值操作 3.从使用的场合来区分:复制构造函数用于产生对象,它用于以下几个地方:函数参数为类的值类型时.函数返回值为类类型时以及初始化语句,例如(示例了

拷贝构造函数(深拷贝vs浅拷贝)

类对象之间的初始化是由类的拷贝构造函数完成的.它是一种特殊的构造函数,它的作用是用一个已知的对象来初始化另一个对象.如果在类中没有显式地声明一个拷贝构造函数,那么,编译器将会自动生成一个默认的拷贝构造函数,该构造函数完成对象之间的位拷贝.位拷贝又称浅拷贝. 一.拷贝构造函数定义格式 类名::拷贝构造函数名(类名& 引用名) 例如: Tdate ::Tdate(Tdate & d); //形参是一个对象的引用 CString( const CString & stringSrc );

[C++参考]拷贝构造函数的参数必须是引用类型

在C++中, 构造函数,拷贝构造函数,析构函数和赋值函数(赋值运算符重载)是最基本不过的需要掌握的知识.在effective C++中说过这么一点:拷贝构造函数的参数必须是引用类型的.但是为什么呢? 拷贝构造函数的参数必须是引用类型的 如果拷贝构造函数中的参数不是一个引用,即形如CClass(const CClass c_class),那么就相当于采用了传值的方式(pass-by-value),而传值的方式会调用该类的拷贝构造函数,从而造成无穷递归地调用拷贝构造函数.因此拷贝构造函数的参数必须是