首页 > 代码库 > C++对C的加强 总结(5)

C++对C的加强 总结(5)

C++中的构造函数和析构函数 

基本概念

构造函数总结

构造函数是C++中用于初始化对象状态的特殊函数

构造函数在对象创建时自动被调用(默认调用),隐身调用

构造函数和普通成员函数都遵循重载规则

拷贝构造函数是对象正确初始化的重要保证

必要的时候,必须手工编写拷贝构造函数 

 

构造函数的调用 

自动调用:一般情况下C++编译器会自动调用构造函数

手动调用:在一些情况下则需要手工调用构造函数

构造函数有三种

有参构造函数、默认构造函数、拷贝构造函数

析构函数

 

 

 

有参构造函数调用的三种方法

//

class Test

{

public:

 

//有参构造函数

Test(int a)

{

m_a = a;

}

//无参数构造函数

Test()

{

m_a = 0;

}

//四种应用场景

//赋值构造函数 copy构造函数

Test(const Test &obj)

{

 

}

public:

void print()

{

cout<<"m_a"<<m_a<<endl;

}

protected:

private:

int m_a;

};

 

void main66()

{

 

//括号法

Test t1(10); //c++编译器自动调用这个类的有参构造函数

t1.print();

//=

Test t2 = 20; //c++编译器自动调用这个类的有参构造函数

t2.print();

//

Test t3 = Test(30);//程序员手工的调用构造函数 进行对象初始化

t3.print();

system("pause");

}

 

构造函数用来完成对象的构造(初始化)工作,

赋值构造函数(copy构造函数) 和 操作是两个不同的概念

赋值构造函数(copy构造函数)的四个应用场景

 

void main81()

{

 

Test88 t1;

//t1.SetBuf("我是t1");

t1.setA(10);

 

Test88 t3;

//第一种场景

//1赋值构造函数和=操作是两个不同的概念

//2  赋值构造函数 copy构造函数 也是构造函数

//在这个场景之下。t2被创建,并且自动的调用copy构造 

//3 当我们没有编写copy构造函数(赋值构造函数)的时候,c++编译器会默认给我们提供一个copy构造函数 执行的是浅copy

Test88 t2 = t1; //对象t2的初始化

cout<<t2.getA()<<endl;

 

//t2 = t1; //是对象的=操作

system("pasue");

}

void main888()

{

 

Test88 t1;

t1.setA(10);

 

//第二种场景

Test88 t2(t1);

 

system("pasue");

}

void f ( Location  p )    

{

cout << "Funtion:" << p.GetX() << "," << p.GetY() << endl ; 

}

void playobjmain()

Location A ( 1, 2 ) ; 

f ( A ) ;

}

class Location 

{

public:

Location( int xx = 0 , int yy = 0 ) 

X = xx ;  Y = yy ;  cout << "Constructor Object.\n" ;  

}

Location( const Location & p )      //复制构造函数

X = p.X ;  Y = p.Y ;   cout << "Copy_constructor called." << endl ;  }

~Location() { cout << X << "," << Y << " Object destroyed." << endl ; }

int  GetX () { return X ; } int GetY () { return Y ; }

private :   int  X , Y ;

} ;

 

void f ( Location  p )    

{

cout << "Funtion:" << p.GetX() << "," << p.GetY() << endl ; 

}

// void playobjmain()

// { 

//  Location A ( 1, 2 ) ; 

//  f ( A ) ;

// } 

Location g()

{

Location A(1, 2);

return A;

}

void main101()

Location B;

B = g();

 

void main102()

//g() 返回一个匿名对象

Location B = g();

}

 

void main1111()

main102();

system("pause");

}

 

 

构造函数析构函数调用规则

规则总结:

/*

当类中没有定义任何一个构造函数时,c++编译器会提供无参构造函数和拷贝构造函数

当类中定义了任意的非拷贝构造函数(无参、有参),c++编译器不会提供无参构造函数

当类中定义了拷贝构造函数时,c++编译器不会提供无参数构造函数

默认拷贝构造函数成员变量简单赋值

总结:只要你写了构造函数,那么你必须用。

*/

 

//对象做函数参数

//1 研究拷贝构造 

//2 研究构造函数,析构函数的调用顺序

 

//总结 构造和析构的调用顺序

 

#include "iostream"

using namespace std;

 

class ABCD 

{

public:

ABCD(int a, int b, int c)

{

this->a = a;

this->b = b;

this->c = c;

printf("ABCD() construct, a:%d,b:%d,c:%d  \n", this->a, this->b, this->c);

}

~ABCD()

{

printf("~ABCD() construct,a:%d,b:%d,c:%d  \n", this->a, this->b, this->c);

}

int getA() 

{

return this->a;

}

protected:

private:

int a;

int b;

int c;

};

 

 

class MyE

{

public:

MyE():abcd1(1,2,3),abcd2(4,5,6),m(100)

{

cout<<"MyD()"<<endl;

}

~MyE()

{

cout<<"~MyD()"<<endl;

}

MyE(const MyE & obj):abcd1(7,8,9),abcd2(10,11,12),m(100)

{

printf("MyD(const MyD & obj)\n");

}

 

protected:

//private:

public:

ABCD abcd1; //c++编译器不知道如何构造abc1

ABCD abcd2;

const int m;

 

};

 

int doThing(MyE mye1)

{

printf("doThing() mye1.abc1.a:%d \n", mye1.abcd1.getA()); 

return 0;

}

 

int run2()

{

MyE myE;

doThing(myE);

return 0;

}

 

//

int run3()

{

printf("run3 start..\n");

ABCD abcd = ABCD(100, 200, 300);

//若直接调用构造函数哪

//想调用构造函数对abc对象进行再复制,可以吗?

//在构造函数里面调用另外一个构造函数,会有什么结果?

//ABCD(400, 500, 600); //临时对象的生命周期

printf("run3 end\n");

return 0;

}

 

int main()

{

//run2();

run3();

system("pause");

return 0;

}

 

 

深拷贝浅拷贝

 

name( name &obj)

{

cout <<" copy Constructing " << endl ;

char *pn2 = obj.getPn();

pname = (char *)malloc(strlen(pn2) +1);

if (pname!=NULL) strcpy(pname,pn2) ;

//pname = new char[strlen(pn)+1] ;

//if (pname!=0) strcpy(pname,pn) ;

size = strlen(pn2) ;

}

 

static专题讲座

void main1888()

{

///GetStatic();

//GetStatic();

Test3 t1(1, 3), t2(3, 4), t3(5, 65);

 

//Test(&t2, 3, 4),

 

cout<<Test3::getCount()<<endl;;

cout<<t3.getCount()<<endl;;

 

system("pause");

}

 

重载=操作符内存泄露场景

void operator=( name &obj1)

{

cout <<" 执行=操作" << endl ;

if (pname != NULL)

{

free(pname);

pname = NULL;

size = 0;

}

 

char *pn = obj1.getPn();

pname = (char *)malloc(strlen(pn) +1);

if (pname!=NULL) strcpy(pname,pn) ;

//pname = new char[strlen(pn)+1] ;

//if (pname!=0) strcpy(pname,pn) ;

pname[0] = ‘m‘;

size = strlen(pn) ;

}