Encapsulation of classes is enhanced by using access descriptors. The members defined after the public descriptor can be accessed throughout the program, and the public members define the interface of the class. The members defined after the private descriptor can be accessed by the member functions of the class, and the private part conceals the implementation details of the class.
Example:
class Sales_data {
public:
Sales_data() = defult;
Sales_data(const std::string &s) :bookNo(s) {}
Sales_data(const std::string &s,unsigned n,double p):
bookNo(s),units_sold(n),revenue(p*n) {}
Sales_data(std::istream &s);
std::string isbn() const {return bookNo;}
Sales_data& combine(const Sales_data&);
private:
double avg_price() const {return units_sold ? revenue/units_sold : 0;};
std::string bookNo;
unsigned units_sold =0;
double revenue =0;
};
** Use class or struct keywords ** Using the struct keyword, members defined before the first access descriptor are public, and if using the class keyword, those members are private.
1. friends
A class can allow other classes or functions to access its non-public members by making other classes or functions friend s. If class To make a function its friend, you just need to add a function declaration statement starting with the friend keyword. Example:
class Sales_data {
//Friend declarations for non-member functions of Sales_data
friend Sales_data add(const Sales_data&,const Sales_data&);
friend std::istream &read(std::istream&, Sales_data&);
friend std::ostream &print(std::ostream&, const Sales_data&);
public:
Sales_data() = defult;
Sales_data(const std::string &s) :bookNo(s) {}
Sales_data(const std::string &s,unsigned n,double p):
bookNo(s),units_sold(n),revenue(p*n) {}
Sales_data(std::istream &s);
std::string isbn() const {return bookNo;}
Sales_data& combine(const Sales_data&);
private:
double avg_price() const {return units_sold ? revenue/units_sold : 0;};
std::string bookNo;
unsigned units_sold =0;
double revenue =0;
};
//Statement of non-member components of the Sales_data interface
Sales_data add(const Sales_data&,const Sales_data&);
std::istream &read(std::istream&, Sales_data&);
std::ostream &print(std::ostream&, const Sales_data&);
** Statement of Youyuan** If you want the user to call a friend function, we will make a special declaration of the function besides the declaration of the friend function. We usually make the declaration of the friend function. Place it in the same header file as the class itself (outside the class).
2. Other features of classes
Define two interrelated classes: Screen and Window_mgr ** Define a type member**
class Screen{
public:
typedef std::string::size_type pos;
private:
pos cursor = 0;
pos height =0; width =0; //Three size_type members representing the position of the cursor and the height and width of the screen
std:: string contents; //Save Screen content
};
(1) Typeedef can also use type aliases equally, as follows:
class Screen{
public:
//Use type aliases to declare a type name equivalently
using pos = std::string::size_type'
}
(2) Members used to define types must be defined before they are used. ** Screen class member function**
class Screen{
public:
typedef std::string::size_type pos;
//Default constructors are required and must be explicitly declared
Screen() =default; //Because Screen() has another constructor, this function is required.
//cursor is initialized to 0 by its class initial value
Screen(pos ht,pos wd,char c):height(ht),width(wd),
contents(ht *wd,c) {}
char get() const //Read the character at the cursor
{return contents[cursor];} //Implicit inline
inline char get(pos ht, pos wd) const; //Display inline
Scereen &move(pos r, pos c);
private:
pos cursor = 0;
pos height =0; width =0; //Three size_type members representing the position of the cursor and the height and width of the screen
std:: string contents; //Save Screen content
};
** Make Members Inline Functions** The member functions defined within the class are automatically inlined. (Advantages of inline Functions: Improving Program Execution Efficiency) Inline is explicitly declared as part of the declaration inside the class. Similarly, inline keywords can be used outside the class to modify the definition of the function: ** Overloaded member functions** ** Variable Data Members** ** Initial values of class data members** In the new C++11 standard, a default initialization value can be assigned to the class definition.
3. Friendship among classes
For example, add a member named clear to Window_mgr, which is responsible for setting the content of a specified Screen to blank. in order to To accomplish this task, clear needs to access the private members of Screen. To make this access legal, Screen needs to designate Window_mgr as its friend.
class Screen {
//Members of Window_mgr can access private parts of Screen classes
friend class Window_mgr;
//The remainder of the Screen class
};
If a class specifies a friend class, member functions of the friend class can access all members of the class, including non-public members in the class. Then, we can The clear members of Window_mgr are written as follows:
class Window_mgr {
public:
// Number of each screen in the window
using ScreenIndex = std::vector <Screen>::size_type;
//Reset the specified Screen to blank by number
void clear(ScreenIndex);
private:
std::vector <Screen> screens{Screen(24,80,'')};
};
void Window_mgr::clear(ScreenIndex i)
{
//s is a Screen reference to the screen we want to empty
Screen &s =screen[i];
//Reset the selected Screen blank
s.contents = string(s.height *s.width,'');
}
** Make member functions as friends** class Screen { // Window_mgr::clear must be declared before the Screen class friend void Window_mgr::clear(ScreenIndex); }; ** Function Overload and Friends** If a class wants to declare a set of overloaded functions as its friends, it needs to declare each of these functions separately: // Overloaded storeOn function
extern std::ostream& storeOn(std::ostream&, Screen &);
exterm BitMap& storeOn (BitMap &, Screen &);
class Screen{
//StorOn's ostream version has access to the private parts of Screen objects
friend std::ostream& storeOn (std::ostream& ,Screen &);
};
** Friendship Statement and Scope** Defining the friend function inside the class, we must also provide the corresponding declaration outside the class to make the function visible. We're just making friends. The member of the metaclass calls the friend function, which must also be declared:
struct X{
friend void f() {/*Friend functions can be defined within a class*/}
X() {f();} //Error: f has not been declared yet
void g();
void h();
};
void x::g() {return f():} //Error: f has not been declared yet
void f(); //Declare the function defined in X
void X::h(); {return f();} //Right: Now the declaration of f is in scope