数据成员和成员函数
- 我们知道类的成员函数可以在类内定义也可以在类外定义,在类外定义时要加上类名字和作用符“ :: ”,其实两者也有一些差别。
- 在类定义的花括号内直接定义的成员函数默认为inline函数,而在类外定义inline函数时,要加关键字inline
访问限定和信息隐藏
-
三种访问限定符
- private(默认):只能由自己的函数成员或友元访问。
- public:成员在任何函数或类中都可以被访问。
- protected:除了自己和友元可以访问外,派生类成员也可以访问。
-
访问器函数
- 要想获取和修改private中的数据,就要在类中设定一种函数,用来访问这些数据。
- 一般的访问器函数有setX,getX等,如void getX{return X;}
this指针
- this指针是指向一个对象的指针,和其他指针一样 this 代表这个类的地址,而 *this 则代表这个对象。
- 每个成员函数都有隐含的参数,指向接受消息的对象,称为 this 指针。
- this指针是一个常量,不能改变其值。
-
this指针作用:
- 区分与局部变量重名的数据成员
- 返回当前对象
- 获取当前对象地址
#include <iostream>
using namespace std;
class X{
int m;
public:
void setVal(int m){
this -> m = m; /*作用1*/
}
X& add(const X& a) {
m += a.m;
return *this; /*作用2*/
}
void copy(const X& a){
if (this == &a) /*作用3*/
{
cout<<"地址相同,没有复制"<<endl;
return;
}
m = a.m;
cout<<"地址不同,成功复制"<<endl;
}
int getm(){
return m;
}
};
int main()
{
X a,b,c;
a.setVal(1); b.setVal(2); c.setVal(3);
a = a.add(b);
cout<<a.getm()<<' '<<b.getm()<<' '<<c.getm()<<endl;
a.copy(a); a.copy(c);
cout<<a.getm()<<' '<<b.getm()<<' '<<c.getm()<<endl;
return 0;
}
注:例子中const X& a含义:
- X& a 表示引用a,如果函数中改变了a的参数,会直接改变main函数中a的参数。
- X a 表示是形参,形参的改变不会造成main中参数的改变。
- 设置形参时要进行复制等工作,效率低;而引用参数有可能无意之中改变了参数的值,造成不易察觉的逻辑错误。
- 加上const以后,如果改变了a的参数,编译会报错,防止了逻辑错误。
友元
- 如果想让非成员函数访问一个类中的私有数据,应该在这个类中将这个函数声明为友元。
- 一个类的友元可以是全局函数、另一个类的成员函数或另一个类。
- 类A是类B的友元隐含着A的所有成员函数都是类B的友元。
- 友元关系是不可以传递也不可以继承的。
- 友元会破坏封装性,应尽量避免使用。
-
实例:设置一个全局函数add实现虚数类的加法。
#include <iostream>
using namespace std;
class Complex{
double real,imaginary;
public:
void setReal(double x){real = x;}
void setImaginary(double x){imaginary = x;}
void getComplex(){cout<<real<<'+'<<imaginary<<'i'<<endl;}
friend Complex add(const Complex&,const Complex&);
};
Complex add(const Complex& a,const Complex& b){
Complex temp;
temp.real = a.real + b.real;
temp.imaginary = a.imaginary + b.imaginary;
return temp;
}
int main()
{
Complex a,b,c;
a.setReal(1); b.setReal(2);
a.setImaginary(3); b.setImaginary(4);
c = add(a,b);
cout<<"a="; a.getComplex();
cout<<"b="; b.getComplex();
cout<<"c=a+b="; c.getComplex();
return 0;
}