类中的访问
1、Private数据:本类的成员函数
类外:对象.私有数据成员(错)
类外访问:inline doube CBox::GetLength() {return私有数据成员m_Length}这样就可以在外部使用私有数据成员:对象.GetLength();
友元函数:double BoxSurface(CBox aBox){return aBox.m_length;}友元函数可以访问该类的所有成员,其为全局函数。调用:BoxSurface(box)
2、Private函数:同类的其他函数成员
注:只有类成员函数,才能用this指针调用
类中的const:
1:被声明为const的对象其this指针也是const,因此编译器不允许调用任何没有将传递给它的this指针指定为const的成员函数
被声明为const的对象可以调用的成员函数也都必须声明为const
(自己:非const对象调用函数则比较随意,const函数非const函数都可以)
2:仅当某个函数是类成员时,将其声明为const才有意义,其最用是使该函数中的this指针成为const,这意味着不能在该函数的定义内在赋值语句左边写上类的数据成员
Const成员函数不能调用同类的非const成员函数,因为那样也可能修改当前对象
(总是应该将所有不修改当前类对象的成员函数声明为const)
类中的静态:
1、 静态数据成员(程序启动时自动创建并初始化为0)
通过类本身或类对象引用静态数据成员没有影响。
CBox::objectCount和boxes[2].objectCount
2、 CBox::Afunction(10)通过类名调用,该函数内只能使用静态数据成员,不能使用对象的成员
aBox.Afunction(10)通过具体对象调用,可以使用对象的成员
类中的指针和引用
1、 指针
CBox * pBox=nullptr
pBox=&cigar
cout<<pBox->Volume()
注:涉及到对象数组:
CBox boxes[5];
CBox *pB=boxes;
Cout<<(pB+2)->volume();
2、 引用:
CBox & rcigar=cigar;
Cout<<rcigar.volume();
类对象的复制构造函数:
1非动态地为类成员分配空间时:
类对象的复制构造函数若写成:CBox(CBox initB)
这时若是调用CBox myBox=cigar其实编译器是执行 CBox(cigar)但是由于这样是值传递,所以存在复制的过程,复制的过程
又涉及到复制构造函数的执行,所以会陷入复制构造函数的反复执行中出不来
所以要将类对象的复制构造函数写成:CBox(const CBox& initB),(函数体为:m_Length=initB.m_Length这种)这样传递引用的过程不存在复制过程,因此不会反复
调用复制构造函数
注:const的一个重要用途在此也有所体现:我们总是应该将函数的引用形参声明为const,除非该函数将修改实参
2,动态地为类成员分配空间时:(CMessage类中有一个数据成员char *pmessage)
再使用默认的复制构造函数就不再合适,因为默认构造函数的作用是将类对象的指针成员存储的地址复制到新的类对象中,在任何
一个对象中对字符串进行修改,也会修改另一个对象
所以要提供一个类复制构造函数来代替默认版本:
CMessage(const CMessage &aMess)
{
size_t len=strlen(aMess.pmessage+1);
pMessage=new char[len];
strcpy_s(pMessage,len,aMess.pmessage);
}
注:
如果动态的为本地C++类的成员分配空间,则必须实现复制构造函数,因为即使没有用一个类对象初始化同类的对象,若是没有自己实现复制构造函数的话,也会出错,比如下面这种情况:
CMessage aMess1("i love you");
DisplayMessage(aMess1);
其中DisplayMessage函数的定义如下:
void DisplayMessage (CMessage aMess2) { cout<<aMess2.ShowIt(); }
因为默认构造函数创建aMess1的副本aMess2的时候,aMess2的指针指向aMess1所指向的字符串,DisplayMessage函数结果时,调用析构函数,释放aMess2指针指向的
内存,删除aMess2,从DisplayMessage返回时,aMess1包含的指针仍然指向刚被释放的那块内存区域,它被再次使用或最后被删除时,程序将表现出异常行为。