在创建对象时,系统都会自动调用一个特殊的方法,即
构造器。
构造器和通常方法的主要区别:
1、构造器的名字必须和它所在的类的名字一样;
2、系统在创建某个类的实例时会第一时间自动调用这个类的构造器;
3、构造器永远付汇返回任何值。
4、创建构造器,需要先把它的声明添加到类里。如下:
class Car
{
Car(void);
};
5、注意大小写与类名保持一致。在结束声明之后开始定义构造器本身。如下:
#include <iostream>
class Car
{
public:
std::string color;
std::string engine;
unsigned int gas_bank;
unsigned int wheel;
Car(void); // 构造函数
void fillTank(unsigned int liter);
int running(void);
};
// 构造函数
Car::Car(void)
{
color = "WHITE";
engine = "V8";
wheel = 4;
gas_bank = 85;
}
void Car::fillTank(unsigned int liter)
{
gas_bank += liter;
}
int main()
{
Car car1;
std::cout << "color: " << car1.color << std::endl;
return 0;
}
注意点:
1、每个类至少有一个构造器,如果没有在类里定义一个构造器,编译器就会使用如下语法默认定义一个: ClassName::ClassName(){}
2、这是一个没有代码内容的空构造器,除此之外,编译器还会默认创建一个副本构造器(CopyConstructor,后续讲解)。
3、这一切都是发生在幕后。
相应地,在销毁一个对象时,系统也会调用另一个特殊的方法,即
析构器。
一般来说,构造器用来完成事先的初始化和准备工作(申请分配内存),析构器用来完成事后所必须的清理工作(清理内存)。
构造器和析构器两者有许多共同之处:
1、析构器有着和构造器/类一样的名字,只不过前边多了一个波浪符“~”前缀;
2、析构器也永远不返回任何值;
3、析构器不带参数,所以析构器的声明永远是如下格式:~ClassName();
4、在比较复杂的类里,析构器往往至关重要(可能引起内存泄露)。在构造器中申请的内存,一定要在析构器中进行释放。
class Car
{
public:
Car(void); // 构造函数
~Car(); // 析构函数
};
程序练习:构造函数打开文件,析构函数关闭文件
#include <iostream>
#include <fstream>
#include <string>
// 构造函数打开文件,析构函数关闭文件
class StoreQuote
{
public:
std::string quote, speaker;
std::ofstream fileOutput;
StoreQuote();
~StoreQuote();
void inputQuote();
void inputSpeaker();
bool write();
};
// 构造函数
StoreQuote::StoreQuote()
{
fileOutput.open("test.txt", std::ios::app);
}
// 析构函数
StoreQuote::~StoreQuote()
{
fileOutput.close();
}
void StoreQuote::inputQuote()
{
std::getline(std::cin, quote);
}
void StoreQuote::inputSpeaker()
{
std::getline(std::cin, speaker);
}
bool StoreQuote::write()
{
if (fileOutput.is_open())
{
fileOutput << quote << "|" << speaker << "\n";
return true;
}
else
{
return false;
}
}
int main()
{
StoreQuote quote;
std::cout << "Input quote: ";
quote.inputQuote();
std::cout << "Input author:";
quote.inputSpeaker();
if (quote.write())
{
std::cout << "Write file successfully!";
}
else
{
std::cout << "Write file fail!";
}
return 0;
}