对象是类的实例,声明一种数据类型只是告诉编译系统该数据类型的构造,并没有预定内存;类只是一个样板(图纸),以此样板可以在内存中开辟出同样结构的实例——对象。
创建类的对象可以有两种常用方法:直接定义类的实例——对象和用指针。
对象的创建与使用
1 直接定义类的实例——对象
如:
这个定义创建了CGoods类的一个对象car,同时为它分配了属于它自己的存储块,用来存放数据和对这些数据实施操作的成员函数(代码);对象只在定义它的域中有效。
对象的使用:
总结:对象的使用规则很简单,只要在对象名后加点号(点操作符——成员访问运算符之一),再加成员数据或成员函数名就可以了,但是这些成员必须是公有的成员,只有公有的成员才能在对象的外面对它进行访问。
2 C++对象模型讨论
方案一:各对象完全独立地安排内存的方案
上图是系统为每一个对象分配了全套的内存,包括安放成员数据的数据区和安放成员函数的代码区,但是区别同一个类所实例化的对象,是由属性(数据成员)的值决定,不同对象的数据成员的内容是不一样的;而行为(操作)是用函数来描述的,这些操作的代码对所有的对象都是一样的。
方案二:各对象的代码区共有的方案
方案二中的图仅为每个对象分配一个数据区,代码区(放成员函数的区域)为各对象类共用。
总结:对象那个模型中的存储区分配,如果代码区共享的话,会节省很多内存空间。
如:
当tea.RegisterGoods(“black_tea”, 12, 560);处理时,RegisterGoods其实是通过一个this指针来处理的。
3 this指针的作用
编译器针对程序员自己设计的类型分三次编译:
第一次:识别和记录类体中属性的名称,类型和访问限定,与属性在类体中的位置无关;如 class CGoods中的Name,Amount,Price,Total;
第二次:识别和记录类体中函数原型(返回类型+函数名+参数列表),形参的默认值,访问限定;
第三次:改写在类中定义函数的参数列表和函数体,改写对象调用成员函数的形式。
如:原代码为:
#include<iostream>
using namespace std;
class CGoods
{
private:
char Name[21]; //商品名称
int Amount; //数量
float Price; //单价
float Total; //总价
public:
void RegisterGoods(const char [], int, float);//输入数据
void CountTotal(void); //计算商品总价值
};
void CGoods::RegisterGoods(const char name[], int amount, float price)
{
strcpy(Name, name);//字符串拷贝函数
Amount = amount;
Price = price;
}
void CGoods::CountTotal( )
{
Total = Price * Amount;
}
int main()
{
CGoods tea;
CGoods book;
tea.RegisterGoods("black_tea", 12, 560);
tea.CountTotal();
book.RegisterGoods("Thinking in C++", 20, 128);
book.CountTotal();
return 0;
}
改写后:
#include<iostream>
using namespace std;
class CGoods
{
private:
char Name[21]; //商品名称
int Amount; //数量
float Price; //单价
float Total; //总价
public:
void RegisterGoods(const char [], int, float);
//void RegisterGoods(CGoods *const this, char [], int ,float);
void CountTotal(void);
//void CountTotal(CGoods *const this);
};
//void CGoods::RegisterGoods(CGoods *const this,char name[], int amount, float price);
void CGoods::RegisterGoods(const char name[], int amount, float price)
{
strcpy(this->Name, name);//字符串拷贝函数
this->Amount = amount;
this->Price = price;
}
//void CGoods::CountTotal(CGoods *const this);
void CGoods::CountTotal( )
{
this->Total = this->Price * this->Amount;
}
int main()
{
CGoods tea;
CGoods book;
tea.RegisterGoods("black_tea", 12, 560);
//RegisterGoods(&tea,"black_tea", 12, 560);
tea.CountTotal();
//CountTotal(&tea);
book.RegisterGoods("Thinking in C++", 20, 128);
//RegisterGoods(&tea,"Thinking in C++", 20, 128);
book.CountTotal();
//CountTotal(&book);
return 0;
}
注意:其中//之后是改正的,可以看出,this指针在代码中其实是隐形存在的,而且this指针不占用内存。