Fundamentals of C + + (IV)
C + + classes (Continued)
Think: the code style written before is not good. As a rule, the class function declaration should be placed inside the class, but the definition should be placed in the cpp file, while the class declaration should be placed in the header file, which makes the code look more neat and clear.
From this section of notes, it has changed from C++Primer to C++PrimerPlus 😁.
1, Create a new class
1. Create a new class in the header file
class Stock { private: std::string company; long shares; double share_val; double total_val; void set_total() { total_val = shares * share_val; } public: void acquire(std::string& co, long n, double price); void buy(long num, double price); void sell(long num, double price); void update(double price); void show(); };
In addition, although there is no order requirement between public and private, it is better to write private first. The internal members of private represent some basic properties of the class. In this way, you can start from the bottom structure and put the interface public behind.
Here, the interface member function is only declared, not defined here. Note: public members can also be accessed by other code outside the class, but private members only allow access or operation by member functions inside the class. Data items are usually placed in the private section as private members
2. Define class member functions in files outside the class
When defining a class member function outside a class, you need to use the domain resolution operator (::) in front of the function name to identify the class:
void Stock::acquire(std::string& co, long n, double price) { ; }
Next, define the class member function in the stock.cpp file. Note that the file should contain the class header file.
#include<iostream> #include"Stock.h" using namespace std; void Stock::acquire(const std::string& co, long n, double price) { company = co; if (n < 0) { std::cout << "Number of share can't be negative" << endl; shares = 0; } else shares = n; share_val = price; Stock::set_total(); } void Stock::buy(long num, double price) //Buy stock function { if (num < 0) { ;// Handling exceptions } else shares += num; } void Stock::sell(long num, double price) { if (num<0) { ;//Handling exceptions } else if (num > shares) { ;//Handling exceptions } elseneil { shares -= num; share_val = price; set_total(); } } mei void Stock::update(double price) {n share_val = price; set_total(); } void Stock::show() { cout << "company:" << company << endl; cout <<"Shares:"<< shares << endl; cout << "Share_price:" << share_val << endl; cout << "Total_worth:" << total_val << endl; }
The functions defined in the class internal declaration will be called inline functions, and the set in the class declaration_ The total () function is an inline function. Class declarations usually use short member functions as inline functions. If you want to define a function outside the class but also make it an inline function, you need to use the inline qualifier.
inline Function name; (inside the class) inline Function name { Function body; }((outside class)
3. Use of classes
To use a created class, you must first create a class object. Personal understanding is that the class is actually more like a template. The class object we create has all the characteristics and functional attributes of the class, but the difference between different class objects is that the internal data may be different.
Stock num1; Stock num2; Stock num3; num1.acquire("Super", 100, 2.333); num1.buy(10000, 23.1); num1.sell(5353, 90); num1.show();
Create three objects, demonstrate the operation of the first object, and call all functions of the class interface.
2, Class constructor and destructor
As mentioned in the previous section, the constructor of class is used to initialize data members. If you do not write your own constructor when creating a class, the compiler will use the default constructor. However, the compiler will issue a warning: member variables are not initialized.
1. Define a self-defined constructor
**The name of the constructor is fixed and needs to be consistent with the class name** When you create a class object, the constructor is called automatically. The parameters of the constructor do not represent class members, but the values assigned to class members. Therefore, the parameter name cannot be the same as the class member name. In order to avoid this problem, it is common to add m before the data member_ Prefix.
private: std::string company; long m_shares; double m_share__val; double m_total_val; void set_total() { m_total_val = m_shares * share_val; }
Change data member name
tips: change the name. Don't find each variable and change it yourself. Right click the variable name and choose Rename. VS will automatically help you match the variables in all locations and then replace them with a new name.
Here, by changing the original acquire() function to a constructor, you can initialize the variables in the class object when it is created, instead of calling the function initialization.
Class external definition:
Stock::Stock(const std::string& company, long shares, double share_val) { m_company = company; m_shares = shares; m_share_val = share_val; }
Class internal declaration:
class Stock { private: std::string m_company; long m_shares; double m_share_val; double m_total_val; void set_total() { m_total_val = m_shares * share_val; } public: Stock(const std::string& company, long shares, double share_val); void buy(long num, double price); void sell(long num, double price); void update(double price); void show(); };
After the constructor is created, you need to enter the initialization parameters when creating the class object.
Stock num1("super", 14,6.77); Stock num2; //Wrong.
There are two ways to use constructors:
Stock num1("super", 14,6.77); //Implicit initialization Stock num2 = Stock("hello", 2324, 9.345); // Explicitly call constructor
More commonly used (with forced lattice) creation methods. New is used together with constructor and pointer to create new objects:
Stock* pnum = new Stock("nice", 232, 9.232);
This statement creates a Stock object, initializes it to the value provided by the parameter, and assigns the address of the object to the pointer. In this case, the object has no name, but the pointer can be used to manage the object.
Myth: calls to non default constructors
Stock num1("hhh", 1, 2); //Constructor Initializers Stock num2(); //Does not represent a constructor, //Instead, the return value type of num2 is the Stock class. //If num2 is a parameterless constructor, you should use the following declaration. Stock num2;
2. Destructor
After creating an object with a constructor, the program is responsible for tracking the object until it expires. When the object expires, the program will automatically call a special member function, the destructor.
The destructor is used to clean up, so it is actually very useful. For example, if the constructor uses new to allocate memory, the destructor will use delete to free memory. Since the Stock class does not use new to allocate memory, and we do not write a destructor (in fact, the destructor does nothing for the above Stock class), the compiler will automatically give a default destructor.
How to create a destructor:
~Class name (){ Function body;}
Destructors that do nothing can also be written in inline function format or not (because they do nothing, the compiler will provide a default destructor).
When a destructor is called is determined by the compiler and should not normally be shown in the code.