Depth analysis of the class (Part II)

Depth analysis of the class (Part II)

A, const objects and const member functions

We use const object const member functions and to limit changes to the object in order to enhance the principle of least privilege.

1, const objects

const Time noon(12,0,0);//const对象不能被修改

Attempt to modify a const object operation will result in a compilation error

2, const member function
declarations may be a member function const member functions, the value of its class object can not be modified.

1, the member function to modify the definition of the object's data members as const causes a compilation error.
2, defined as const member functions it calls the same instance of the same class of non-const member functions will cause a compiler error.
3, const object to call a non-const member functions will cause a compiler error.
4, does not allow the constructor and destructor functions declared const, but const object can call the constructor and destructor.

Below a category Time will be described briefly:

/*函数原型的定义,函数实现不需要改变的声明为const*/
int getHour() const;
int getMinute() const;
int getSecond() const;
void printUniversal() const;
/*函数实现时也需要在函数原型后面加上const限定词*/
int Time::getHour() const;
......
void Time::ntUniversal() const; 

When generating objects declared const object can only call const function;
rather than const object can either call the const function, you can also call non-const function.

const and non-const comparison:

/*类的定义*/
class Time
{
public:
      void setTime(int,int,int);//非const函数。
      void setTime(int,int,int) const;//const函数。
      //....
};

/*对象的生成*/
int main()
{
const Time noon;//const对象。
Time t1;//非const对象。
noon.setTime(12,0,0);//const对象调用const函数。
t1.setTime(9,0,10);//非const函数都可以调用。
}

3, members initializer
member is used to initialize the data members of the class initialization, all the data members can be initialized with the initialization syntax member.

You must use member initialization to initialize the data are:

  • const data members;
  • Referenced data members;
  • Members of the object;

Member initialization list before the constructor body is executed.

class ...//类的定义
{
private:
       int count;
       count int increment;//const数据成员
};

/*使用成员初始化器来初始化*/
Increment::Increment(int c,int i)//构造函数count(c),//可以使用成员初始化器初始化,也可以在构造函数体中初始化。
increment(i)//只可以在这初始化。
{
......
}

1, members of the initializer ends with a colon begin without any symbol.
2, if there is more than one member initializers, then between them separated by commas.

Second, the composition: object as a member of the class

Order structure (if there are multiple) member objects to define the class declaration, not before they establish in order to initialize the list of members, and include them in the class object.

The following give Date class Employee class and will be explained:Here Insert Picture DescriptionHere Insert Picture Description

//Date类
private:
       int month;
       int day;
       int year;

//Employee类
private:
       char firstName[25];
       char lastName[25];
       const Date bithDate;//Date类生成bithDate对象
       const Date hireDate;//Date类生成hireDate对象

In the constructor function implemented in the Employee:

Employee::Employee(const char * const first,const char * const last,const Date & dateOfBirth,const Date & dateOfHire)
:bithDate(dateOfBirth),
hireDate(dateOfHire)//分别调用了两次拷贝构造函数初始化数据成员bithDate和hireDate。
{
......
}

If the object is not a member of the members is initialized with the initialization class members in the form object and does not provide a default constructor, a compile error.

If the members of the class is the object of another class, even if the development of the member object is public, it will not destroy hidden encapsulation and private members of the members of the object, but it does break encapsulation containing class implementation and hidden, so the object class type members must be private, like all other members of the same data.

Third, the friend function and friend class

Class friend function defined outside the domain class, but have permission to access the non-public class (and public) members, separate function or the entire class may be declared as a friend of another class; the class definition before the function prototype plus friend keyword, declare a function like a friend.
To all the class member functions declared as a friend of Class Two Class One should add the following statement in the form of ClassOne definition:

friend Class Two;

The following example illustrates a first friend function:

#include<iostream>
using namespace std;

class Count
{
     friend void setX(Count &,int );//friend declaration.
public:
     Count()
     {
          x = 0;
     }
     void print() const
     {
          cout << "x is :" << x << endl;
     }
private:
     int x;
};

void setX(Count &c,int number)
{
     c.x = number;//allowed because setX is a friend of Count.
}

int main()
{
     Count counter;
     counter.print();

     setX(counter,10);//set X using a friend function.
     counter.print();
     return 0;
}

The second example illustrates the friend classes:
Here Insert Picture Description
Class A is a friend class B, class A can access the object by Class B Class B, in particular the class B private data members.

The use of this pointer

Each object can use a pointer to point to this own address, this is not an object pointer part of the object itself.
Each class member functions this contains a pointer to the object belongs when this member function is called. E.g:

object1.set(~);//set函数存在一个this指针指向object1;
object2.set(~);//set函数依然存在一个this指针指向object2.

1, the use of this pointer to access the data members of the object and display the implicit

this pointer as an implicit argument passed to each non-static member functions of the object; the object may be implicit or explicit reference to their use this pointer to data members and member functions.

