Detailed description of C++ classes

Examples of Super Girls have been playing for a long time. To learn from them and leave them temporarily, I will use examples of actual project development to explain more about classes.

File operations have been learned in the C language basics. In practice, in order to improve efficiency, I will encapsulate file operations into a class with the following declarations:

// File Action Class Declaration
class CFile
{
private:
  FILE *m_fp;        // field name pointer
  bool  m_bEnBuffer; // Whether buffers are enabled, true-enabled; false-not enabled

public:
  CFile();   // Constructor of class
  CFile(bool bEnBuffer);   // Constructor of class

 ~CFile();   // Class destructor

  void EnBuffer(bool bEnBuffer=true);  // Enable or Disable Buffers

  // Open the file with the same parameters as fopen, open successfully true, fail to return false          
  bool Open(const char *filename,const char *openmode);

  // Call fprintf to write data to file
  void Fprintf(const char *fmt, ... );

  // Call fgets to read a line from a file
  bool Fgets(char *strBuffer,const int ReadSize);

  // Close file pointer
  void Close();
};

1. Access rights of class members

C++ controls access to member variables and member functions through three keywords: public, protected and private. They represent public, protected and private, respectively, and are called member access qualifiers.Access rights refer to code outside a class that accesses the permissions of its members.

Within a class, that is, in a member function of a class, members can be accessed to each other regardless of whether they are declared public, protected, or private, without restrictions on access rights.

Outside the class (outside the code that defines the class), members of the public can only be accessed through objects, and members of the private, protected properties cannot be accessed.

This section focuses on public and private, and protected will be introduced later.

Members after private are private, such as m_fp and m_bEnBuffer, and will not become common until a public appears; there are no other qualifiers after a public, so members after a public are common.

The purpose of the private keyword is to better hide the internal implementation of the class. This exposed interface (members that can be accessed through an object) is declared public, and it is recommended that members that are not known to the outside, used only within the class, or have no effect on the outside be declared private.

Members declared private and members declared public can appear either first in the private part or first in the public part in any order.If you neither write private nor public, it defaults to private.

private and public can occur multiple times in a class body, respectively.The valid range for each part ends when another access qualifier or body appears (the last right curly bracket).

You might say it's easy to set member variables all to public, and it's true that 99.9% of cases are not an error, and I don't think there's anything wrong with it; however, setting member variables to private is a software design specification, especially in large and medium-sized projects, and it's important that you follow this principle as much as possible.

2. Naming of member variables

Most of the member variables start with m_which is a convention, not a grammatical requirement.Starting with m_you can see at a glance that this is a member variable and distinguish it from the parameter names in member functions.

For example, the body of the member function EnBuffer is as follows:

// Enable or Disable Buffers
void CFile::EnBuffer(bool bEnBuffer)
{
  m_bEnBuffer=bEnBuffer;
}

3. Constructors

There are special member functions in the declaration of the CFile class, CFile(), which are constructor s.

  CFile();   // Constructor of class
  CFile(bool bEnBuffer);   // Constructor of class    

The constructor has the same name and class name, does not return a value, cannot be called explicitly, and is automatically executed when an object is created.

Constructors have the following characteristics:

1) The constructor must be a public property.

2) The constructor does not return a value because there are no variables to receive the return value, which is useless even if it is declared or defined. No return value type can appear before the function name, even if it is void.

3) Constructors can have parameters that allow overloading.A class can have multiple overloaded constructors, and the object is created to determine which constructor to call based on the parameters passed.

4) Constructors are widely used in practical development. They are often used to do some initialization work, initialize member variables, etc. Note that the whole class cannot be initialized with memset.

Example

CFile::CFile()   // Constructor of class
{
  m_fp=0;
  m_bEnBuffer=true;
}

CFile::CFile(bool bEnBuffer)   // Constructor of class
{
  m_fp=0;
  m_bEnBuffer=bEnBuffer;  
}

4. Destructors

There is also a special member function \~CFile() in the declaration of the CFile class, which is the destructor.

~CFile();   // Class destructor

The destructor's name is prefixed with the class name \~, does not return a value, but can be explicitly called, and is automatically executed when an object is destroyed to clean up, such as freeing allocated memory, closing open files, etc. This is an important use to prevent programmers from making mistakes.

Destructors have the following characteristics:

1) The constructor must be public.

2) The constructor does not return a value because there are no variables to receive the return value, which is useless even if it is declared or defined. No return value type can appear before the function name, even if it is void.

3) Destructors do not allow overloading.A class can only have one destructor.

CFile::~CFile()   // Class destructor
{
  Close();  // Call Close to release resources
}

5. C++ programs are also elegant

Many people say that C/C++ programs are boring, Python programs are elegant, and this person is ridiculous because C/C++ doesn't understand it. If we want, we can write code as elegant and concise as python. In book210.cpp, the main function is extremely concise.

Example (book210.cpp)

/*
 * Program name: book210.cpp, this program demonstrates more knowledge of using C++ classes.
 * Author: C Language Technology Network (www.freecplus.net) Date: 20190525
*/
#include <stdio.h>
#include <string.h>
#include <stdarg.h>

// File Action Class Declaration
class CFile
{
private:
  FILE *m_fp;        // field name pointer
  bool  m_bEnBuffer; // Whether buffers are enabled, true-enabled; false-not enabled

public:
  CFile();   // Constructor of class
  CFile(bool bEnBuffer);   // Constructor of class

 ~CFile();   // Class destructor

  void EnBuffer(bool bEnBuffer=true);  // Enable or Disable Buffers

  // Open the file with the same parameters as fopen, open successfully true, fail to return false          
  bool Open(const char *filename,const char *openmode);

