类的基本知识

类的产生:提供了一种可以重用代码的机制,使得程序员编程的代码可以相互利用

类实际上是一种新产生的数据类型,那就要求给数据类型命名,数据类型名称采用大写字母开头的命名方法。

类包括数据成员和成员函数,成员函数可以在类内部定义,也可以在类外部定义,如果采用在外部定义的话,就要在函数名称前面加上类名Date和名空间引导符"::"。

成员函数的定义:

成员函数一定从属于类,而不能独立存在,则也就是为什么在函数名前面加上类名的道理。

只要是在类定义中包含的成员函数,就有默认声明内联的性质

什么是内联函数呢?参考https://blog.csdn.net/cloud323/article/details/68065098

编译是否真的将成员函数安排为内联,还要看函数是否足够简单,是否包含不适于内联运行的循环结构。

日期类的实现:

#include <iostream>
#include <iomanip>
using namespace std;

class Date
{
	int year,month,day;
public:
 	void set(int y,int m,int d){
 		year = y,month = m,day = d;
	 }	
	 bool isLeapyear();
	 void print();
};
inline bool Date::isLeapyear()
{
	return (year%4==0&&year%100!=0||year%400==0);
}
void Date::print()
{
	cout << setfill('0');
	cout << setw(4)<< year << '-' << setw(2) << month << '-' << setw(2) << day << "\n";
	cout << setfill(' ');
}

还可以使用对象指针

Date* dp = new Date;

dp->set(2000,12,6);

if(dp->isLeapyear())

  (*dp).print();


常成员函数:

成员函数的操作,如果只是对对象进行读操作,则该成员函数设计成常成员函数。

经验之谈:能够成为常成员函数的,应尽量写成常成员函数

void Date::print()const{}  这就是常成员函数的定义。

操作符重载:

#include <iostream>
#include <iomanip>
using namespace std;

class Point
{
	int x,y;
public:
	void set(int a,int b):x(a),y(b){
	}
	void print()const 
	{
		cout << x << ", " << y << endl; 
	}
	friend Point operator+ (const Point& a,const Point& b);
	friend Point add (const Point &a,const Point&b);
};
Point operator+ (const Point& a,const Point& b)
{
	Point s;
	s.set(a.x+b.x,a.y+b.y);
	return s;
}
Point add(const Point& a,const Point& b)
{
	Point s;
	s.set(a.x+b.x,a.y+b.y);
	return s;
}

任何自定义的+操作符的行为都是对c++原有+操作符的重载,其他操作符的定义也是重载行为。

因为operator+ 和 add函数体中都要用到Point对象进行私有数据访问,作为普通函数,这是不允许的,编译器也会报错,但是其在Point类中以friend关键字引导进行的函数声明后,编译就对这两个函数访问Point的私有数据网开一面了。

增量操作符的重载:

#include <iostream>
#include <iomanip>
using namespace std;

class Time
{
	int hour,minute,second;
public:
	void set(int h,int m,int s)
	{
		hour = h,minute = m,second = s;
	}
	friend Time& operator++(Time& a);
	friend Time operator++ (Time& a,int);
	friend ostream& operator<< (ostream& o,const Time& t);
};
//前增量++ 
Time& operator++(Time& a)
{
	if(!(a.second=(a.second+1)%60)&&!(a.minute=(a.minute+1)%60))
	a.hour = (a.hour+1)%60;
	return a;
}
//后增量++ ,为了和前增量区分,参数里面多加了一个int,用以区分 
Time operator++ (Time& a,int)
{
	Time t(a);
	if(!(a.second=(a.second+1)%60)&&!(a.minute=(a.minute+1)%60))
	a.hour = (a.hour+1)%60;
	return t;
}
//重载<<运算符 
ostream& operator <<(ostream& o,const Time& t)
{
	o << setfill('0') << setw(2) <<t.hour << ":" << setw(2) << t.minute << ":";
	return o << setw(2) << t.second << endl << setfill(' ');
}

成员操作符:

成员操作符与普通操作符不同的是:成员操作符声明和定义中省略了第一个参数,因为成员函数总是和对象绑定使用的,被绑定的对象就是被操作的第一参数。因此单目成员操作符没有参数,双目成员操作符只有一个参数。

重载<< 操作符的时候,因为<<操作的前置对象是流类型的cout,不是point类型,所以不能把<<操作设计成Point的成员,而只能设计成普通的函数,而且为了能够访问Point的私有数据,必须用关键字friend引导。


静态数据成员:

有些属性不是类中每个对象分别拥有的,而是类所共有的,保证每个类只有一个实体,每个对象中不再有它的副本,国有的对象都共享这份实体。

静态成员函数:

可以使用对象名调用静态成员函数,也可以使用类名加上域操作符调用静态成员函数,如 

Student s,

s.print() 或者 Student::print()

静态成员函数如果不在类中实现,而在类外实现时,类名前应免去static关键字,成员函数的静态性只在类中声明的时候才是必要的。

静态成员函数调用的时候,如果没有当前的对象信息,所以对象成员函数不能访问数据成员。


友元

将一个普通函数声明为类的友元,就可以直接访问类的私有数据。

友元函数的定义一般放在类的实现中,以作为类的不可分割的一部分。友元可以看作是类操作中的一种访问权限不到位的补充。

猜你喜欢

转载自blog.csdn.net/lidafoye/article/details/80613356