C++ review special-class\structure\function\two-dimensional array\polymorphism brief introduction

class

Class declaration

//test1.h     注意这里是头文件
class stock
{
    private:
        std::string company;
        long shares;
        double share_val;
        double total_val;
        void set_tot(){cout<<"fuck"<<endl;
    public:
        void acquire();
        void buy();
        void spell(int a, int b, double sum);
        void output(std::string str, name, int age);
};
  
/*
    这里介绍一下public和private,显然public就是对外开放的,你可以通过类对象用.运算符或通过指针利用->访问符, 来访问公有成员函数,即public下的成员统称#为公有成员,同理private下的成员统称为私有成员
    是的,public成员可以通过.操作来进行访问,但是私有成员无法直接通过对象用.操作符来访问,必须由对象通过公有成员来访问私有成员
    这种私有成员,很好的杜绝了数据外泄,可以很好的组织程序直接访问数据,这被称为数据隐藏
*/

Usually C++ programmers put the interface (class definition) in the header file, as in the above program, and the definition of the class method is in the source code file that contains the above header file. How are that class definition and class method definition specifically related? What about??

  • Interface/Package

The idea of ​​a class separates the public interface from the implementation details, puts the implementation details together and separates them from the abstract, that is, term encapsulation.

The above data hiding is also a kind of encapsulation, and hiding the implementation details in the private part is also encapsulation.

The public interface of the class represents the abstract component of the design. For example, many void functions in the public mentioned above are method functions for data manipulation, which is a data manipulation method abstracted from specific data . These method function declarations are It is placed in the .h header file, and the specific algorithm of this method, that is, the structure of the function body is implemented in the source code file containing the .h header file. This is also a kind of encapsulation, that is, the implementation details and Abstract separation

Is there any difference between class and structure? 

Yes, for now, it seems that there is no difference, except that class is a struct with public and private.

The biggest and only difference between class and struct is that class accesses private by default and struct accesses public by default. Yes, the structure is extended in C++, and it can also have some characteristics of class, such as public and private

C++ usually uses classes to describe data and related operations, while structures are only used to purely represent data objects

  • How to implement the member functions of the class?

Class member functions/method functions/methods, like ordinary functions, have function declarations, return values, parameters, and function bodies.

the difference:

1⃣️The function declaration is placed in the header file , and the function definition is placed in the source code containing the header file

2⃣️When defining function members, you need to use the scope resolver ::  to mark the class to which the function belongs

Of course, the class method can access the private members of the class (this is what we said above)

The realization of the class generally includes three files: the header file creates the class, the definition file implements the class function, and the main program file calls the reference class.

//实现类的成员函数,就是在包含了头文件的源代码中去定义函数体
double stock::acquire()   
{
    "在类方法函数的定义中,你可以随便调用任何一个成员变量"
}

float stock::buy()
{
    ...
}

double stock::spell(int a, int b, double sum)
{
    ...
}

long stock::output(std::string str, name, int age)
{
    ...
}

The difference between the definition of class method function and ordinary function:

Class method functions do not require function prototype declaration, while ordinary functions need

When class method function definition declaration, you need to use :: to indicate the class to which it belongs, ordinary function does not need

  • Member access, public or private

One of the main goals of OOP is to hide data, so the member functions that make up the class interface are in the public part, and the data items are often in the private part.

Why can't member functions be placed in the private part? Because if the function is private, it is not possible to directly call the member function through the class object

What if I have to define a function in the class declaration, that is, the function body of the class method is in the class declaration, and in private, what will happen?

//类声明,即头文件中
//举例说明类声明
//test1.h     注意这里是头文件
class stock
{
    private:
        std::string company;
        long shares;
        double share_val;
        double total_val;
        void set_tot(){cout<<"fuck"<<endl;}    #就是笔记开头的这个语句
    public:
        void acquire();
        float buy();
        void spell(int a, int b, double sum);
        double output(std::string str, name, int age);
};

Note: As long as the functions defined in the class declaration are inline functions , they are automatically converted to inline functions. The functions in the class declaration have a characteristic: short and concise

To expand the idea, I can also define an inline function under the class declaration, just specify the corresponding class, as follows

//举例说明类声明
//test1.h     注意这里是头文件
class stock
{
    ...
};
inline void stock::set_tot()
{
    cout<<"fuck"<<endl;
}
//这和上述代码是一样的效果,不要忘记,这里也是在头文件中哦, 即使inline函数是完整的定义声明(含函数体)

Class object initialization-constructor

Since the data items of the class are hidden, they cannot be initialized when defined like int types or structures. After all, data access is private and cannot be accessed directly.

