C++知识文档六_对象常量_静态成员_友元_抽象类

对象和常量

  常对象。常对象指在任何场合都不能对其成员的值进行修改的对象。

定义常对象的形式为:

const类名 对象名(参数列表);

或者

类名 const 对象名(参数列表);

  常数据成员。将对象的数据成员声明为const,则为常对象成员。

常对象成员只能在构造函数的初始化成员列表中对其进行初始化(参见初始化成员列表一节)。

  常成员函数。常成员函数不能修改类中的成员数据。

常成员函数的声明形式为:返回类型 函数名() const。

如:

classCA

{

   void Print() const;

};

voidCA::Print() const

{

   cout<<"CallCA::Print()"<<endl;

};

常指针和指向常变量(或常对象)的指针

classCA;

voidFunc(const CA *pa); //函数内部不能通过pa修改对象的成员

voidmain()

{

   int i=1;        

   int * const pi1=&i; //指针本身值不能改变

   const int *pi2;     //不能通过指针修改指向的整型变量值

   CA * const pa1;     //pa1本身的值不能变,没有赋初值,编译通不过

   const CA *pa2;      //不能通过pa2指针修改指向的对象的成员的值。

}

类的静态成员

在面向过程程序设计中,数绝共享主要是通过全局变量来实现的,虽然全局变量引入能够实现数据共享,但是使得变量的值贬得难以跟踪和调试。在面向过陈哥程序设计中,虽然提倡数据的封装和信息隐藏,但有时候也需要在对象间实现数据的共享。类的静态成员变量的引入使得这一目的得以实现。

静态数据成员为类的所有对象共享。即在内存中只有一份空间,静态数据成员的生存期为整个程序运行期。静态数据成员必须在类体外进行初始化。静态成员的通常用 类名::静态成员名 的形式访问

类的另外一种静态成员就是静态成员函数,静态成员函数的引入是为了访问类的成员变量,而且只能访问类的静态数据成员。静态成员的通常用 类名::静态成员函数名的形式调用。

例6、演示静态成员的用法

classCA

{

public:

   int m_iNormal;

   static int m_iStatic;

   void NormalFunc()

   {

      m_iStatic++;        //普通成员函数可以访问类的静态成员变量。思考:为什么还要引入静态成员函数访问静态成员变量

      m_iNormal++;       

   }

   static void StaticFunc()

   {

      m_iStatic++;

      //m_iNormal++;        //非法

   }

   //通过静态成员函数访问某个对象的普通数据成员s

   static void StaticAccessNormal(CA *pThis)

   {

      pThis->m_iNormal++;

   }

};

intCA::m_iStatic=100;

voidmain()

{

   CA a,b;

   CA::m_iStatic=200;    //常用形式

   a.m_iStatic=300;      //不常用

   b.m_iStatic=400;      //不常用

   CA::StaticFunc();        //常用形式

   a.StaticFunc();          //不常用

   b.StaticFunc();          //不常用

   b.StaticAccessNormal(&a); //不常用

   CA::StaticAccessNormal(&a);//常用形式

}

注意:静态成员函数没有this指针。


友元

前面章节讲过,当把一个的成员的访问属性设置成为非公有属性后,是不能从类的外部访问的。但是有的时候,我们需要某个函数或者类也能够访问这些非公有成员。

在C++中有这样的机制使得这一愿望得以实现,这就是友元机制。有以下三种友元:

  友元函数  如果希望一个普通函数Func中能够访问类CTest中的非公有成员,可以在类CTest中声明普通函数Func为该类CTest的友元。即Func是类CTest的友元函数。

  友元成员函数  如果希望类CTest2的成员函数CTest2Func可以访问类CTest1的非公有成员,可以在类CTest1中将类CTest2的成员函数CTest2Func声明为友元

  友元类 如果希望类CTest2的所有成员函数都可以访问类CTest1的非公有成员,可以在类CTest1中将整个类CTest2声明为友元。

注意:友元关系是单向、非传递的。

例7、演示友元的用法

#include<iostream>

usingnamespace std;

classCMyTime;

classCTest2

{

   void Display(CMyTime &tm);

};

classCTest

{

public:

   void Display(CMyTime &tm);

   void Display2(CMyTime &tm);

   friend class CTest2;              //声明CTest2为CTest的友元

};

classCMyTime

{

private:

   int m_iHour,m_iMinute,m_iSecond;

public:

   CMyTime():m_iHour(14),m_iMinute(20),m_iSecond(1){}

   friend void Display(CMyTime &tm);   //声明Display为CMyTime的友元

   friend void CTest::Display(CMyTime&tm);//声明CTest的成员函数Display为CMyTime的友元

   friend class CTest;               //声明CTest为CMyTime的友元

   friend class CTest2;              //因为友元关系不能传递,所以要在CTest2中访问CMyTime类的非公有成员,必须要声明CTest2为CMyTime的友元

};

voidDisplay(CMyTime &tm)

{

   CMyTime obj;

   obj.m_iHour=9;                    //普通函数访问对象的非公有成员

   cout<<tm.m_iHour<<":"<<tm.m_iMinute<<":"<<tm.m_iSecond<<endl;

}

voidCTest::Display(CMyTime &tm)

{

   cout<<tm.m_iHour<<":"<<tm.m_iMinute<<":"<<tm.m_iSecond<<endl;//别的类成员函数访问当前类的非公有成员

}

voidCTest::Display2(CMyTime &tm)

{

   cout<<tm.m_iHour<<":"<<tm.m_iMinute<<":"<<tm.m_iSecond<<endl;

}

voidCTest2::Display(CMyTime &tm)

{

   cout<<tm.m_iHour<<":"<<tm.m_iMinute<<":"<<tm.m_iSecond<<endl;

}

voidmain()

{

   CMyTime time;

   Display(time);

   CTest test;

   test.Display(time);

}


抽象类

当一个类的构造函数是私有或者保护型的时候,这样的类不能像普通类一样来实例化对象。这样的类叫做作抽象类。

构造函数是私有的情况,由于不能从外面调用该类的构造函数。我们考虑从内部来调用该类的构造函数来实例化该类的对象,具体方法是提供一个静态成员函数来调用该类的构造函数。

例8、定义一个类,使用该类只能实例化一个对象,我们把这种情况叫做单例。

#include<stdio.h>

classSingleton

{

public:

   static Singleton* CreateInstance();

   static void ReleaseInstance(Singleton*);

private:

   Singleton(){};

   static Singleton* pinstance;

};

//初始化成员指针

Singleton*Singleton::pinstance = 0;

Singleton*Singleton::CreateInstance()

{

   if (pinstance == 0)

   {

      pinstance = new Singleton;

   }

   return pinstance;

}

voidSingleton::ReleaseInstance(Singleton *pThis)

{

   delete pThis;

}

intmain()

{

   Singleton *pObj=NULL;

   // 调用静态成员函数实例化该类对象

   pObj=Singleton::CreateInstance();

   // 使用完毕后释放该类对象

   Singleton::ReleaseInstance(pObj);

   return 0;

}

阅读更多
文章标签: C++
个人分类: c++自学笔记
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