C++构造函数的意义
为什么c++会出现构造函数这个概念?
是因为c++希望类的成员方法和类的成员属性,更加安全,就会降低程序员写代码的成本
【1】构造函数
1.构造函数是成员函数 2.构造函数的函数名与类名相同 3.构造函数没有返回值 4.构造函数不能手动调用,在类创建对象的时候自动调用 5.如果没有自定义构造函数,当创建对象的时候,系统会自动创建[默认构造函数] 6.构造函数在public:实现
练习:
通过构造函数实现
设计一个人的类,私有属性—变量(姓名,性别,年龄)
私有方法—函数(设置姓名,性别,年龄接口,用于输出人的信息)
公有方法:show()输出成员信息
#include <iostream>
using namespace std;
class Student
{
public:
// 构造函数
Student(string name,int age,char sex)
{
// this->name = name;
// this->age = age;
// this->sex = sex;
setName(name);
setAge(age);
setSex(sex);
}
public:
void show(void);
private:
void setName(string name);
void setAge(int age);
void setSex(char sex);
private:
int age;
char sex;
string name;
};
void Student::setName(string name)
{
this->name = name;
}
void Student::setAge(int age)
{
this->age = age;
}
void Student::setSex(char sex)
{
this->sex = sex;
}
void Student::show()
{
cout << name <<" "<< age << " " << sex << endl;
}
int main()
{
Student st("Jack",18,'M');
st.show();
return 0;
}
【2】this指针
当创建一个对象的时候,系统会给这个对象分配一个this指针
this指针指向分配的空间,用于访问对象里面的成员
说白了,this指针就是指向对象本身,一个对象对应一个this指针
demo:
public:
// 构造函数
Student(string name,int age,char sex)
{
// this->name = name;
// this->age = age;
// this->sex = sex;
setName(name);
setAge(age);
setSex(sex);
}
【3】堆空间申请对象
例子:
class Student
{
public:
// 构造函数
Student(int age,char sex)
{
cout << "student"<< endl;
this->age = age;
this->sex = sex;
cout << this->age << " " << this->sex << endl;
}
private:
int age;
char sex;
};
int main()
{
//创建对空间
Student *st = new Student(18,'M');
delete st;
st = NULL;
// 栈空间如果不传递参数给构造函数的情况下,不要加()
//Student st1(); // 错误的
//Student st1; // 正确的
}
总结 :
1.以栈的方式申请对象,不传参的情况下
Student st1(); // 错误的,不能调用构造函数
Student st1;// 正确的,可以调用构造函数,建议使用
2.以堆空间方式申请对象
Student *st = new Student(); // 正确的,可以调用构造函数,不建议使用
Student *st = new Student; // 正确的,可以调用构造函数,建议使用
【4】析构函数
1.析构函数定义 ~类名() 例子: ~Student(){}
2.析构函数没有返回值,没有参数
3.对象结束的时候自动调用析构函数
4.析构函数的作用是用于释放堆空间
例子:
#include <iostream>
#include <cstring>
using namespace std;
class Student
{
public:
// 构造函数声明
Student(const char *name);
// 析构函数
~Student();
char *name;
};
//-------------------------------
// 构造函数实现
Student::Student(const char *name)
{
cout << "Student " << endl;
//this->name = name; // 使用方式不正确,会修改this->name的地址
this->name = new char[100];
strcpy(this->name,name);
cout << this->name << endl;
}
//-------------------------------
// 析构函数实现
Student::~Student()
{
cout << "~student" << endl;
// 释放堆空间
delete []this->name;
this->name = NULL;
}
int main()
{
Student st("jack");
// Student *st1 = new Student;
// delete st1;
}
【5】构造函数重载
Student(string name,int age,char sex)
{
cout << "Student()" << endl;
this->name = name;
this->age = age;
this->sex = sex;
}
// 构造函数重载
Student()
{
cout << "student" << endl;
}
格式
构造函数名(外部参数1,外部参数2,外部参数3):类内参数1(外部参数1),类内参数2(外部参数2),类内参数3(外部参数3)
其实就是将外部参数赋值给类内变量
例子:
// 参数列表初始化,功能与自行调用函数进行传参一样
// 等价与 this->age = Age;
Student(int Age):age(Age)
{
//this->age = age;相当于 int a=10;int &b;b=a;// 错误
cout << this->age << endl;
}
参数列表初始化特点
1.如果类内私有属性是引用,一定义是要使用参数列表初始化
2.如果类内私有属性是const修饰的成员属性(变量),一定义是要使用参数列表初始化
例子:
class Student
{
public:
// 参数列表初始化,功能与自行调用函数进行传参一样
Student(int Age,string Name,char Sex):age(Age),name(Name),sex(Sex)
{
//this->age = age;相当于 int a=10;int &b;b=a;// 错误
cout << this->age <<" "<< this->name << " " << this->sex << endl;
}
~Student(){cout << "~student"<<endl;}
private:
int &age; //this->age = age;相当于 int a=10;int &b;b=a;// 错误 ,因为定义的是引用变量必须初始化
string name;
char sex;
};
//--------------------
int main()
{
Student st(100,"Jack",'M');
}
2.构造函数参数列表初始化在类内声明,类外实现方式如下:
1.类内声明
// 参数列表初始化,功能与自行调用函数进行传参一样
Student(int Age,string Name,char Sex);
== 2.类外实现==
// 构造用函数参数列表初始化实现
Student::Student(int Age,string Name,char Sex):age(Age),name(Name),sex(Sex)
{
//this->age = age;相当于 int a=10;int &b;b=a;// 错误
cout << this->age <<" "<< this->name << " " << this->sex << endl;
}