构造函数与析构函数

构造函数与析构函数,第1张

一、定义 构造函数

主要作用在于创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无须手动调用。即初始化

  •  构造函数,没有返回值也不写void,同时函数体中不能有 return 语句。
  •  函数名称与类名相同
  •  和普通成员函数一样,构造函数是允许重载的。一个类可以有多个重载的构造函数,创建对象时根据传递的实参来判断调用哪一个构造函数。
  •  一个类必须有构造函数,要么用户自己定义,要么编译器自动生成。一旦在类中定义了构造函数,那么创建对象时就一定要调用。如果用户自己没有定义构造函数,那么编译器会自动生成一个默认的构造函数,只是这个构造函数的函数体是空的,也没有形参,也不执行任何 *** 作。
#include 
using namespace std;

class Student
{
private:
    char *m_name;
    int m_age;
    float m_score;
public:
    //声明构造函数
    Student( char *name, int age, float score);
    //声明普通成员函数
    void show();
};


//定义构造函数
Student::Student( char *name, int age, float score){
    m_name = name;
    m_age = age;
    m_score = score;
}
//定义普通成员函数
void Student::show(){
    cout< show();
    return 0;
}
 析构函数 主要作用在于对象销毁前系统自动调用,执行一些清理工作。
  • 析构函数,没有返回值也不写void
  • 函数名称与类名相同,在名称前加上符号 ~
  • 析构函数不可以有参数(构造函数有参数),因此不可以发生重载,一个类只能有一个析构函数。如果用户没有定义,编译器会自动生成一个默认的析构函数。
  • 程序在对象销毁前会自动调用析构,无须手动调用,而且只会调用一次
#include
using namespace std;

class Person {
    public:
    //构造函数
    Person()
    {
     cout << "Person的构造函数调用" << endl;
    };
    //析构函数
    ~Person()
    {
     cout << "Person的析构函数调用" << endl;
    };
    };
    void test01()
    {
     Person p;
    }

    int main()
    {
     test01();
    return 0;
}
二、构造函数的分类及调用 有三种构造函数(定义与声明): 1、无参构造(默认函数)
#include
using namespace std;
class Person
{
public:
	//声明默认构造函数
	Person();
	int m_Age;
	int* m_Height;
};
//定义默认构造函数
Person::Person() 
{
	cout << "默认构造函数的调用!" << endl;
	this->m_Age = 0;
	this->m_Height = new int(0);
}
int main()
{
	Person p;
	cout << "此人的年龄是: " << p.m_Age << endl;
	cout << "此人的身高是: " << *(p.m_Height) << endl;
	return 0;

}

2、有参构造

#include
using namespace std;

class Person
{
public:
	//声明默认构造函数
	Person();
	//声明有参构造
	Person(int age, int height);
	int m_Age;
	int* m_Height;
};
//定义默认构造函数
Person::Person()
{
    cout << "默认构造函数的调用!" << endl;
	this->m_Age = 0;
	this->m_Height = new int(0);
}
//定义有参构造函数,把age赋值给m_Age,身高用m_Height指向
Person::Person(int age,int height)
{
    cout << "有参构造函数的调用!" << endl;
	this->m_Age = age;
	this->m_Height = new int(height);
}

int main()
{
	Person p(18,175);
	cout << "此人的年龄是: " << p.m_Age << endl;
	cout << "此人的身高是: " << *(p.m_Height) << endl;
	return 0;
}

3.拷贝构造

上面都是开始是给出属性的值进行初始化,而拷贝构造函数在开始是传递一个对象,把对象的个属性拷贝到此对象中,进行对象的初始化(可以把传去的参数,看成一只羊,拷贝构造后克隆了一只新的羊,两只羊的属性一样)根据这样可以实现对象的创建。