  • The class constructor is generated for initialization. C++ provides a special member function, the class constructor, which is specifically used to construct new objects. The function is to assign specific values ​​to data members.
    • C++ provides a name and applicable syntax for this special member function, we need to provide a method definition

      • The name of this type of function is the same as the name of the class, that is, a member function in the stock class is stock()

      • This special member function, the constructor, has no return value

  • The creation of this special function is the constructor. The parameter name of this function cannot be the same as the data member name of the class, and the prefix m_ etc. can be added.

The declaration of the constructor

//创建一个构造函数,需要两部分,即声明和定义
//声明
//class.h
stock(const string & co, long n =0, double pr =0.0);
//定义
//project.cpp
stock::stock(const string & co, long n, double pr)
{
  	"在类方法中,你可以随便调用任何一个成员变量"
    company =co;
    if (n < 0)
        {    
            cout<<"fuck"<<endl;
        }
        else {cout<<"gun"<<endl}
}
//构造函数没有返回值, 构造函数名字和类名相同,构造函数的具体定义是你自己来搞的

Constructor call

How to use the constructor? How to avoid not using the class but just using the constructor?

  • Show call constructor
stock food = stock("world", 250, 12.2);
//第一个stock是类,创建了对象food,第二个stock是类构造函数
  • Implicitly call the constructor
stcok food("world",250,122.2);
//这里的stock是类,创建了对象food
  • Combined with new to dynamically create and initialize
stock *food_ptr = new stock("world",250,122.2);
//第一个stock是类,创建了对象指针,第二个stock是类构造函数

Note! Ordinary classes can use the object. operator to access class functions, but they cannot access class constructors, that is, constructors are used to create objects, but they are not called by objects

~Destructor

 

The constructor is used to initialize the object, and the destructor is used to clean up the object. The constructor can allocate memory through new. The destructor uses delete to complete the memory release. If new is not used, the destructor has no tasks to do. Up.

The destructor is very special, that is, adding ~ before the name of the class is its name. For example, the destructor of the stock class is ~stock()

Like the constructor, the destructor has no return value and statement type statement, the difference is that the destructor has no parameters.

Declaration of destructor-how to use destructor

If the destructor does not perform any important work, it can be written as a function that does nothing

stock::~stock()
{}

Destructor call-when to use destructor

The compiler decides that the destructor is usually not called explicitly

In the same way, if we do not provide a destructor, the compiler will automatically declare a destructor (note that it is a declaration), and then when it finds that there is code to delete the object, it will automatically define a default destructor (here is the definition)

The constructor and destructor are the declaration in the header file in, and specific functions defined in the source code of the

//stock.h头文件
class stock
{
    private:
        std::string company;
        long share;
        double share_val;
        void set_tot(){cout<<"fuck"<<endl;}
    public:
        stock();
        stock(const std::stirng &co, long n=0, double pr=0.0);
        ~stock();
        ...
}
//stock.cpp源代码
#include <iostream>
#include "stock.h"
stock::stock()
{
    std::cout<<"这里是默认构造函数"<<endl;
    company ="no name";
    shares = 0;
    share_val = 111;
}

stock::stock(const std::stirng &co, long n=0, double pr=0.0);
{
    std::cout<<"普通构造函数的输入字符串是:"<<co<<endl;
    company = co;
    ...
}
stock::~stock()
{
    cout<<"there are nothing"<<endl;#可以不写,只是为了看看
}

Can the braces {} be used for initialization?

stock test1 = {"test1", 100, 2.2};
stock test2 {"test2",200.3.4};
stock test{}

The first two directly call stock::stock(const std::stirng &co, long n=0, double pr=0.0)

The last one directly calls stock::stock()

Modify the data members of the class

this pointer can help you

What does it mean? That is, your private data can only be accessed through public member functions, but cannot be modified. How to modify this data?

Class inheritance

  • C++ provides a better way to extend and modify classes than modifying code, that is, class inheritance

    • A new class can be derived from an existing class, and the derived class inherits the original characteristics, including all method functions

      •  The original class is called the base class, the derived class is called the derived class, or the inherited class is called the derived class.

Base class

  • Use the symbol:  to point out that the base class of the RP class is the TTP class, plus public to indicate that this is a public base class, and RP as a derived class is also called a public derived class

  • Derived class objects will contain base class objects

  • The public derived class will have all the public members and private parts of the base class, but the private part of the base class, the derived class is not free to access

    • The derived class inherits the implementation of the base class, that is, the data members of the base class.

    • The derived class inherits the methods of the base class, that is, the interface of the base class

class TTP
{    
    ...
}
class RP: public TTP
{
    ...
}

Derived class

Knowing the relationship between the base class and the derived class, what do we need to add to the definition of the derived class???

  • Belongs to the constructor of the derived class

  • Append non-base classes that are extra data members and member functions

Derived class constructor

The derived class cannot directly access the private members of the base class, and must be accessed through the method (function) of the base class .

Q: Our constructor is used to initialize class members. If we can't access these data members, we can't initialize the data through the constructor of the derived class.

A: Need your derived class constructor must use the base class constructor

The base class object should be created before the program enters the derived class constructor.  To create the derived class object, you must first create the base class object

Note that this is not to say to create two objects, but C++ uses the list initialization syntax to complete this operation, how to complete it? See below

RatedPlayer::RatedPlayer(unsigned int r , const string & fn, const strng & ln, bool ht):TableTennisPlayer(fn, ln, ht)
{
    //派生类  ::   派生类构造函数(参数)  :  基类构造函数(基类参数)
    ...
}
//基类成员初始化列表 :TableTennisPlayer(fn, ln, ht), 这是调用了基类的构造函数

//这里可能晦涩难懂, 举个例子

RatedPlayer xjh(1123, "M", "duck", true);

First, in the RatedPlayer constructor, the parameters of the xjh object are given to the four formal parameters r, fn, in, ht of the RatePlayer constructor, and then this formal parameter is used as an actual parameter and passed to the formal parameter fn in ht of TableTennisPlayer , So a base class object is created, and your xjh parameters are stored in the base class object. Then, the program enters the function body of the RatedPlayer constructor, and executes the statement of the function body

Create a derived class object -> derived class constructor -> object parameter to the constructor parameter -> constructor parameter as an actual parameter to the base class constructor -> base class constructor to create a base class object- >The initialization parameters of the derived class object are all stored in the base class object -> to complete the above-mentioned creation of the derived class object, the base class object must be created

The base class object must be created first, but like in the above code, you don't write: TableTennisPlayer(fn, in, ht) This base class constructor, the program will automatically call the program

Use derived classes

To use a derived class, you must put the declarations of the base class and the derived class together. Of course, you can also put them in different .h header files through the #include method, or put them in one header file.

The interface definition of the class can be placed in a separate .cpp file, just need your source code and this .cpp file include the above header files, it's OK. And your header file, you don't need to include the source code and the .cpp file

//tabletenn1.h 头文件
using namespace std;
using namespace string;
class TableTennisPlayer
{
    ...
}
class RatedPlayer : public TableTennisPlayer
{
    ...
}


//tableten1.cpp 接口源文件
#include "tabletenn1.h"
TableTennisPlayer::TableTennisPlayer () {}
//这里都是两个类的函数结构定义程序



//main.cpp 主程序源文件
#include "tabletenn1.h"
int main()
{
    //直接使用类
    TableTennisPlayer xjh1(...);
    RatedPlayer xjh2(...);
}

Use and design

Learned the definition and simple use of classes, learned about the two member function destructors and constructors, these are the general principles of classes, and then began to learn class design techniques

Create class object

Note! Each created object has its own memory block. Here you can think of ordinary variables. The class is of type int, and the object is a data object of type int, such as int name=0;

#include <iostream>
#include "test1.h"
int main(){
    stock xjh;//创建类对象
    xjh.acquire();
    xjh.buy();
    xjh.spell();
    xjh.output();
// 对于指针
    stock * ptr = new stock;
    ptr->buy();
    ptr->spell();
}

structure

