在第六章学习了类与对象,这是c++特有的内容,有些像结构体,但又有很多不一样的功能与语法,以下来总结这一章需要注意的地方:
1,不同于结构体定义的变量是公有,class默认定义私有,也就是要遵循封装原则,学习类就是为了保护数据不被修改,所以在写关于类代码时,保护数据的思想一定要贯穿始终,另外,类名,结构体名第一个字母一般大写,其中的数据称数据成员,类所定义的变量称为对象或实例。可以说类是宏观的概念是总体,是一种数据类型,是集合,对象是具体的事物。面向对象编程的主要工作就是创建一组对象并给他们发送消息。要注意 每个对象都有自己的数据成员,类的成员函数并不在各个对象中存储,而是整个类存储一份,所有对象共享这些成员函数的定义
class SalesData{
public: //类的接口
double totalRevenue();
void read();
void print();
private: //私有数据
std::string productNo;
double price = 0.0;
unsigned unitSold = 0;
};
2,成员函数
数据成员类内初始值只能放在等号“=”右边,或者放在花括号“{}”里,不能使用圆括号()
struct SalesData{
//成员函数声明,成员函数对数据成员操作完成功能
double totalRevenue();
void read();
void print();
};
//成员函数的类外定义
double SalesData::totalRevenue()// 双冒号是界定符表示此函数在前边的结构体内起作用
{ return price * unitSold;}
void SalesData::read()
{ cin >> productNo >> price>> unitSold;}
void SalesData::print()
{ cout << productNo<< ":"<< price<<" "<< unitSold
<< " " << totalRevenue() << endl;}
3,this指针的注意点
每个成员函数都有一个隐含的参数,指向接收消息的对象,称为this指针,不能取this指针的地址,用处:
*区分与数据成员同名的变量
*返回当前对象
*取得当前对象地址
class X {
int m;
public:
void setVal(int m) { this -> m = m; }
X add(const X& a) {
m += a.m;
return *this; //返回当前对象
}
void copy(const X& a) { //复制对象
if (this == &a) //同一对象,无需复制
return;
m = a.m; //拷贝复制
}
};
4,访问器与修改器
应该是类中的基本操作符了set修改器将初值修改(当然也可以赋值)相当于cin,get访问器将一个私有成员拿出,相当于cout的意思,以下列举用法:
struct Rectangle {//列举结构体下俩个私有成员的访问器与修改器
double area();
double perimeter();
//width 的访问器和修改器
double getWidth(){return width;}
void setWidth(double newWid)
{ if(newWid > 0) width = newWid; }
//height 的访问器和修改器
double getHeight(){return height;}
void setHeight(double newHei)
{ if(newHei > 0) height = newHei; }
private:
double width;
double height;
5,友元(慎用)
C++引入了friend关键字,如果想让非成员函数访问一个类中的私有数据,应该在类中将这个函数声明为friend,友元必须在被访问的类中声明与友元相关联的俩函数无对称关系,是单向,不可传递
public:// 在公有声明中声明函数,类外写函数便可使用私有成员。
fridend void g(x*,int)
friend class z;
6,构造函数与解析函数(初始化与销毁)
构造函数一定要写俩个,一个带参数一个不带。解决定义时不带参的问题
构造函数在创建对象时被自动调用,负责初始化对象
构造函数的名字和类名字相同,它没有返回类型
是没有返回类型,不是返回void 类型
构造函数的参数通常为数据成员提供初始值
*对于不能采用直接赋值的变量用初始化列表,列表的赋值不按列表顺序按定义顺序。
class X {
int m, &r;
public:
X(){ m = 0;}无返回值,名字是类名
x (int v) {m=v;}
};
int main()
{
x shiya(5)//m=5
}
X(int v = 0): r(m) { m = v;}
X(int v = 0): m(v), r(m) {}
链表形
class X{
int a, b; //成员声明顺序
public:
X(int val):a(val), b(a){} //先初始化a,再用a初始化b
};
//下面的形式更好一些: 用val 初始化,没有成员的依赖
X(int val) : a(val), b(val){}
//下面的形式可能会产生未定义的行为:试图用未定义的值b初始化a
X(int val) : b(val), a(b){} //编译器会警告
析构函数返还空间
语法:~类名();
7,const成员(局部常成员,整体常对象)
const数据成员:该成员的值在对象的生存期中不改变(常对象)
const成员函数:不能通过该函数改变值(常函数)
*声明const成员函数的语法形式
返回类型 成员函数名(参数表) const;
*定义const成员函数的语法形式
返回类型 成员函数名(参数表) const { 函数体 }
* 注意const成员函数声明和定义的语法
对于在类外定义的const成员函数,必须在它的定义和声明中同时指定关键字const
语法规则(很难记忆):
只有声明为const 的成员函数才可以被const 对象调用
const 对象不能调用非const 成员函数
非const 对象可以调用const 成员函数
const 成员函数中不能修改类的数据成员
const 成员函数中不能调用其他非const 成员函数
8,static成员(类内全局成员)
static数据成员对整个类类型只有一个,由这个类型的所有对象共享访问
static成员仍然遵循访问控制规则 ,可以实现信息隐藏,static成员可以是private成员,而全局变量不能
class Object {
static int count; //静态数据成员
…
friend void func(Object& obj);
};
void func(Object& obj){
cout << obj.count; //成员访问语法
cout << Object::count; //类名限定访问
}