#include
using namespace std;
class Person
{
public:
	//声明默认构造函数
	Person();
	//声明有参构造
	Person(int age, int height);
	//声明拷贝构造
	Person(const Person& p);
	int m_Age;
	int* m_Height;
};
//定义默认构造函数
Person::Person()
{
	cout << "默认构造函数的调用!" << endl;
	this->m_Age = 0;
	this->m_Height = new int(0);
}
//定义有参构造,把age赋值给m_Age,身高用m_Height指向
Person::Person(int age, int height)
{
	cout << "有参构造函数的调用!" << endl;
	this->m_Age = age;
	this->m_Height = new int(height);
}
//定义拷贝构造函数调用
Person::Person(const Person& p)
{
	cout << "拷贝构造函数的调用!" << endl;
	this->m_Age = p.m_Age;
	this->m_Height = new int(*p.m_Height);
}

int main()
{
	Person p(18, 175);
	cout << "p的年龄是: " << p.m_Age << endl;
	cout << "p的身高是: " << *(p.m_Height) << endl;
	Person p2(p);
	cout << "p2的年龄是: " << p2.m_Age << endl;
	cout << "p2的身高是: " << *(p2.m_Height) << endl;
	return 0;

}

三种调用方式(初始化)

  • 括号法
  • 显示法
  • 隐式转换法
#include
using namespace std;

class Person
{
public:
	//声明无参构造函数
	Person();
	//声明有参构造
	Person(int age, int height);
	//声明拷贝构造
	Person(const Person& p);
	int m_Age;
	int* m_Height;
};

//定义无参构造函数
Person::Person()
{
	cout << "默认构造函数的调用!" << endl;
	this->m_Age = 0;
	this->m_Height = new int(0);
}

//定义有参构造,把age赋值给m_Age,身高用m_Height指向
Person::Person(int age, int height)
{
	cout << "有参构造函数的调用!" << endl;
	this->m_Age = age;
	this->m_Height = new int(height);
}

//定义拷贝构造函数调用
Person::Person(const Person& p)
{
	cout << "拷贝构造函数的调用!" << endl;
	this->m_Age = p.m_Age;
	this->m_Height = new int(*p.m_Height);
}



int main()
{
    //注意1:调用无参构造函数不能加括号,如果加了编译器认为这是一个函数声明 //Person p2();
    Person p0;
    //1 括号法,常用
	Person p(18, 175);
	cout << "p的年龄是: " << p.m_Age << endl;
	cout << "p的身高是: " << *(p.m_Height) << endl;
	Person p2(p);
	cout << "p2的年龄是: " << p2.m_Age << endl;
	cout << "p2的身高是: " << *(p2.m_Height) << endl;
	//2 显式法
	 Person p3 = Person(10,234);
	 Person p4 = Person(p2);
	 cout << "p3的年龄是: " << p3.m_Age << endl;
	 cout << "p4的身高是: " << *(p4.m_Height) << endl;
	 //2.3 隐式转换法
     //Person p5 = 10,453; // Person p4 = Person(10);
	   Person p6= p4; // Person p5 = Person(p4);
       cout << "p6的年龄是: " << p6.m_Age << endl;
       cout << "p6的身高是: " << *(p6.m_Height) << endl;
     //注意2:不能利用 拷贝构造函数 初始化匿名对象 编译器认为是对象声明
     //Person p5(p4);
	 return 0;
}
三、拷贝构造函数的调用

拷贝构造函数的调用有以下三种情形:

  • 用类的一个对象去初始化另一个对象时;
  • 当函数的形参是类的对象时(值传递),如果是引用传递则不会调用;
  • 当函数的返回值是类的对象或引用时。
#include 
using namespace std;

class Point{
public:
    Point(int xx=0,int yy=0){x=xx;y=yy;}
    Point(const  Point& p);
    int getX(){return x;}
    int getY(){return y;}
private:
    int x,y;
};

Point::Point(const Point& p){
    x=p.x;
    y=p.y;
    cout<<"Calling the copy constructor\n"<