构造函数的概念
在创建类的对象时会调用类的构造函数。
类的构造函数与所属的类的名称相同,类可以有多个构造函数。
构造函数没有任何返回类型。
类的构造函数的首要目的是给类的数据成员赋予初始值。
#include <iostream>
#include <iomanip>
#include <string>
class CPerson
{
public:
std::string name{ "Jeff" };
int age{ 20 };
void show();
CPerson(int age, std::string name)
{
this->age = age;
this->name = name;
}
//默认构造函数
CPerson() = default;
};
int main()
{
CPerson person1(30,"Pin");
person1.show();
}
inline void CPerson::show()
{
std::cout << name << "'age is " << age << std::endl;
}
默认构造函数
默认构造函数既可以是定义中没有指定任何形参的构造函数,也可以是实参全部由默认值得构造函数。
=后面的default关键字指定,无参数构造函数应包含在类中。
//等效class_name()=default
class_name()
{
}
默认的形参值
对类的成员函数,包括构造函数,可以在函数原型中给函数的形参指定默认值。
#include "pch.h"
#include <iostream>
#include <iomanip>
#include <string>
class CPerson
{
public:
std::string name;
int age;
void show();
CPerson(int age=8, std::string name="coco")
{
this->age = age;
this->name = name;
}
};
int main()
{
CPerson person1;
person1.show();
}
inline void CPerson::show()
{
std::cout << name << "'age is " << age << std::endl;
}
在构造函数中使用初始化列表
初始化列表只包含传递给构造函数的实参。
构造函数的初始化列表与形参列表之间以冒号分开,各个成员的初始化器之间以逗号分开。
对于const或引用类型的类成员,其唯一的初始化方式是在构造函数中使用成员初始化列表,构造函数体中的赋值语句是无效的。
成员初始化的顺序不同于它们在构造函数初始化类别中的顺序,而与它们在类定义中的顺序形同。
#include <iostream>
#include <iomanip>
#include <string>
class CPerson
{
public:
std::string name;
int age;
void show();
CPerson(int age = 4, std::string name = "tiger") :age{age},name{name}
{
}
};
int main()
{
CPerson person1;
person1.show();
}
inline void CPerson::show()
{
std::cout << name << "'age is " << age << std::endl;
}
声明显式的构造函数
explicit关键字声明显式转换
委托构造函数
类定义多个构造函数时,一个构造函数可以调用另一个构造函数,以帮助创建对象,但只能在构造函数头的构造函数初始化列表中调用。
一个构造函数调用另一个构造函数的唯一方式是通过成员初始化列表。
范例
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
class Cobject
{
public:
Cobject() { cout << R"(Cobject的无参数构造函数被调用)" << endl; }
~Cobject() { cout << R"(Cobject的析构函数被调用)" << endl; }
virtual void MsgShow()
{
cout << "MsgShow in class Cobject is called" << endl;
}
};
class Cperson : public Cobject
{
public:
string name;
int age;
public:
Cperson() : name{ "" }, age{ 0 }{ cout << R"(Cperson的无参数构造函数被调用)" << endl; }
explicit Cperson(string myName, int myAge) : name{ myName }, age{myAge} { cout << R"(Cperson带参构造函数被调用)" << endl; }
~Cperson() { cout << R"(Cperson的析构函数被调用)" << endl; }
inline virtual void MsgShow()
{
cout << "MsgShow in class Cperson is called" << endl;
}
};
class Cstudent : public Cperson
{
private:
int studentID;
int classroom;
Cstudent() : Cperson(), studentID{ 0 }, classroom{ 0 } { cout << R"(Cstudent的默认构造函数被调用)" << endl; }
explicit Cstudent(string myName, int myAge, int myStudentID, int myClassroom ) : Cperson(myName, myAge),studentID{ myStudentID }, classroom{ myClassroom } { cout << R"(Cstudent的带参构造函数被调用)" << endl; }
~Cstudent() { cout << R"(Cstudent的析构函数被调用)" << endl; }
inline virtual void MsgShow()
{
cout << "MsgShow in class Cstudent is called" << endl;
}
};
class Ctecher : public Cperson
{
private:
string subject; //学科
int seniority;//工龄
public:
Ctecher() : Cperson(), subject{ "" }, seniority{0} { cout << R"(Ctecher的无参数构造函数被调用)" << endl; }
explicit Ctecher(string myName, int myAge, string mySubject, int mySeniority) : Cperson(myName, myAge), subject{ mySubject }, seniority{ mySeniority } { cout << R"(Ctecher的带参构造函数被调用)" << endl; }
~Ctecher() { cout << R"(Ctecher的析构函数被调用)" << endl; }
virtual void MsgShow();
};
int main()
{
cout << "Ctecher techer" << endl;
Ctecher techer;
cout << endl;
cout << "techer.MsgShow()" << endl;
techer.MsgShow();
cout << endl;
cout << "static_cast<Cperson>(techer).MsgShow()" << endl;
static_cast<Cperson>(techer).MsgShow();
cout << endl;
cout << "static_cast<Cobject>(techer).MsgShow()" << endl;
static_cast<Cobject>(techer).MsgShow();
cout << endl;
cout << "end" << endl;
}
//放在类外实现函数
void Ctecher::MsgShow()
{
cout << "MsgShow in class Ctecher is called" << endl;
}