Note: Hou Jie's article titled exploring the second version of MFC
Static members (variables and functions)
I think you already know that if you generate three objects based on a class, each object will have a member variable. Sometimes this is not what you want. Assume that you have a class specifically used to process a deposit account. It should at least have the name, address, deposit amount, interest rate and other member variables of the Account:
Class savingaccount
{
PRIVATE:
Char m_name [40]; // name of the account
Char m_addr [60]; // inventory address
Double m_total; // deposit amount
Double m_rate; // Interest Rate
...
};
This row library uses floating interest rates. The interest of each account is calculated based on the listed interest rate on the current day. At this time, m_rate is not suitable for a piece of data in each account object. Otherwise, it takes a lot of time to change the m_rate value when all the account content is called out every day. M_rate should be independent of each object and become unique data of the class. How? Add the static modifier before m_rate:
Class savingaccount
{
PRIVATE:
Char m_name [40]; // name of the account
Char m_addr [60]; // inventory address
Double m_total; // deposit amount
Static double m_rate; // Interest Rate
...
};
Static member variables are not part of objects but part of classes. Therefore, programs can process such member variables before any objects are generated. But first you must initialize it.
Do not schedule the initialization action of static member variables in the class constructor, because the constructor may be called repeatedly, but the initial value of the variable should be set only once. Do not arrange initialization actions in the header file, because it may be included in many places, so it may be executed many times. You should set the initial value in the implementation file and any location other than the class. For example, in Main, global function, or outside of any function:
Double savingaccount: m_rate = 0.0075 ;//
Set the initial values of static member variables
Void main (){...}
In this case, was m_rate a private data? It doesn't matter. When the initial values of static member variables are set, they are not subject to any access permissions. Note that the type of static member variables also appears in the Initial Value Setting sentence, because this is an initial value setting action, not an assignment action. In fact, static member variables are defined at this time (rather than in the class Declaration. If you do not perform this initialization, a link error occurs:
Error lnk2001: unresolved external symbol "Private: static double
Savingaccount: m_rate "(? M_rate @ savingaccount 2ha)
The following is a way to access static member variables. Note that no object entity has been generated yet:
// The first access method
Void main ()
{
Savingaccount: m_rate = 0.0075; // to set this row, change m_rate to public.
}
In this case, an object is generated and the static member variable is processed through the object:
// Method 2
Void main ()
{
Savingaccount myaccount;
Myaccount. m_rate = 0.0075; // to set this row, change m_rate to public.
}
You have to understand the concept that static member variables are not implemented because of the implementation of objects. They already exist. You can imagine them as a global variable. Therefore, the first method does not give a false impression in the sense.
As long as the access level permits, any function (including global function or member function, static or non-static) can access static member variables. But if you want to access the private static member variable of the class before generating any object, you must design a static member function (such as the following setrate ):
Class savingaccount
{
PRIVATE:
Char m_name [40]; // name of the account
Char m_addr [60]; // inventory address
Double m_total; // deposit amount
Static double m_rate; // Interest Rate
...
Public:
Static void setrate (double newrate) {m_rate = newrate ;}
...
};
Double savingaccount: m_rate = 0.0075; // set the initial value of the static member variable
Void main ()
{
Savingaccount: setrate (0.0074); // directly call the static member function of the class.
Savingaccount myaccount;
Myaccount. setrate (0.0074); // call the static member function through an object
}
Since a static member function can be called and executed without any object, the compiler does not add a this pointer to it. Because of this, the static member function cannot process non-static member variables in the class. Remember, as I said before, the reason why a member function can process data of each object in a single copy of the function code is not disordered. It depends entirely on the instructions of the this pointer.
The static member function does not have this parameter, which is exactly what our MFC application needs when preparing the callback function. In the Hello world example in chapter 1, I will introduce such an instance.