Explain how to set the access rights of a constructor or destructor to the Private_c language in C + +

Source: Internet
Author: User

Today's interview was asked about the technical tools commonly used in this single case pattern, which is analyzed below:
        In many cases requires that there be only one object in the current program. For example, a program has only one connection to the database, and only one mouse object. We usually place the declaration of a constructor in the public sector, what happens if we put it into the private sector? What does that mean?
        When we declare an object in a program, the compiler is calling the constructor (if any), and the call is usually external, That is, it is not a call to the class object itself, and if the constructor is private, it will cause a compilation error because it is not allowed to access private members outside of class.
        However, for class itself, you can take advantage of its static public members because they are independent of class objects and can be used without having to produce objects.
        at this point because the constructor is privatized by class, we must be able to access the private domain of class if we want to create an object That only members of class can do it, but how can we use its members before we construct the object? Static public member, which exists independently of the class object, and "we" can access it. If you create an object of that class in a static function and return it as a reference or as a pointer (this is not returned as an object, the main constructor is private, and the outside cannot create a temporary object), the right to use the object is obtained.
Here's an example:

Class Onlyheapclass 
{public 
: 
  static onlyheapclass* getinstance () 
  { 
    // Creates a Onlyheapclass object and returns its pointer return 
    (new Onlyheapclass); 
  void Destroy (); 
Private: 
  Onlyheapclass () {} 
  ~onlyheapclass () {} 
}; 
 
int main () 
{ 
  Onlyheapclass *p = Onlyheapclass::getinstance (); 
  ..//Use *p 
  delete p; 
  return 0; 
} 


This example uses a private constructor, getinstance () as a static member function of Onlyheapclass to create an object in memory: Because you want to pass across functions and cannot use value delivery, we choose to create objects on the heap so that even the getinstance () Exits, the object is not released, and can be released manually.
The design of classes that privatize constructors ensures that other classes cannot derive from this class or create instances of classes. There is another use: for example, to implement such a class: it has at most one in memory, or a specified number of objects (you can add a static type counter in the private domain of Class) , its initial value is set to 0, and then in the getinstance () to make some restrictions: each time you call it to check whether the value of the counter has reached the upper limit of the number of objects, if it is an error, otherwise the new object, The value of the counter is also increased by 1. Finally, to avoid a new copy of the object when the value is replicated, the copy constructor is specifically declared and private, in addition to the constructor being private.
If you design a constructor as protected, you can achieve the same purpose, but you can be inherited.
How else do you guarantee that you can only have a new class object on the heap? Simply define the destructor as a private member.
The reason is that C + + is a statically bound language. All non-virtual function calls must be parsed during the compilation process. Even virtual functions need to check for accessibility. As a result, when an object is generated on the stack, the object is automatically destructor, which means that the destructor must be accessible. And the generation of objects on the heap, because the time of the destructor is controlled by the programmer, the destructor is not necessarily required. To ensure that an object cannot be generated on the stack, it is necessary to prove that it can be generated on the heap. The only difference between the Onlyheapclass and the general object is that its destructor is private. The delete action invokes the destructor. So it can't be compiled.
So how do you release it? The answer is also simple, providing a member function that completes the delete operation. In a member function, destructors are accessible. Of course the Detele operation can also be compiled through.

void Onlyheapclass::D Estroy () { 
  delete this; 
} 

The class design for the privatization of constructors guarantees that objects can only be generated in the heap with the new command, only dynamically to create objects, so that the object's lifecycle can be controlled freely. However, such a class would need to provide a public interface for creation and revocation.
In addition, overload delete,new for private can achieve the purpose of requiring objects to be created on the stack, with placement new can also be created on the stack.

Add:
1. Why should you call it yourself? Does the destructor automatically be invoked when an object ends its lifetime? When do you need to call the destructor yourself?
In a situation like this, you want to do something before you deconstruct it, but you don't know it by your class, so you can write a function that takes all the things you need to do and then calls the destructor. So that people can only call you the function of the destructor, so as to ensure that before the destructor will do your required action.

2. Under what circumstances would it be useful to give birth to only a pile of objects?
The heap object is new, relative to the Stack object. Under what circumstances to new, under what circumstances in the stack in advance allocation, nothing but is when to use dynamic, when the problem of static generation. This should be based on the specific situation of specific analysis. For example, in a function where you know beforehand that an object can be up to 10, you can define an array of objects. 10 elements, each element is a stack object. If you cannot determine the number, you can define a pointer to the object, create it when it is created, and use a list or vector to manage it.

The meaning of the "private" permission in a class is that private members can only be accessed within the class domain and cannot be accessed outside the class.

The definition of a destructor as private prevents the user from using the destructor outside the class. This is manifested in the following two areas:

1. Users are not allowed to define variables of this type, that is, to prevent the creation of objects of this type in the stack memory space. To create an object, you can only use new on the heap.

2. Prevent users from using delete in the program to delete this type of object. The deletion of an object can only be implemented within a class, meaning that only the implementation of the class can implement the delete of the object, and the user cannot delete the object arbitrarily. If a user wants to delete an object, it can only be done according to the method provided by the class's implementation.

Visible, this greatly limits the user's use of this class. Generally do not do this; this is usually done to achieve a specific purpose, such as in the implementation of Singleton.

PS: Why constructors cannot be virtual functions
In addition, the difference between a constructor and a virtual function:
1. From the storage space point of view, the virtual function corresponds to a pointer to the vtable virtual function table, which we all know, but this pointer to vtable is actually stored in the object's memory space. The problem comes out, if the constructor is virtual, it needs to be called through vtable, but the object has not been instantiated, that is, the memory space has not yet, how to find vtable? So the constructor cannot be a virtual function.
2. From the angle of use, the virtual function is mainly used in the case of incomplete information, can make the overloaded function get the corresponding call. The constructor itself is to initialize the instance, and there is no practical meaning to use virtual functions. So constructors are not necessarily virtual functions. The function of a virtual function is to call it through a pointer or a reference to a parent class, which can become the member function of the calling subclass. Constructors are called automatically when an object is created, and cannot be invoked through a pointer or a reference to a parent class, and therefore the constructor cannot be a virtual function.
3. Constructors do not need to be virtual functions, it is also not allowed to be a virtual function, because we always specify the type of the object when we create an object, although we may access it through a pointer or reference to the base class of the lab, but destructors do not necessarily, and we often destroy the object through a pointer to the base class. At this point, if the destructor is not a virtual function, the object type cannot be correctly recognized and the destructor is not correctly invoked.
4. From an implementation perspective, VBTL is created after a constructor call, thus a constructor cannot be a virtual function. From the actual meaning, it is not possible to determine the true type of the object when invoking the constructor (because the subclass will tune the constructor of the parent class), and the constructor function is to provide initialization, only once in the object life cycle, is not a dynamic behavior of an object, nor is it necessary to be a virtual function.
5. When a constructor is invoked, one of the first things it does is initialize its vptr. Therefore, it can only know that it is the "current" class, and completely ignores whether there are successors behind the object. When the compiler generates code for this constructor, it generates code for the constructor of the class-neither a base class nor a derived class for it (because the class does not know who inherits it). So the vptr that it uses must be the vtable for this class. And, as long as it is the last constructor call, then within the lifetime of the object, Vptr will remain initialized to point to this VTABLE, but if a later derived constructor is invoked, the constructor will set the vptr to its VTABLE, And so on. Until the end of the constructor function. The state of the vptr is determined by the last constructor called. This is another reason why a constructor call is an order from a base class to a more derived class. However, when this series of constructor calls is occurring, each constructor has been set vptr point to its own vtable. If a function call uses a virtual mechanism, it will only produce a call through its own vtable, rather than the final vtable (all constructors are called to have the final vtable).

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.