类是一个模型,当我们为这个类创建实例的时候也就是对象的本身。
对象的内部可以有变量和函数,而结构通常只是由各种变量构成。对象与结构有很多相似之处,但是对象还可以有他们自己的函数。
类由变量和函数组成,对象将使用哪些变量来存储信息,调用哪些函数来完成操作,所以习惯上类里边变量成为属性,函数成为方法。
OOP(面向对象编程过程):
第一步:创建一个类(每个类跟变量一样都有一个名字,类名的第一个字母通常采用大写)
“::”作用域解析符作用是告诉编译器这个方法存在于何处,或者说是属于哪一个类。
std::cout所引用的是std定义的cout,而std::string数据类型其实也是一个对象。
class Car
{
public ://(public这个关键词实际上就是作用域的问题)
std::string color;
std string eigine;
float gas_tank;
unsigned int Wheel;
//方法的声明(写在类里面)
void fill_Tank(float liter);//只有一个参数,不需要返回值
void running(void);//不需要返回类型,不需要参数
//方法的定义通常安排在类声明的后面
};//可以直接在这个后边定义类的对象Car(但是一般呢不这样用,将声明和定义是分开的)。
//方法的定义通常安排在类声明的后面
void Car::fill_Tank(float liter)//::是作用域解析符(是在说fill_Tank这个函数是在Car这个类里边的)
{
gas_tank += liter;
}
int main()
{
Car mycar;//使用Car这个类定义一个变量mycar(在创建类的对象时,也可以像结构那样直接在大括号后边进行定义),一个具体实例。拥有方法和属性
mycar.gas_tank=85;
return 0;
}
PS:我们可以把类的声明和类的函数的定义分别存入两个不同的文件,声明存入.h头文件,定义存入相应的.cpp文件。
C++允许在类里面声明常量,但是不允许对它进行赋值。
把一个对象赋值给另一个同类的对象将会自动使同名的的属性有同样的值。
class Car
{
public:
const float TANKSIZE=85;//这样会出错。
}
//绕开这一限制的方法就是创建一个静态常量
class Car
{
public:
static const float TANKSIZE=85;//这样会出错。
};
Car car1,car2;
car2=car1;//把一个对象赋值给另一个同类的对象将会自动使同名的的属性有同样的值。
总结:开发程序最基本的步骤:
(1)定义一个有属性(变量)和方法(函数)的类。(模板)
(2)为该类创建一个变量。(实现)
-------------------------扩展
构造器:
1、构造器和通常方法的主要区别:
- 构造器的名字必须和他所在的类的名字一样。
- 系统在创建某个类的实例时,会第一时间自动调用这个类的构造器。
- 构造器永远不会返回任何值。
2、创建构造器需要先把他的声明添加到类里:
class Car
{
Car(void);
}
3、注意大小写和类名保持一致,在结束声明之后开始定义构造器本身:
Car::Car(void)//因为构造器默认不会有任何返回值,所以我们不用写为 void Car::Car(void)
{
color="white";
engine="V8";
wheel=4;
gas_tank=FULL_GAS;
}
4、构造器的作用就是对它进行初始化
class Car
{
std::string color;
std::string enigen;
unsigned int gas_tank;
unsigned int wheel;
Car(void);
void set color(std string col);
void set enigen(std string eng);
void set wheel(unsigned int whe);
void fill tank(int liter);
int running(void);
void warning(void);
}
Car::Car(void)
{
color="white";
}
5、构造对象数组
数组可以是任何一种数据类型,当然也包含对象。
Car mycar[10];//Car是类名,后边是一个数组
//调用的语法:
Mycar[x].running;//x表示给定数组元素的下标
6、注意每个类至少有一个构造器,如果你没有在类里定义一个构造器,编译器就会使用以下语法替你定义一个:
ClassName::ClassName(){}
析构器:
在创建对象时系统会自动调用一种特殊的方法,即构造器。
在销毁一个对象时系统也应该会调用另一个特殊方法达到对应效果,即析构器。(一般来说构造器用来完成事先的初始化和准备工作(申请内存),析构器用来完成时候所必须的清理工作(清理内存))
1、析构器有着和构造器/类一样的名字,只不过前边多了一个波浪符“~”前缀。析构器也永远不返回任何值。析构器是不带参数的,所以析构器的声明格式永远是~ClassName();
class Car(void)
{
Car();
~Car();
}
//析构器是不带参数的,所以析构器的声明格式永远是
~ClassName();
在我们刚刚上边的例子中,析构器是可有可无的,(因为我们刚刚的例子并没有涉及到内存的申请啊以及动态内存的申请,只不过是申请了几个变量,而变量在这个函数,对象结束的时候由栈的机制它会自动返回,不用我们来处理;如果我们用这个new申请的一些动态内存的话,就必须在析构器里边对它进行释放;或者说我们打开一个文件也是对他进行申请内存,比如openfile后面就必须有closefile与之对应,那我们就必须分别写在构造器和析构器里面),但是在比较复杂的类里,析构器往往非常重要。(可能会引起内存泄漏。也就是你申请了一块内存没有去用它,或者说你调用完这块内存之后,你这个类消除了,但是你这块内存没有释放,那么他就会在内存空间中存下,保留这个地址,当你不小心访问到这个地址的时候,就会出现该内存不能读,就会弹出错误对话框);例如某个类的构造器申请了一块内存,我们就必须在析构器里释放这块内存。
#include<iostream>
#include<string>
#include<fetream>
class StoreQuote
{
publis:
std::string quote,sperker;
std::ofstream fileOutput;
StoreQuote();//构造器
~StoreQuote();//析构器
void inputQuote();
void inputSpeaker();
bool write();
};//类的声明
StoreQuote::StoreQuote()
{
fileoutput.open("test.txt",std::ios::app);//类.方法()打开一个文件,app表示追加的形式打开
}
StoreQuote::~StoreQuote()
{
fileOutput.close();//析构器里边对它进行关闭
}
void StoreQuote::inputQuote()
{
std::getline(std::cin,quote);//写入这句话,把他写进quote这个字符串里边
}
void StoreQuote::inputSpeaker()
{
std::getline(std::cin,speaker);//写入作者,把他写入speaker这个字符串里边
}
bool StoreQuote::write()//把刚才的两个给写入文件里边
{
if(fileOutput.is_open())
{
fileOutput<<qupte<<"i"<<speaker<<"\n";
return true;
}
else
{
return false;
}
}
int main()
{
StoreQuote quote;
std::cout<<"请输入一句话:\n";
quote.inputQuote();//调用这个函数
std::cout<<"请输入作者:\n";
quote.inputSpeaker();
if(quote.write())//判断是否成功的写入文件
{
std::cout<<"成功写入文件";
}
else
{
std::cout<<"写入文件失败":
return 1;
}
return 0;//main函数的默认返回值
}