  // Call fprintf to write data to file
  void Fprintf(const char *fmt,... );

  // Call fgets to read a line from a file
  bool Fgets(char *strBuffer,const int ReadSize);

  // Close file pointer
  void Close();
};

int main(int argc,char *argv[])
{
  if (argc !=2) { printf("Please enter the name of the file to be opened.\n"); return -1; }

  CFile File;

  if (File.Open(argv[1],"r")==false) { printf("File.Open(%s)Failed.\n",argv[1]); return -1; }

  char strLine[301];

  while (true)
  { // Read each line from a file
    if (File.Fgets(strLine,300)==false) break;

    printf("%s",strLine);   // Show screen what you read from the file
  }
}

CFile::CFile()   // Constructor of class
{
  m_fp=0;
  m_bEnBuffer=true;
}

CFile::CFile(bool bEnBuffer)   // Constructor of class
{
  m_fp=0;
  m_bEnBuffer=bEnBuffer;
}

// Close file pointer
void CFile::Close() 
{
  if (m_fp!=0) fclose(m_fp);  // Close file pointer
  m_fp=0;
}

CFile::~CFile()   // Class destructor
{
  Close();  // Call Close to release resources
}

// Enable or Disable Buffers
void CFile::EnBuffer(bool bEnBuffer)
{
  m_bEnBuffer=bEnBuffer;
}

// Open the file with the same parameters as fopen, open successfully true, fail to return false          
bool CFile::Open(const char *filename,const char *openmode)
{
  Close();  // Close a new file if it is already open before opening it.

  if ( (m_fp=fopen(filename,openmode)) == 0 ) return false;

  return true;
}

// Call fprintf to write data to file
void CFile::Fprintf(const char *fmt,...)
{
  if ( m_fp == 0 ) return;

  va_list ap;
  va_start(arg,ap);
  vfprintf(m_fp,fmt,ap);
  va_end(ap);

  if ( m_bEnBuffer == false ) fflush(m_fp);
}

// Call fgets to read a line from a file
bool CFile::Fgets(char *strBuffer,const int ReadSize)
{
  if ( m_fp == 0 ) return false;

  memset(strBuffer,0,ReadSize);

  if (fgets(strBuffer,ReadSize,m_fp) == 0) return false;

  return true;
}

The effect of book210 is to show the contents of the file line by line, a cat command for the type of linux system.

6. Other knowledge of classes

Other knowledge about classes, including this pointer, static members, friends and so on, is of little significance. I will not introduce it. Time is too precious, there is too much important knowledge to learn, there is no need to waste time on these knowledge points which are neither painful nor practical, so you can look at them later.

7. Variable parameters

We have already introduced the printf, fprintf, sprintf, snprintf functions, which are a set of functions with similar functions and have one common point: the parameter list of functions can be changed.

The function is declared as follows:

int printf(const char *format, ...);        // Format Output to Screen
int fprintf(FILE *stream, const char *format, ...);  // Format Output to File
int sprintf(char *str, const char *format, ...);     // Formatting output to string
int snprintf(char *str, size_t size, const char *format, ...); // Formats the output of a specified length of content to a string

In practical development, our custom functions also use variable parameters to implement functions like these, such as Fprintf member functions of the CFile class.

The C language uses va_start macros, va_end macros, and a series of functions to implement variable parameter functions.

void CFile::Fprintf(const char *fmt,...)
{
  if ( m_fp == 0 ) return;

  va_list ap;
  va_start(arg,ap);
  vfprintf(m_fp,fmt,ap);
  va_end(ap);

  if ( m_bEnBuffer == false ) fflush(m_fp);
}

Take the Fprintf member function of the CFile class as an example.

void CFile::Fprintf(const char *fmt,...);     // Declarations for custom functions with variable parameters

The va_list pointer, va_start macro, and va_end macro are used to analyze parameters and are difficult to understand. You'll use them, but I won't go into details.

  va_list ap;
  va_start(ap,fmt);
  vfprintf(m_fp,fmt,ap);     
  va_end(ap);

The vfprintf function outputs the results of the macro analysis to a file, along with a series of similar functions, as declared below:

// Output Screen
int vprintf(const char *format, va_list ap);
// output to a file
int vfprintf(FILE *stream, const char *format, va_list ap);
// Output to String
int vsprintf(char *str, const char *format, va_list ap);
// Output to a string, the second parameter specifies the length of the output, similar to the snprintf function.
int vsnprintf(char *str, size_t size, const char *format, va_list ap);

8. Homework

1) Write a sample program to test the access rights of class members of a class.

2) Write an example program, test the constructor of a class and its overload, and use gdb to track the execution of the constructor.

3) Write a sample program to test the destructor of a class and use gdb to track the execution of the destructor.

4) Write a sample program to implement the functions of printf, sprintf and snprintf functions, which are declared as follows:

int myprintf(const char *format, ...);
int mysprintf(const char *format, ...);
int mysnprintf(const char *format, ...);

5) Class definitions include the declaration of member variables and functions and the definition of member functions. In practice, we usually put the declaration of public classes in the header file (e.g. _public.h) and the definition of member functions in the program file (e.g. _public.cpp). Modify the book210.cpp program in this way, add the _public.h and _public.cpp programs, and modify the makefile.

9. Copyright Statement

C Language Technology Network original article, reproduced with links to the source, author and text of the article.
Source: C Language Technology Network (www.freecplus.net)
Author: Weinong Youdao

If this article is helpful to you, please comment on it or forward my article to your blog, thank you!!!
If the article has mistyped words, incorrect content, or other suggestions and opinions, please leave a message to correct, thank you very much!!!

Keywords: C++ C network Python Linux

Added by bensonang on Sat, 18 Apr 2020 20:10:10 +0300