构造函数
一 构造函数特点
1)自动调用(在创建新对象时,自动调用)
2)构造函数的函数名,和类名相同
3)构造函数没有返回类型
4)可以有多个构造函数(即函数重载形式)
二 构造函数的种类
- 默认构造函数
- 自定义的构造函数
- 拷贝构造函数
- 赋值构造函数
2.1 默认构造函数
没有参数的构造函数,称为默认构造函数
如果数据成员使用类内初始值,同时又在构造函数中进行了初始化,那么以构造函数中的初始化为准。相当于构造函数中的初始化,会覆盖对应的类内初始值
#include <iostream>
#include <string>
using namespace std;
class Human
{
public:
Human();
void description();
private:
string name;
int age = 18; //类内初始值
int salary;
};
// 默认构造函数
Human::Human()
{
cout << "调用 Human() " << endl;
name = "无名";
age = 20;
salary = 10000;
}
void Human::description()
{
cout << "name:" << name << " age:" << age << " salary:" << salary << endl;
}
int main()
{
Human f1;
f1.description();
return 0;
}
2.2 自定义构造函数
#include <iostream>
#include <string>
using namespace std;
class Human
{
public:
Human();
Human(string name, int age, int salary);
void description();
private:
string name;
int age = 18; //类内初始值
int salary;
};
// 默认构造函数
Human::Human()
{
cout << "调用 Human() " << endl;
name = "无名";
age = 20;
salary = 10000;
}
// 自定义构造函数
Human::Human(string name, int age, int salary)
{
cout << "调用 Human(string name, int age, int salary) " << endl;
this->name = name;
this->age = age;
this->salary = salary;
}
void Human::description()
{
cout << "name:" << name << " age:" << age << " salary:" << salary << endl;
}
int main()
{
Human f1;
Human f2("小红", 15, 3000);
f1.description();
f2.description();
return 0;
}
2.3 拷贝构造函数
#include <iostream>
#include <string>
#define ADDR_LEN 64
using namespace std;
class Human
{
public:
Human();
Human(const string name, int age, int salary, const char* addr);
Human(const Human& man);
void description();
void setAddr(const char* addr);
const char* getAddr();
private:
string name;
int age = 18; //类内初始值
int salary;
char* addr;
};
// 默认构造函数
Human::Human()
{
cout << "调用 Human() " << endl;
name = "无名";
age = 20;
salary = 10000;
addr = new char[ADDR_LEN];
strcpy_s(addr, ADDR_LEN, "China");
}
// 自定义构造函数
Human::Human(const string name, int age, int salary, const char *addr)
{
cout << "调用 Human(const string name, int age, int salary, const char *addr) " << endl;
this->name = name;
this->age = age;
this->salary = salary;
this->addr = new char[ADDR_LEN];
strcpy_s(this->addr, ADDR_LEN, addr);
}
// 拷贝构造函数
Human::Human(const Human& man)
{
cout << "调用 Human(const Human& man) " << endl;
name = man.name;
age = man.age;
salary = man.salary;
addr = new char[ADDR_LEN];
strcpy_s(addr, ADDR_LEN, man.addr);
}
void Human::description()
{
cout << "name:" << name << " age:" << age
<< " salary:" << salary << " addr:" << addr << endl;
}
void Human::setAddr(const char* addr)
{
if (!addr)
{
return;
}
strcpy_s(this->addr, ADDR_LEN, addr);
}
const char* Human::getAddr()
{
return addr;
}
int main()
{
Human f1;
Human f2("小红", 15, 3000,"广东");
Human f3(f2);
f1.description();
f2.description();
f3.description();
f2.setAddr("上海");
cout << "-----------------------------------" << endl;
f1.description();
f2.description();
f3.description();
return 0;
}
2.4 赋值构造函数
#include <iostream>
#include <string>
#define ADDR_LEN 64
using namespace std;
class Human
{
public:
Human();
Human(const string name, int age, int salary, const char* addr);
Human(const Human& man);
Human& operator=(const Human&);
void description();
void setAddr(const char* addr);
const char* getAddr();
private:
string name;
int age = 18; //类内初始值
int salary;
char* addr;
};
// 默认构造函数
Human::Human()
{
cout << "调用 Human() " << endl;
name = "无名";
age = 20;
salary = 10000;
addr = new char[ADDR_LEN];
strcpy_s(addr, ADDR_LEN, "China");
}
// 自定义构造函数
Human::Human(const string name, int age, int salary, const char *addr)
{
cout << "调用 Human(const string name, int age, int salary, const char *addr) " << endl;
this->name = name;
this->age = age;
this->salary = salary;
this->addr = new char[ADDR_LEN];
strcpy_s(this->addr, ADDR_LEN, addr);
}
// 拷贝构造函数
Human::Human(const Human& man)
{
cout << "调用 Human(const Human& man) " << endl;
name = man.name;
age = man.age;
salary = man.salary;
addr = new char[ADDR_LEN];
strcpy_s(addr, ADDR_LEN, man.addr);
}
// 赋值构造函数
Human& Human::operator=(const Human& man)
{
cout << "调用 Human& operator=(const Human& man) " << endl;
//检测是否是对自己赋值,例如:f1=f1
if (this == &man)
{
return *this;
}
name = man.name;
age = man.age;
salary = man.salary;
//如果有必要,需要先释放自己的资源(动态内存)
//delete[] addr;
//addr = new char[ADDR_LEN];
strcpy_s(addr, ADDR_LEN, man.addr);
//返回对象本身的引用,以便做链式连续处理,例如 f1=f2=f3
return *this;
}
void Human::description()
{
cout << "name:" << name << " age:" << age
<< " salary:" << salary << " addr:" << addr << endl;
}
void Human::setAddr(const char* addr)
{
if (!addr)
{
return;
}
strcpy_s(this->addr, ADDR_LEN, addr);
}
const char* Human::getAddr()
{
return addr;
}
int main()
{
Human f1;
Human f2("小红", 15, 3000,"广东");
Human f3(f2);
Human f4;
f4 = f2;
f1.description();
f2.description();
f3.description();
f4.description();
f2.setAddr("上海");
cout << "-----------------------------------" << endl;
f1.description();
f2.description();
f3.description();
f4.description();
return 0;
}
三 拷贝构造函数调用时机
- 调用函数时,实参是对象,形参不是引用类型
- 函数返回值类型是类,而且不是引用类型
- 对象数组的初始化列表中,使用对象
#include <iostream>
#include <string>
#define ADDR_LEN 64
using namespace std;
class Human
{
public:
Human();
Human(const string name, int age, int salary, const char* addr);
Human(const Human& man);
Human& operator=(const Human&);
void description();
void setAddr(const char* addr);
const char* getAddr();
private:
string name;
int age = 18; //类内初始值
int salary;
char* addr;
};
// 默认构造函数
Human::Human()
{
cout << "调用 Human() " << endl;
name = "无名";
age = 20;
salary = 10000;
addr = new char[ADDR_LEN];
strcpy_s(addr, ADDR_LEN, "China");
}
// 自定义构造函数
Human::Human(const string name, int age, int salary, const char *addr)
{
cout << "调用 Human(const string name, int age, int salary, const char *addr) " << endl;
this->name = name;
this->age = age;
this->salary = salary;
this->addr = new char[ADDR_LEN];
strcpy_s(this->addr, ADDR_LEN, addr);
}
// 拷贝构造函数
Human::Human(const Human& man)
{
cout << "调用 Human(const Human& man) " << endl;
name = man.name;
age = man.age;
salary = man.salary;
addr = new char[ADDR_LEN];
strcpy_s(addr, ADDR_LEN, man.addr);
}
// 赋值构造函数
Human& Human::operator=(const Human& man)
{
cout << "调用 Human& operator=(const Human& man) " << endl;
//检测是否是对自己赋值,例如:f1=f1
if (this == &man)
{
return *this;
}
name = man.name;
age = man.age;
salary = man.salary;
//如果有必要,需要先释放自己的资源(动态内存)
//delete[] addr;
//addr = new char[ADDR_LEN];
strcpy_s(addr, ADDR_LEN, man.addr);
//返回对象本身的引用,以便做链式连续处理,例如 f1=f2=f3
return *this;
}
void Human::description()
{
cout << "name:" << name << " age:" << age
<< " salary:" << salary << " addr:" << addr << endl;
}
void Human::setAddr(const char* addr)
{
if (!addr)
{
return;
}
strcpy_s(this->addr, ADDR_LEN, addr);
}
const char* Human::getAddr()
{
return addr;
}
// 1.调用函数时,实参是对象,形参不是引用类型
void test1(Human man)
{
man.description();
}
// 2.函数的返回类型是类,而且不是引用类型
Human test2(Human& man)
{
return man;
}
int main()
{
Human f1;
test1(f1);
test2(f1); //会创建一个临时对象,接收test2的返回值
// 3.对象数组的初始化列表中,使用对象
Human f2, f3;
Human man[] = { f1, f2, f3 };
return 0;
}
参考:https://blog.csdn.net/weixin_43831728/article/details/107788822