类——一个用户定义的类型
1、类的定义
一、struct实现日期的概念
struct Data{
int d,m,y;
};
void init_data(Data& d,int,int,int);
void add_year(Data& d,int n);
void add_month(Data& d,int m);
void add_data(Data& d,int n);
Data的类型和Data的函数没有显式的关系
建立关系
struct Data{
int d,m,y;
void init_data(Data& d,int,int,int);
void add_year(Data& d,int n);
void add_month(Data& d,int m);
void add_data(Data& d,int n);
};
问题的到来:
外部的函数都可以访问结构内部的所有成员;
解决办法:
通过类class实现
二、对访问的控制
类的定义(声明)
class Data{
private: //定义为私有的 只有内部的成员函数可以访问(通过类成员名的控制)
int d,m,y;
public: //定义为公有的
void init_data(Data& d,int,int,int);
void add_year(Data& d,int n);
void add_month(Data& d,int m);
void add_data(Data& d,int n);
}
三、构造函数
class Data{
Data();
........};
void Data(){};
定义对象:
Data my_birthday(6,18,1983);
要点:
多种构造方式
默认参数
重载规则
检查初试合法化
类内的静态的成员
为了不要受某个全局变量的限制
在类内定义个静态的成员
与其他对象的区别是无须在每个对象内存一个副本
可以通过定义一个静态的成员函数来修改静态变量
四、类对象的复制
定义一个复制构造函数X::X(const X&)
五、常量成员函数
int year() const;
表明函数不改变对象的值
六、自引用及this指针
class Data {
Data& add_year(int);
}
add_year(int n)
{
...........
return *this;//返回的是一个此函数引用的对象;
}
七、物理的和逻辑的常量
(1)、一些成员函数在逻辑上是const,但却要改变一些用户无法直接访问的细节,称为逻辑的const。
class Data{
bool cache_valid;
string cache;
void compute_cache_value();
............
}
string Data::string_rep() const
{
if (cache_value==false){
Data* th = const_cast<Data*>(this);//强制去掉const,有时候可以工作,有时候无法工作,
//如:const Data d2;无法对d2操作
th -> compute_cache_value();
th->cache_value = true;
}
}
(2)、利用可变的mutable
把要进行缓存管理的数据声明成mutable
class Data{
mutable bool cache_valid;//把成员定义为可以更新
mutable string cache;
void compute_cache_value();
............
}
string Data::string_rep() const//采用这种机制后的缓存管理函数
{
if (cache_value){
compute_cache_value();
cache_value = true;
}
return cache;
}
八、高效类定义
。。。。
慢慢积累中
九、成员函数
类的操作的实现
十、协助函数
可以用名字空间限制
十一、重载运算符
十二、具体的类的意义
意图是使一个较小的、单独的事情能够很好地并且高效的工作。
区别于抽象层次的类的意义。
2,对象
一、析构函数
~Data();
//用于释放定义一个类的对象的时候所申请的资源;
二、默认构造函数
struct Tables{
int i ;
int v[10]; //不对i和v进行初始化
Data t;
Data tt[10]; //定义一个Tables类型的数据时,自动调用一个Data::Data(15)对tt和t进行初始化
}
成员中的 const 和引用一定要初始化
三、构造和析构
(1)、局部对象:对其声名时建立,程序离开时候销毁
(2)、对象的的复制:
Data t1; //调用一次构造
Data t2=t1; //没调用
Data t3; //调用一次构造
t3=t2;
//三次析构,但只调用了两次构造
解决办法:
将复制的意义定义清楚,复制是整个对象的复制,包括从新分配所需要的空间
策略:防止自复制,删除老元素,初始化,复制新元素。
(3)、自由存储对象
new和delete的使用
(4)、类对象做为成员
对类成员的构造
Data::Data():year(y),month(m),date() //等价Data::Data():year(y),month(m)如果某个成员的构造函数不要参数可以省略
{ //成员构造在类构造之前,按类在成员中的初始化顺序执行
} //析构的时候和构造的顺序相反
成员初始化的必要性:对于const和引用
成员常量:可以在类声明的时候用常量表达式初始化
成员的复制问题:小心对const和引用成员的复制,必须在复制构造函数中明确声明
(5)、数组、局部静态变量、非局部变量与C语言中的一样
(6)、
(7)、对象的放置
(8)、