深拷贝和浅拷贝的简单区别 拷贝构造函数是一种特殊的构造函数,在创建对象时,它是使用同一类中之前创建过的对象来初始化新创建的对象 。
strcpy是深拷贝,“=”是浅拷贝
使用strcpy时会有两个字符串;而使用“=”只有一个字符串
strcpy是将字符串拷贝到指定地址
1 2 3 4 5 6 7 char * str1 = "字符串" ; char * str2 = str1; str2 = "字符串3" ;
我们在编写程序的过程中,如果不主动编写拷贝构造函数和赋值函数,编译器将会调用默认的函数,如果类中含有指针变量 ,那么如果使用的默认的函数就会有错误,下面首先我们先进行简单的介绍,之后再用具体的例子来加以说明。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 #include <iostream> #include <cstring> #pragma warning (disable : 4996) using namespace std;class Person { public : char * name; int age; Person (const char * name, int age) { this ->name = new char [strlen (name) + 1 ]; strcpy (this ->name, name); this ->age = age; } Person (const Person &a) { age = a.age; name = new char [strlen (a.name)]; strcpy (name,a.name); } void showPerson () { cout << name << " " << age << endl; } ~Person () { if (name != nullptr ) { delete [] name; name = nullptr ; } } }; int main () { char name[100 ] = { 0 }; int age; cin >> name; cin >> age; Person p1 (name, age) ; Person p2 = p1; p2.showPerson (); return 0 ; }
下面再用两个图来说明其区别
strcpy操作方法
“=”操作方法
数组类的拷贝函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 #include <bits/stdc++.h> #include <cstring> using namespace std;class Array { private : int n; int *a; public : Array (){ cin>>n; a=new int [n]; for (int i=0 ;i<n;i++) cin>>a[i]; } ~Array (){ delete []a; } int getlen () { return n; } int get (int i) { return a[i]; } Array (const Array &c) { n=c.n; a=new int [n]; for (int i=0 ;i<n;i++) { a[i]=c.a[i]; } } void show () { for (int i=0 ;i<n;i++) cout<<a[i]<<' ' ; } }; int main () { Array a; Array b=a; b.show (); return 0 ; }
C++函数后面加”:” 1 Sub (int x, int y, int z):Base (x,y)
上述语句中单冒号“:”的作用时表示后面是初始化列表,一般有三种使用场景
1.对父类进行初始化
调用格式为子类构造函数 : 父类构造函数
,如下,其中QMainWindow是MyWindow的父类:
1 MyWindow::MyWindow (QWidget* parent , Qt::WindowFlags flag) : QMainWindow (parent,flag)
2.对类成员进行初始化
1 2 3 4 5 6 7 8 9 A ( int aa, int bb ):a (aa),b (bb){ } A ( int aa, int bb ){ a=aa; b=bb; }
3.对类的const成员变量进行初始化
由于const成员变量的值无法在构造函数内部初始化,因此只能在变量定义时赋值或使用初始化列表赋值。
对于2、3中的应用场景,有以下两点说明:
1、构造函数列表初始化执行顺序与成员变量在类中声明顺序相同,与初始化列表中语句书写先后无关。
2、相对于在构造函数中赋值,初始化列表执行效率更高。
下面上一道例题让大家品一品
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 #include <bits/stdc++.h> using namespace std;class rectangle { private : int length,width; public : rectangle (int x,int y){ length=x; width=y; } void set (int x,int y) { length=x; width=y; } int area () { return length*width; } }; class cuboid :public rectangle{ private : int height; public : cuboid (int x,int y,int z):rectangle (x,y) { height=z; } int getvolume () { return area ()*height; } }; int main () { int x,y,z; cin>>x>>y>>z; cuboid a (x,y,z) ; cout<<a.getvolume (); return 0 ; }
for循环中加: 正常我们想要输出一个数组的全部元素时,需要采用以下的方法:
1 2 3 4 5 6 7 int arr[10 ] = { 54 , 23 , 78 , 9 , 15 , 18 , 63 , 33 , 87 , 66 };for (int i = 0 ; i < 10 ; i++) { cout << arr[i] << " " ; }
在C++11中,我们可以在for循环填加冒号 : 来简化这一过程:
1 2 3 4 5 6 7 8 9 10 11 int arr[10 ] = { 54 , 23 , 78 , 9 , 15 , 18 , 63 , 33 , 87 , 66 }; for (auto a : arr) { cout << a << " " ; } for (auto &a : arr) { cout << a << " " ; }
需要注意的是: 如果传入的迭代参数类型为非引用 时,做的是值拷贝 ,因此修改数据是无效的 。