  • The array allows you to define variables that can store the same type of data items, and the structure allows you to store different types of data items.
  • You can define pointers to structures in a similar way to defining pointers to other types of variables. Put the & operator in front of the structure name
  • Pointer access to the members of the structure , you must use the -> operator
struct Books *struct_pointer;
struct_pointer = &Book1;
struct_pointer->title;
  • In a simpler way to define the structure, you can take an "alias" for the created type. Now, you can directly use  Books  to define   the variables of the Books type without using the struct keyword (in general, it is possible even if it is not quoted (Ignore the strcut keyword to define structure objects)
//previous
struct Books
{
   string name;
   int   book_id;
};

struct Books Book1;
Books newBook;
newBook.name = "abcd";

//now
typedef struct Books
{
   string name;
   int   book_id;
}BOOKS;

BOOKS Book1, Book2;

In order to access the members of the structure, we use the member access operator (.)

struct type_name {
member_type1 member_name1;
member_type2 member_name2;
member_type3 member_name3;
.
.
} object_names;


struct Books
{
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
} book;

typedef struct Books
{
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
}Books;

function

The construction template of the function is as follows

typeName functionName(parametersList);
void mian(){}
typeName functionName(parametersList)
{   
    statements
    return value;
}
//retrun无法返回数组,但可以是结构,类对象,或者可以把数组作为结构和类对象的成员返回
//函数参数也不能是数组

Functions cannot return arrays, and function parameters cannot be arrays, but you can use arrays through structures and classes, or set parameters

When defining a function, the variables of the parameter list are formal parameters. When the function is called, they are actual parameters. The actual parameters always exist (of course, this is a normal variable, new is to say otherwise), the formal parameters, when the function is called, the computer assigns the formal parameters Memory, when the function ends, these memory blocks are released, so the formal parameters are called local variables, and their scope is only inside the function

typeName fucntion(int param1, &prama2){}
void main()
{
    int a = 10;
    int b =11;
    function(a, &b);
}
//a和b都是实参,param1和param2都是形参

Combine arrays and functions

Wait! Doesn't it mean that the parameter cannot be an array, and retrun cannot return an array??? Is it just for parameter passing?? No

int functionArray(int array[], int n);
//这里的array[]实际上是个指针,还记得指针和数组名其实是一个东西吗?
  • Yes, int array[] means an array, and the square brackets are empty, which means that you can pass an array of any length to the function functionArray(), which is actually wrong, the array here is a pointer!!! But you see him What about arrays?

  • In addition, if you want to process the array through a function, you'd better tell the function the name of the array, the type of the array, and the length of the array.

If you want the function to modify the passed array

void function(double arr[], int n){}

If you don’t want the function to modify the passed array

void function(const double arr[], int n){}

Inline function

  • The final compilation process is to generate an executable file and then run it. When running the program, the operating system loads the executable file, that is, these machine language instructions into the memory, and then executes it step by step according to the address of the instruction. Sometimes a loop or conditional branch is encountered. The statement will jump and execute, the function call will also jump from an address to the first address where the function is located, and the function will return when it ends

  • When the program jumps to the function address, that is, the program will store the address of the instruction immediately after the function is called, then put the function parameters in the stack memory pool, and then jump directly to the memory block that marks the start of the function to start executing the function code , And jump back at the end of the function.

  • Jumping back and forth and recording the jump position requires too much overhead. Therefore, C++ provides inline functions without jumping, but requires more memory. That is, if the program calls the same inline function in 10 different places, this The introverted function will have 10 copies

  • Use: Add the keyword inline before the function declaration or definition

  • Reference variable

    • Reference notes

Function overloading

  • Terminology: polymorphism and overloading refer to the same thing, that is, multiple forms of the same object

  • Function polymorphism = function overloading, that is, multiple forms of functions are allowed, that is, there are multiple functions with the same name, polymorphism is function polymorphism, and overloading is actually function name overloading

  • Regardless of polymorphism or overloading, the meaning is that the name is the same but the parameter list is different

  • Function signature: The parameter list of the function. If two functions, the number of parameters, the parameter type, and the order of the parameters are the same, then their signatures are the same. Obviously, it has nothing to do with the name of the parameter variable.

  • C++ allows to define functions with the same function name, provided that their signatures are different

double cube(double x);
double cube(double &x);
//看起来特征标是不同的,其实,类型引用和类型本身是同一特征标

double long(double x);
long long long(double x);
//显然这里的long函数是不允许被重载的,因为特征标是相同的,即返回值类型并不是特征标之一

Function overloading is great, but don't abuse it. Only when the function performs basically the same task, but the data type of the object is different, you can consider function overloading

Function template

  • The function template is a general function description. Use "generic" to define the declared function. Here, "generic" can be replaced with specific types, such as int, double, long, etc. The specific method is to pass specific types such as double as parameters. Pass to the template, the compiler will automatically generate this type of function

  • Another name, ①The programming method of function template is also called general programming, because there is no specificity, ②The specific type of function is represented by parameters, and this template feature is also called parameterized type

  • How to create a function template?? Using the keywords template and typename, note that typename is also a keyword here, distinguishing our previous <typeName> This is a generalization written by ourselves for convenience

  • template <typename AnyType>//建立模板,类型是AnyType,如果你想用类class,即把typename关键字改成关键字class即可
    //函数定义声明如下
    void xjh(AnyType &a, AnyType &b)   
    {
        AnyType xjh1;     //定义声明变量xjh1是AnyType类型
        xjh1 = a;         //交换两个变量a和b的值,注意这里都是AnyType类型,可以是int double long long等
        a = b;
        b = xjh1;
    }
    int x =1000;
    int y =20000;
    xjh(x,y)
    //xjh()函数获得了两个int类型的值,所以编译器生成了函数的int版本

 

 

Function templates cannot always be used indiscriminately. Just like function overloading, function overloading is when the function performs basically the same task, and the object type is different. Function overloading can be used, while the function template is when performing the same task, if the object type Different, use function template

  • The basic same function overload tells us that it is not necessary to perform the exact same calculation method or algorithm, so function templates can also be overloaded, that is, template overloading

  • void xjh(AnyType &a, AnyType &b) The function template here, in fact, you can also call it a template function, and its signature is AnyType &, AnyType &

  • Instantiation and reification of templates

    • Including the function template itself in the code does not generate function definitions. The job of this template is only to generate function definition schemes. That is to say, when the compiler uses the template through specific types, it will get an instance of the template. This template The instance is the definition declaration of the function

    • Initialization of associative variables, then can our template initialize a type when creating the template?

 

Two-dimensional array

int data[3][4] = {
   
   {1,2,3,4}, {5,6,7,8}, {1,2,3,4}};

Looking at data first, obviously we know that data is an array name and also a pointer. The regular int data[]; means that data is an int array, and data is also a pointer to an int type.

  •  
  • What is the data here? data is a pointer, this pointer points to an array, this array is composed of 4 int type elements, namely int (*data) [4]; this is too obscure, it can also be int data[][4 ]; The meaning is exactly the same, here it shows that data is not an array but a pointer

  • I understand here, then how to pass the length of the array?

    • Obviously int data[][4] has no limit on the number of rows, but it is clear that if the number of columns is 4, that is, the length of each array pointed to by the data pointer is 4

  • Similarly, functions have no way to pass and return C-style strings. It is more appropriate to use string directly

  • Function pointer, function pointer here is handed over to pointer note record 

Operator polymorphism

Functions have overloading, that is, function polymorphism, and operators, that is, operator overloading, operator polymorphism. The overloading of the function wants you to use the same function name to complete basically the same operation.

Operators also have overloads. In fact, you have already learned them. For example, * is a multiplication sign and an address operator. The specific function is determined according to the left and right items of the operator.

We know that function overloading can be defined by itself, and the operator can actually be

How to perform operator overloading? Use operator's existing operator (parameter), here operator is a function, the difference is that you need to follow the function name immediately after the operator you need to overload, such as operator+()

//time.h
class time
{
    private:
        int hours;
        int munutes;
    public:
        time();
        time(int h, int m = 0);
        void AddMin(int m);
        void AddHr(int h);
        void Reset(int h=0, int m=0);
    
        time sum(const time & t) const;
        void Show() const;
// 加const表明,该函数只能是只读的,不能修改私有变量的值。加强安全性。
}
//endif 这里sum的参数运用了&运算符重载,即引用

//把stock::sum()函数利用运算符+的重载来实现
//time.h
class time
{
    private:
        int hours;
        int munutes;
    public:
        time();
        time(int h, int m = 0);
        void AddMin(int m);
        void AddHr(int h);
        void Reset(int h=0, int m=0);
    
        time operator+(const time & t) const;
        void Show() const;
}

When using operator+ member function, you can also use the object. operator to call the method function, or you can directly use the + operator to operate the function

int main()
{
    total = coding.operator+(fixing);
    total1 = coding + fixing;
}

 

Guess you like

Origin blog.csdn.net/Mrsherlock_/article/details/109487436