回顾:之前我们讨论了使用面向对象的编程技术开发程序最基本步骤:
- 定义一个有属性和方法的类(模板)
- 为该类创建一个变量(实现)
这是OOP技术的基础,现在逐步向大家介绍一些更复杂和更有用的概念。
首先是构浩器,它是类里的一种特殊的方法。
构浩器
构造器和通常方法的主要区别:
(1)构浩器的名字必须和它所在的类的名字一样
(2)系统在创建某个类的实例时会第一时间自动调用这个类的构造器
(3)构浩器永远不会返回任何值
创建构浩器,需要先把它的声明添加到类里:
class Car{ Car( void ); }
注意大小写与类名保持一致。在结束声明之后开始定义构造器本身:
Car:Car(void)//不用写void Car::Car(void) { color="WHITE"; engine="V8"; wheel=4; gas_tank=FULL_GAS; }
好,到这里我们就可以自己着手对之前打造的那辆跑车代码进行“改装"了吧?car.cpp

#include <iostream> #include <windows.h> #define FULL_GAS 85 class Car { public: std::string color; std::string engine; unsigned int gas_tank; unsigned int wheel; Car(void); void setColor(std::string col); void setEngine(std::string eng); void setWheel(unsigned int whe); void fillTank(int liter); int running(void); void warning(void); }; Car::Car(void) { color = "While"; engine = "V8"; wheel = 4; gas_tank = FULL_GAS; } void Car::setColor(std::string col) { color = col; } void Car::setEngine(std::string eng) { engine = eng; } void Car::setWheel(unsigned int whe) { wheel = whe; } void Car::fillTank(int liter) { gas_tank += liter; } int Car::running(void) { char i; std::cout << "我正在以120的时速往前移动。。。越过那高山越过那河。。。 "; gas_tank--; std::cout << "当前还剩 " << 100*gas_tank/FULL_GAS << "%" << "油量! "; if( gas_tank < 10 ) { std::cout << "请问是否需要加满油再行驶?(Y/N) "; std::cin >> i; if( 'Y' == i || 'y' == i ) { fillTank(FULL_GAS); } if( 0 == gas_tank ) { std::cout << "抛锚中。。。。。。"; return 1; } } return 0; } void Car::warning(void) { std::cout << "WARNING!!" << "还剩 " << 100*gas_tank/FULL_GAS << "%" << "油量!"; } int main() { Car mycar; while( !mycar.running() ) { ; } return 0; }
构造对象数组:之前我们已经说过,数组可以是任何一种数据类型,当然也包括对象。
如:Car mycar[10];
调用语法依旧是:mycar[x].running; 注:x代表着给定数组元素的下标。
好了,自己造十几辆法拉利“自慰下”。
Pay attention:
每个类至少有一个构造器,如果你没有在类里定义一个构浩器,编译器就会使用如下语法替你定义一个:ClassName::ClassName(){ }
这是一个没有代码内容的空构浩器,除此之外,编译器还会替你创建一个副本构浩器(CopyConstructor)。(这个迟些给大家介绍)
这一切都发生在幕后,而在这里给大家提出主要目的是希望大家能够了解构造器有多么重要。
一种常见的做法是在创建对象的同时做一些事情(构浩器背后搞息),在对象创建出来之后用另一个方法做同样或者不同的事情。
如:
Car mycar; mycar.setColor("Yellow");
析构器
从前边的内容我们了解到,在创建对象时,系统都会自动调用一个特殊的方法,即构造器。
相应地,在销毁一个对象时,系统也应该会调用另一个特殊方法达到对应效果?没错,这就是析构器。
一般来说,构造器用来完成事先的初始化和准备工作(申请分配内存),析构器用来完成事后所必须的清理工作(清理内存)。
构造器和析构器两者相辅相成,有许多共同之处。首先,析构器有着和构浩器/类一样的名字,只不过前边多了一个玻浪符"~”前缀。
class Car { Car(void); ~Car(); }
其次,析构器也永远不返回任何值。
另外,析构器是不带参数的。所以析构器的声明永远是如下格式:~ClassName();
在我们刚刚的例子中析构器可有可无。但是在比较复杂的类里,析构器往往至关重要(可能引起内存泄露)。例如某个类的构造器申请了一块内存,我们就必须在析构器里释放那块内存。
#include <iostream> #include <string> #include <fstream> 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 << " "; return true; } else { return false; } } int main() { StoreQuote quote; std::cout << "请输入一句名言: "; quote.inputQuote(); std::cout << "请输入作者: "; quote.inputSpeaker(); if( quote.write() ) { std::cout << "成功写入文件^_^"; } else { std::cout << "写入文件失败T_T"; return 1; } return 0; }