Implicit and explicit use of this pointer:
(1), using an implicit:
only the specified data member names.
(2), explicit use of:

this->//箭头运算符*this.//圆点运算符

For example, to output the value of x in a program, there are three methods:

cout "          x = " << x ;//隐式使用
cout "    this->x = " << this->x ;//使用箭头运算符
cout << "  (*this).x = " << (*this).x ;//使用圆点运算符

operation result
2, this series of function pointers to make it possible to
make more function calls in the same statement:

//函数返回其对象的引用
t.setHour(10).setMinute(25).setSecond(50);

Returns the type of comparison:

Time setHour();//返回的是Time的一个副本
Time &setHour();//返回Time的引用

Here is an example:

Time &Time::setHour(int h,int m,int s)
{
   setHour(h);
   setMinute(m);
   setSecond(s);
   return *this;
}//返回对象的引用,操纵者能够使用该对象。

void Time::printUniversal() const;//无返回类型
void Time::printStandard() const;//无返回类型

int main()
{
t.setHour(10).setMinute(25).setSecond(50);//正确
t.setTime(11,1,10).printUniversal();//正确
t.setTime(11,1,10).printUniversal().printStandard();//错误
t.printUniversal().setTime(11,1,10);//错误
}


Five, static class members

static data members of the class looks like global variables, but they only work in the class scope; static data members of each class of only one copy is shared by all objects of that class.

If the class is not an object is instantiated before, this static data member still exists, this is a start to finish there. It can read data whether objects.

1, declare static data members
before the variable declaration plus the static keyword can be declared as public, private, and protected

2, initialize static data member
static initialization data from the definition of the body member of the class. Before initialization of static data member name plus the name of the class

double Account::interestRate = 0.0589//Account为类名

Under special circumstances, int const static data members can be initialized in the class declaration.

Initialize static data member can not be placed in the header file, executable file, but functions defined in the class members.

3, access to static data member
static data members of a class member function can be used directly in class. E.g:

double Account::dailyReturn()
{
  return  (interestRate/365*amount);
}

A non-member function (function test code) (data members using a non-member function, the modified data members of the public should be), accessed by static data members of two ways:

Member access operator (->,.) When there is an object ---------;
data member names preceded scope resolving the class name and binary operators (::) ------ no object.
Time::静态数据成员;

When there is not an object class, static data members access to private and protected classes, it provides a public static member functions, and in front of the function name by the class name and binary scope resolution operator call mode. (If there is present in the object class, the interface may be accessible by the public.)

Declare static member function declaration with non-static member function is the same, except for the first class declaration in a static member function add the keyword static. And the function can not be declared const.

static data members and static member functions added only when declaring static, in the implementation and initialization not need to add static, such as:

static int count;//声明静态数据成员
int Employee::count = 0;//初始化

static int getCount();//静态成员函数的声明,只在原型中。
int Employee::getCount()//静态成员函数的实现
{
}

const member functions in the declarations and implementations need to add const, for example:

int getHour() const;//声明
int Time::getHour() const//实现
{
}

6, the Acting Class

The client proxy class code changes implemented isolated
following a simple example to be described:

class Implementation//定义Implementation类
{
public:
     Implementation(int v)
     :value(v)
     {
     }//空的函数体
     void setValue(int v)
     {
          value = v;
     }
     int getValue() const
     {
          return value;
     }
private:
     int value;
};

/*代理类,此代理类提供给用户,私有数据成员以及成员函数的实验完全不能被看到*/
class Implementation;//声明一个需要被代理的类

class Interface
{
public:
     Interface(int);//代理类自己的构造函数
     void setValue(int);//与被代理的类完全一样
     int getValue() const;//与被代理的类完全一样
     ~Interface();//代理类自己的析构函数
private:
     Implementation *ptr;//一个私有数据成员指向被代理类的指针
};
#include "Interface.h"
#include "Implementation.h"

Interface::Interface(int v)
:ptr(new Implementation(v))//通过私有数据成员的指针来操纵被代理的类
{
}

void Interface::setValue(int v)//代理类中的setValue()
{
     ptr->setValue(v);//被代理类中的setValue()
}

int Interface::getValue() const //代理类中的getValue()
{
     return ptr->getValue();//被代理类中的getValue()
}

Interface::~Interface()
{
     delete ptr;//删除指针
}

#include<iostream>
using namespace std;

#include "Interface.h"

int main(void)
{
     Interface i(12);
     cout << "Interface contains :" <<  i.getValue() << "before setValue" << endl;
    
     i.setValue(10);
     cout << "Interface contains :" <<  i.getValue() << "after setValue" << endl;

     return 0;
}

Released three original articles · won praise 18 · views 390

Guess you like

Origin blog.csdn.net/m0_46518461/article/details/105195888