对象的构造和析构
1)c++中的类可以定义与类名相同的特殊成员函数,这种与类名相同的函数叫做构造函数
2)构造函数在定义时可以由参数
3)没有任何形式的返回类型
构造函数的调用:
一般情况C++会自动调用
一些情况需要手动调用
析构函数:
没有参数,没有返回类型, 对象销毁的时候自动调用
#include <iostream>
using namespace std;
class Test{
public:
Test(){
cout<<"我是构造函数"<<endl;
}
~Test(){
cout<< "析构函数被调用" <<endl;
}
protected:
private:
};
//给对象一个行为平台,来研究对象行为
void objplay(){
Test t1,t2;
}
void main(){
objplay();
cout<<"hello"<<endl;
system("pause");
return ;
}
//先创建的对象后析构
#include <iostream>
using namespace std;
class Test{
public:
Test(){//完成初始化作用
a=10;
p=(char *)malloc(100);
strcpy(p,"aaaaaafff");
cout<<"我是构造函数"<<endl;
}
void print(){
cout<<p<<endl;
cout<<a<<endl;
}
~Test(){
if(p!=NULL){
free(p);
}
cout<< "析构函数被调用" <<endl;
}
protected:
private:
int a ;
char *p;
};
//给对象一个行为平台,来研究对象行为
void objplay(){
Test t1,t2;
t1.print();
t2.print();
}
void main(){
objplay();
cout<<"hello"<<endl;
system("pause");
return ;
}
#include <iostream>
using namespace std;
class Test2{
public :
Test2(){
cout<<"无参构造函数"<<endl;
}
Test2(int ta,int tb){
a =ta;
b =tb;
cout<<"带参构造函数"<<endl;
}
Test2(const Test2 &obj){//拷贝(赋值)构造函数
cout<<"拷贝构造函数"<<endl;
}
~Test2(){
cout<<"析构函数"<<endl;
}
protected:
private:
int a;
int b;
};
void main(){
Test2 t1;
Test2 t2(3,4);//调用有参构造法1
Test2 t4();//注意:这里尽管没参数,但是实际上调用有参构造
//Test2 t5 = (3,4);//这个错误常见,想要解决就要增加一个参数的构造函数
// c++中对=操作符进行了功能性增强、
Test2 t6 = Test2(4,6);//也是调用有参构造,手动的调用构造函数
//直接调用构造函数,会有一个匿名对象
Test2 t3(t2);
cout<<"hello"<<endl;
system("pause");
return ;
}
//设计构造函数和析构函数的原因
类似一共一个统一的出厂配置
如果没有写构造函数,C++编译器会默认提供一个构造函数
定义对象数组时,没有机会进行初始化
//拷贝构造函数四种调用时机
1.用一个对象初始化另一个对象
2.用已经存在的函数赋值另一个对象
3.用实参调用形参的时候
4.返回的复杂对象进行赋值
#include <iostream>
using namespace std;
class Test4{
public :
Test4(){
cout<<"无参构造函数"<<endl;
}
Test4(int ta,int tb){
a =ta;
b =tb;
cout<<"带参构造函数"<<endl;
}
Test4(const Test4 &obj){//拷贝(赋值)构造函数
a = obj.a+20;
b=obj.b +20;
cout<<"拷贝构造函数"<<endl;
cout<<a<<b<<endl;
}
int getA(){
return a;
}
int getB(){
return b;
}
~Test4(){
cout<<"析构函数"<<endl;
}
protected:
private:
int a;
int b;
};
//业务函数 形参是一个元素
void f(Test4 p ){
cout<<p.getA()<<endl;
}
Test4 g(){
Test4 g1(5,6);
return g1;
}
void objPlay(){
g();
}
void main(){
//1.赋值构造函数,用一个对象初始化另外一个对象
Test4 t1(1,2);//带参构造
Test4 t0(1,2);//带参构造
Test4 t2 = t1;//用t1来初始化t2 ,拷贝构造
t0=t1;//用t1给t0赋值,这个和初始化是两个不用的概念。
//2.第2种调用方法
Test4 t4(t1);//用一个对象初始化t2对象
//3.第3种调用方法
f(t2);//用实参t2初始化形参p,也调用了拷贝构造函数
//4.第4种调用方法
g();//调用有参构造,返回新的匿名对象
objPlay();
//注意,其实这里调用了两次构造,第二次就是拷贝构造
Test4 t5 = g();//调用拷贝构造,返回的元素是一个复杂类型,给另外的对象初始化
cout<<"hello"<<endl;
system("pause");
return ;
}
//有关匿名对象的去留
//如果用匿名对象初始化另外一个同类型的对象,匿名对象,转成有名对象
//如果用匿名对象赋值给另一个同类型的对象,匿名对象被析构,这个是很重要的点
Test4 t6= g();//转成又名对象
Test t7(1,2); t7 = g();//赋值完马上析构