在完成对C语言的学习后,我最近开始了对C++和Java的学习,目前跟着视频学习了一些语法,也跟着敲了一些代码,有了一定的掌握程度。现在将跟着视频做的笔记进行整理。本篇博客是整理C++知识点的第十二篇博客。
本篇博客介绍了C++的构造函数。
本系列博客所有C++代码都在Visual Studio 2022环境下编译运行。程序为64位。
目录
这一部分接着上一篇对构造函数的初步介绍。
C++中,调用拷贝构造函数的时机通常有这三种情况:
使用一个已经创建的对象初始化一个新对象。
用值传递给函数参数传参。
以值的方式返回局部对象。
- #include
- using namespace std;
- class test {
- public:
- int age;
- test() {
- cout << "This is A" << endl;
- }
- test(const int num) {
- age = num;
- cout << "This is B" << endl;
- cout << "Age = " << age << endl;
- }
-
- test(const test& temp) {
- age = temp.age;
- cout << "This is C" << endl;
- cout << "Age = " << age << endl;
- }
- };
-
- int main(void)
- {
- test test1;
- test test2(10);
- test test3(test2);
- return 0;
- }
程序中用已经创建的test2初始化一个新的对象test3。
程序的输出是:
This is A
This is B
Age = 10
This is C
Age = 10
- #include
- using namespace std;
- class test {
- public:
- int age;
- test() {
- cout << "This is A" << endl;
- }
- test(const int num) {
- age = num;
- cout << "This is B" << endl;
- cout << "Age = " << age << endl;
- }
- test(const test& temp) {
- age = temp.age;
- cout << "This is C" << endl;
- cout << "Age = " << age << endl;
- }
- };
- void testfunc(test temp);
-
- int main(void)
- {
- test test1(10);
- testfunc(test1);
- return 0;
- }
-
- void testfunc(test temp)
- {
- return;
- }
程序创建了一个test1对象,随后将这个对象作为参数以值传递的方式传递给testfunc函数。testfunc函数只接受这个参数,什么也不执行。因为值传递需要拷贝,所以会执行拷贝构造函数。
程序的输出是:
This is B
Age = 10
This is C
Age = 10
- #include
- using namespace std;
- class test {
- public:
- int age;
- test() {
- cout << "This is A" << endl;
- }
- test(const int num) {
- age = num;
- cout << "This is B" << endl;
- cout << "Age = " << age << endl;
- }
-
- test(const test& temp) {
- age = temp.age;
- cout << "This is C" << endl;
- cout << "Age = " << age << endl;
- }
- };
- test testfunc(void);
- int main(void)
- {
- test test2 = testfunc();
- return 0;
- }
-
- test testfunc(void)
- {
- test test1(10);
- return test1;
- }
程序进入main函数后,先执行testfunc函数,testfunc函数创建了一个对象,并将该对象返回main函数,main函数接收后返回。由于返回值也是拷贝,会调用拷贝构造函数。
程序的输出是:
This is B
Age = 10
This is C
Age = 10
默认情况下,C++编译器会给一个类添加一个默认构造函数,此构造函数无参,函数体为空。还会添加一个默认析构函数,函数体为空。还会添加一个默认拷贝构造函数,对属性进行值拷贝。
如果已经自定义有参构造函数,那么编译器不再提供默认无参构造函数,但是会提供默认拷贝构造。如果自定义拷贝构造函数,那么编译器不会提供其他构造函数。
浅拷贝就是简单的赋值拷贝操作,深拷贝会在堆区重新申请空间,进行拷贝。
编译器默认浅拷贝,这样在释放空间时造成重复释放,会导致程序崩溃。如果一个类中有堆区的数据,并且涉及到拷贝,要自己提供拷贝构造函数进行深拷贝。
- #include
- using namespace std;
- class test {
- public:
- int age;
- int* height;
- test() {
- cout << "This is A" << endl;
- }
- test(const int numage, const int numheight) {
- age = numage;
- height = new int(numheight);
- cout << "This is B" << endl;
- cout << "Age = " << age << endl;
- cout << "Height = " << *height << endl;
- }
-
- test(const test& temp) {
- age = temp.age;
- height = new int(*temp.height);
- cout << "This is C" << endl;
- cout << "Age = " << age << endl;
- cout << "Height = " << *height << endl;
- }
- ~test() {
- delete height;
- cout << "This is D" << endl;
- }
- };
-
- int main(void)
- {
- test test1(20, 170);
- test test2(test1);
- return 0;
- }
test类提供只输出This is A的无参构造函数。同时提供一个有参构造函数,对age和height进行赋值,age存储在栈区,height存储在堆区,进行了内存开辟。同时输出This is B和成员变量信息。同时提供拷贝构造函数,对height进行了深拷贝,同时输出This is C和成员变量信息。test类的析构函数将height销毁,同时输出This is D。
main函数用有参构造函数和拷贝构造函数进行初始化。程序的输出是:
This is B
Age = 20
Height = 170
This is C
Age = 20
Height = 170
This is D
This is D
C++提供了初始化列表,用来初始化属性。语法是:
构造函数():属性1(值1),属性2(值2),属性3(值3)...{...}
- #include
- using namespace std;
- class test {
- public:
- int A;
- int B;
- int C;
- test() :A(10), B(15), C(20){}
- test(int a,int b,int c) :A(10), B(15), C(20)
- {
- A = a;
- B = b;
- C = c;
- }
-
- void show() {
- cout << "A = " << A << endl;
- cout << "B = " << B << endl;
- cout << "C = " << C << endl;
- }
- };
- int main(void)
- {
- test atest;
- atest.show();
- return 0;
- }
程序创建了test类,test类有成员A,B,C,构造函数中默认初始化值为10,15,20。程序创建了一个类对象,并调用了无参构造函数。程序的输出是:
A = 10
B = 15
C = 20
如果用构造函数,传入三个0作为参数,程序的输出是:
A = 0
B = 0
C = 0
一个类的成员可以是另一个类的一个对象。
当有其他类的对象作为本类成员时,构造时先构造类对象,后构造自身,析构时相反。
- #include
- #include
- using namespace std;
- class Phone {
- public:
- string brand;
- Phone(void) {
- cout << "A" << endl;
- }
- ~Phone(void) {
- cout << "Z" << endl;
- }
- };
-
- class Person {
- public:
- string name;
- Phone phone;
- Person(string tempname, string tempbrand){
- cout << "a" << endl;
- name = tempname;
- phone.brand = tempbrand;
- }
-
- void show() {
- cout << "The name is " << name << endl;
- cout << "The phone is " << phone.brand << endl;
- }
- ~Person() {
- cout << "z" << endl;
- }
- };
- int main(void)
- {
- Person people("Allen", "Apple");
- people.show();
- return 0;
- }
程序提供了Phone类,有一个成员变量brand,构造函数输出A,析构函数输出Z。程序还有Person类,有一个成员变量是字符串name,另一个成员变量是Phone类对象phone。Person类的带参构造函数输出a,同时对成员变量进行赋值。析构函数输出z,show函数输出成员变量信息。main函数中实例化Person类对象并执行此对象的show函数。
程序的输出是:
A
a
The name is Allen
The phone is Apple
z
Z