您的位置:首页 > 编程语言 > C语言/C++

C++ 构造函数,析构函数,拷贝构造函数

2017-06-20 16:17 148 查看
1 C++类的普遍写法

新建NBAPlayer.cpp文件

#include "NBAPlayer.h"

void NBAPlayer::setAge(int age){
this->age = age;
}

int NBAPlayer::getAge(){
return this->age;
}

void NBAPlayer::setName(char *name){
this->name = name;

}
char* NBAPlayer::getName(){
return this->name;
}


新建NBAPlayer.h文件

#pragma once
class NBAPlayer{
public:
int age;
char *name;
public:
void setAge(int age);
int getAge();
void setName(char *name);
char *getName();

};


调用

#include "NBAPlayer.h"

void main(){
NBAPlayer n1;
n1.name = "WestBrook";
n1.age = 28;

cout << n1.getName() <<endl;

system("pause");
}


打印结果

WestBrook


2 构造函数

对象初始化时调用

class NBAPlayer{
private:
char *name;
int age;
public:
//无参构造函数(会覆盖默认的午餐构造函数)
NBAPlayer(){
cout << "无参构造函数" << endl;
}

//有参构造函数会覆盖默认的构造函数
NBAPlayer(char *name,int age){
this->name = name;
this->age = age;
cout << "有参构造函数"<<endl;
}

};


void main(){
NBAPlayer n;
system("pause");
}


打印结果

无参构造函数


当调用有参数构造时:

void main(){
NBAPlayer n2("Durrant",28);
system("pause");
}


打印结果

有参构造函数


另外一种调用方式

NBAPlayer n3 = NBAPlayer("Stephen Curry",29);


3 拷贝构造函数

对象销毁时调用

class NBAPlayer{
private:
char *name;
int age;
public:
NBAPlayer(){
this -> name = (char*)malloc(100);
strcpy(name,"Rose");
age = 30;
cout << "无参构造函数" << endl;
}

//析构函数
//当对象要被系统释放时,析构函数被调用
~NBAPlayer(){
cout << "析构" << endl;
//释放内存
free(this->name);
}
};

void func(){
NBAPlayer n;
}


void main(){
func();
system("pause");
}


打印结果

无参构造函数
析构


4 拷贝构造函数

class NBAPlayer{
private:
char *name;
int age;
public:
NBAPlayer(char*name,int age){
this->name = name;
this->age = age;
cout << "有参构造函数" << endl;
}

//拷贝函数
//默认拷贝构造函数,是值拷贝
NBAPlayer(const NBAPlayer &obj){
this->name=obj.name;
this->age = obj.age;
cout << "拷贝构造函数" << endl;
}

void myPrint(){
cout << name << "," << age << endl;
}
};


1 声明时赋值

void main(){
NBAPlayer n("Derric Rose",29);

//拷贝构造函数被调用的场景
//1 声明时赋值
NBAPlayer n1 = n;
n1.myPrint();
system("pause");
}


打印结果

有参构造函数
拷贝构造函数
Derric Rose,29


2 作为参数传入方法

void func(NBAPlayer n){
n.myPrint();
}


void main(){
NBAPlayer n("Derric Rose",29);

//2 作为参数传入 实参给形参赋值
func(n);

system("pause");
}


打印结果

有参构造函数
拷贝构造函数
Derric Rose,29


3 作为参数返回值返回,给变量初始化赋值

NBAPlayer func1(NBAPlayer n){
n.myPrint();
return n;
}

void main(){
NBAPlayer n("Derric Rose",29);

//3 作为参数返回值返回,给变量初始化赋值
NBAPlayer n2 = func1(n);

system("pause");
}


打印结果

有参构造函数
拷贝构造函数
Derric Rose,29

拷贝构造函数


可以看出最后一个拷贝函数执行是返回值给变量赋值时调用的。

总而言之,拷贝函数在变量初始化赋值时将会被调用。2,3中拷贝函数是在1的基础上衍生出来的。归根结底还是变量在初始化赋值时调用拷贝函数。

4 不会调用拷贝函数的情况

void main(){
NBAPlayer n("Derric Rose",29);

NBAPlayer n2("Wade",30);
//这种情况 不会调用拷贝函数
n2 = n;

system("pause");
}


5 浅拷贝

class NBAPlayer{
private:
char *name;
int age;
public:
NBAPlayer(char*name, int age){
this->name = (char*)malloc(100);
strcpy(this->name,name);
this->age = age;
cout << "有参构造函数" << endl;
}

NBAPlayer(const NBAPlayer &obj){
this->name = obj.name;
this->age = obj.age;
cout << "拷贝构造函数" << endl;
}

~NBAPlayer(){
cout << "析构函数"<< endl;

free(this->name);
}

void myPrint(){
cout << name << "," << age << endl;
}
};

void func(){
NBAPlayer n1("McGready",38);
NBAPlayer n2 = n1;
n2.myPrint();
}


void main(){
func();
system("pause");
}


运行后将会打印

有参构造函数
拷贝构造函数
McGready,38
析构函数
析构函数


然后程序会崩溃,因为在n1调用析构函数释放name后,n2在调用析构函数时,name将会为空。也就是说n1和n2操作的是同一个对象。

6 深拷贝

其他代码一样 只是在拷贝函数中把属性的值拷贝了一份

NBAPlayer(const NBAPlayer &obj){
int len = strlen(obj.name);
this->name = (char*)malloc(len+1);

//拷贝属性值
strcpy(this->name,obj.name);
this ->age = obj.age;

cout << "拷贝构造函数" << endl;
}


在此执行,运行结果一样,但是将不会报错。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