Abstract: This article is a reflection on the previous post of bbs c/C ++. When I saw the post, I suddenly felt that I had timed out. It seems that I am getting unfamiliar here. This article attempts to discuss how the access control operator works, how to use it, and how to understand it.
The original post is as follows: 1 # include <iostream>
2 using namespace STD;
3
4 Class {
5 public:
6 A (int I _, Int J _)
7 {
8 I = I _;
9 J = J _;
10}
11 void disp (A &)
12 {
13 cout <a. I <Endl <a. j <Endl;
14}
15
16 private:
17 int I;
18 protected:
19 Int J;
20 };
21
22 int main (INT argc, char * argv [])
23 {
24 A (123,456 );
25 a B (789,543 );
26 A. disp (B );
27 B. disp ();
28
29 return 0;
30}
At first glance, there may be questions. Why is there a bug?
After careful consideration, we can actually look at classes and objects like this:
Classes encapsulate data members and a series of operations (member functions) on them. Note: the member function can operate on data members (the data member in the class can be called a wildcard data member )!
Objects are class instantiation. How can we understand instantiation? In fact, each instance object is only initialized to the data member. In the memory image, each object only retains its own copy of the data member. The member functions are shared for the entire class, that is, a class retains only one member function.
So how does an object relate to a member function that can be considered as "separated", that is, how does a member function operate on the data member of an object? Remember this pointer, regardless of whether the object passes through (.) operations or (->) Operations call member functions. during compilation, the compiler converts such calls into common global functions, and there is an extra parameter (usually the first parameter), and then the this pointer is passed into this parameter. Therefore, the binding (or contact) between the object and the member function is completed ).
After instantiation, multiple different objects of the same class are obtained. Since member functions are shared, member functions can operate on the data members of objects.
The problem is that there are multiple objects. The member function needs to know which object is operated as a data member?
For example, objects obj1 and obj2 both belong to Class A, and Class A has the public member function Foo ()
If obj1 calls this function, it will pass the this pointer to the foo function during compilation. The members operating on obj1 in obj1 and foo do not need any modification and access directly, because the data members are automatically found based on the this pointer.
If obj1 calls this function, it can also access data members of other similar objects! So what you need to do is to let the foo function know which object is a data member of the same class object. One solution is to pass in pointers or references of other similar objects, you can operate on data members of other similar objects.
Foo (A & OBJ)
And then call:
Obj1.foo (obj2)
You can access the data members of obj2 in obj1, regardless of whether the data members are private or protected.
Moving out of the C ++ object model, you can draw the memory map of each object to see more clearly:
Conclusion: the access modifier of C ++ takes the class as the unit, rather than the object as the unit.
In general, similar objects can access each other's data members, but the access path is not direct access.
Step: Call the public member function of an object, this member function can access public/private/protected data members and member functions of its own or similar objects (all objects of the class are shared ), in addition, you need to specify the data member of the object (the member of the object that calls the function does not need to specify it, because this pointer exists; the data member of other objects can indirectly specify it through reference or pointer)
Summary of public, protected, and private access in C ++
1. Access scope of the private, public, and protected methods (under the Public inheritance)
PRIVATE: It can only be accessed by functions in the class and their meta-functions. It cannot be accessed by any other function, nor can it be accessed by objects in the class.
Protected: it can be accessed by functions in the class, sub-class functions, and their friends functions, but cannot be accessed by objects in the class.
Public: can be accessed by functions in the class, sub-class functions, and their friends functions, or by objects in the class.
Note: youyuan functions include two types: global functions set as youyuan and member functions in youyuan class.
Second, method property changes after class inheritance:
Using private inheritance, all methods of the parent class are changed to private in the subclass;
Using Protected inheritance, the protected and public methods of the parent class are changed to protected in the subclass, and the private method is not changed;
Using Public inheritance, the method attributes in the parent class are not changed;
|
Public: |
Protected: |
PRIVATE: |
Public inheritance |
Public |
Protected |
--- |
Protected inheritance |
Protected |
Protected |
--- |
Private inheritance |
Private |
Private |
--- |
Protected inheritance and private inheritance can reduce Access Permissions
Again, the subject of the access behavior that can be provided is "function ".
There is no access restriction on the class body, that is, the private function can access the public/protected/private member function or data member. Similarly, the protected function, the public function can also access the Members defined in this class.
Under Public inheritance, the public and protected members in the base class inherit from the public and protected members (member functions or data members) of the subclass, and then the access is still unrestricted within the class.
Access to member functions within the scope of a category is not restricted. In the case of inheritance, the base class private member still inherits from the derived class, but it cannot be accessed directly, even in the class, not to mention the class object. You can see through the following example: 1 # Include < Iostream > 2 Using Namespace STD; 3 4 Class C { 5 Public : 6 C ( Int Val): M_c (VAL ){} 7 Private : 8 Int M_c; 9 }; 10 11 Class D: Public C { 12 Public : 13 D ( Int Val1, Int Val2): C (val1), m_d (val2 ){} 14 Int M_d; 15 }; 16 17 Int Main () 18 { 19 20 21 Cout < Sizeof (C) < " " < Sizeof (D) < Endl; // 4 8 22 D OBJ ( 2 , 25 ); 23 Cout < & OBJ < " " < & OBJ. m_d < Endl; // 0x0012ff78 0x0012ff7c 24 // Cout <obj. M_c; // Error, cannot access 25 26 D * PTR = & OBJ; 27 Int * Iptr = ( Int * ) PTR; 28 Cout < * Iptr < " " < * (Iptr + 1 ) < Endl; // 2 25 29 30 Return 0 ; 31 } 32 33 Similarly, by adding a virtual function, you can see that the VC compiler places the vptr at the beginning of the Data zone. |
The following is an article from the blog Park, with a very incisive understanding:
The following question is taken from a forum post:
Three classes O, P, and q are known. Class O defines a private method F1, a public method F2, and a protected method F3: class P and class Q are derived classes of Class O. The Inheritance Method is as follows:
Class P: protected o {...};
Class Q: Public o {...};
The correct description of method F1 is ___ (34) ___; the correct description of method F2 is ___ (35 )___; which of the following statements about method F3 is correct? ___ (36 )___.
(34)
A. Method F1 cannot be accessed
B. Method F1 can be accessed only within Class O
C. Method F1 can be accessed only within Class P
D. Access Method F1 only within Class Q
(35)
A. Objects of Class O, P, and Q can access the F2 method.
B. Objects of the p and q classes can access the F2 method.
C. Objects of the Class 0 and Q can access the F2 method.
D. Access Method F2 only within Class P
(36) A. Objects of Class 0, P, and Q can access method F3.
B. Objects of the 0, P, and Q classes cannot access method F3.
C. Objects of the Class 0 and Q can access the method F3.
D. Objects of the class p and q can access method F3.
Is there any way to simply remember these many rules? The following describes a method that you do not need to remember.
As the name suggests, private/public/protected indicates private/public/Protection respectively. They are a group usedAccess permissionControl keywords. First, the key point to be clarified is:Control who is authorized to access? Who is the subject of this access? Who is the object (subject?
We often hear this saying:
1) A ClassYouyuanYou can access anyMember(Including member variables and member methods, the same below ).
2) PrivateMemberOnly this class can be accessed, protectedMemberOnly the class and its derived class can be accessed, publicMemberAll users can access the service.
It is clear who the object (subject) is.Member(Including member variables and member methods ).Who is the subject? This is the key to obfuscation. It is also vague in this statement.
To be clearSubject)Refers toFunctionInsteadClass(Not a variable, of course ). Private/public/protected:A function)ForClass member (including member variables and member methods). Therefore, the complete statement is:
1) A ClassYouyuan (including all member functions of youyuan function or youyuan class)You can access anyMember(Including member variables and member methods ).
2) except for friends, privateMemberOnlyMember functions of this classAccessible, protectedMemberOnly the member functions of this class and Their Derived classes can be accessed, publicMemberAll functions are accessible.
That is to say, when we say that a class can access XXX, it actually impliesMember functions of this classYou can access XXX. After understanding this and adding an obvious rule, it is not difficult to answer the above questions. This rule is:
3) when the derived class inherits, the access permission of the member can be weakened (modified by protected/private ). For example, the above example class P: protected o {...}; When a function accesses a member in O through class P, this function has only the protected permission for the Public Member in Class O.
Supplement: There is a technology called member spy (class member spyware). Through this technology, a derived class can be used to change the protected member of the base class to the public permission. This technology uses the using keyword. Example:
Class
{
Protected:
Int m_data;
};
Class spya: public
{
Public:
Using a: m_data;
};
Void testspy (A * pA)
{
Spya * pspya = static_cast <spya *> (PA );
// Forcibly convert a to spya, which requires that spya has no member variables and does not overload the virtual function in.
// Now you can access m_data through pspya. For example, int DATA = pspya-> m_data;
}
Because this technology uses forced type conversion, use it with caution.
Question: define a class by yourself. It has only one data member and is private. Its member functions are all public. It generates two objects: obj1, obj2, first, we need to use the least member function to implement obj1 to access the private data member of obj2.
Implementation 1: