Design a class based on the characteristics of the class (cannot be inherited, can only create objects on the stack/heap)

Source: Internet
Author: User
One, design a class cannot be inherited

Method 1:
Using static member functions ...
Since a class cannot be inherited, that is, the constructor of the class cannot be accessed by the outside world, the constructor and destructor of the class need to be declared private,
Any non-static member variable or function that calls a class requires an object to invoke (the this pointer is required), but we cannot directly create objects of that class in the outside world.
So I think of the advantages of static member variables and functions, no object can be called, so we can define a static member function, within the static function to complete the creation of the object,
The object that is created is then returned, so that we can get the object of the class by invoking its static member function outside the class by using the scope qualifier of the class.

But there is a flaw in this approach: the objects created are created on the heap. Objects cannot be created on the stack.
The code is as follows:

Design a class cannot be inherited
class SealedClass1
{public
:
    static sealedclass1* Getinst () {return  New SealedClass1 ();

    }

    static void Destory (Sealedclass1* p)
    {
        if (p)
        {
            delete p;
            p = NULL;
        }

Private:
    int _a;
    SealedClass1 ()
        : _a (0)
    {}
    ~sealedclass1 ()
    {}
};

Method 2.:
Can you design a class that is functionally different from the general class and cannot be inherited?
References: Virtual inheritance

Requires a secondary class (TMP) to declare both its constructors and destructors as private. It then designs a class sealedclass that cannot be inherited (the class is virtual inheriting the helper Class), and the class must also be a friend of the helper class, so that the class can invoke the constructor of the helper class.

Now suppose that the class sealedclass that we are designing can be inherited by Class C, and since the Sealedclass class is a virtual inheritance of the TMP class, then Class C must be able to invoke the TMP constructor, which can be derived from the object model of Class C, and because Class C is not a friend of the TMP class. So class C cannot directly call the constructor of the TMP class, so the class Sealedclass cannot be inherited.

Class Sealedclass;

Class TMP
{public
:
    friend Sealedclass;
Private:
    Tmp ()
        : _a (0)
    {}
    ~tmp ()
    {}
    int _a;
};

Class Sealedclass:virtual public Tmp
{public
:
    sealedclass ()
        : _b (1)
    {}

    ~sealedclass ()
    {}
private:
    int _b;
};

Class C:p ublic sealedclass
{public
:
    C ()
        : _c (3)//There is a compilation error
    {}
private:
    int _c;
};

In C + +, the object of a class is set up into two types:
One is statically established: such as A;
The other is dynamic establishment: such as a * ptr=new A;
There is a difference between the two ways.

The static establishment of a class object, is the compiler for the object in the stack space allocated memory, is by directly moving the top of the stack pointer, move out the appropriate space, and then in this memory space call the constructor to form a stack object. Using this method, you call the constructor of the class directly.

Dynamically establishes class objects, using the new operator to build objects in heap space. This process is divided into two steps:
The first step is to execute the operator new () function, searching the heap space for the appropriate memory and allocating it;
The second step is to invoke the constructor constructor to initialize the memory space. This method indirectly invokes the constructor of the class. second, design a class can only create objects on the heap

Ideas:
It is easy to think of a constructor as private. After you make a constructor private, you cannot call the constructor outside of the class to construct the class object, you can only use the new operator to create the object.
However, the execution of the new operator is divided into two steps:
① calls the operator new () operator to open up space for an object on the heap;
② calls the object's constructor to construct an object on the heap for the space that it opens up for the object.
Obviously, the ② step is to call the object's constructor, so this method is not possible.

When an object is built on top of the stack, the compiler allocates the memory space, calling the constructor to construct the Stack object. When the life cycle of an object is nearly over, the compiler calls the destructor to release the space occupied by the stack object.
The compiler manages the entire lifecycle of the object. What would happen if the compiler could not invoke the destructor of the class. For example, the destructor of a class is private, and the compiler cannot invoke a destructor to free memory.

So, when the compiler allocates stack space for class objects, it first checks the accessibility of the destructor of the class, not just destructors, but the compiler checks as long as it is a non-static function. If the destructor of the class is private, the compiler does not allocate memory for the class object on the stack space.

Therefore, the destructor is set to public, and the class object cannot be built on the stack.

Class A
{public
:
    A (int x = 0)
        : _a (x)
    {}

    void Destory ()
    {
        Delete this;
    }

Private:
    ~a ()
    {}
    int _a;
};

When an object is created on the stack (A;), the compiler complains that the destructor is inaccessible outside of the class.
But there's a problem, it looks strange, the object created with new is not released with delete, and if you use Delete to release the object, you'll find that it doesn't work at all, because the delete does two things when it frees up object space:
① calls the destructor of the class to clean up the object space;
② calls operator delete () to free up space for the object.
Because destructors are protected and cannot be accessed outside of a class, you cannot use this method to free up space for objects.

So we think of an interface function that can invoke a class to create an object on the heap, and then call an interface function to free up the object's space.
As we all know, calling a Non-static member function in a class requires a class object, so the interface function needs to be declared static.

Class A
{public
:
    static * Getinst ()
    {return
        new A ()
    }

    void Destory ()
    {
        Delete this;
    }

Protected:
    A (int x = 0)
        : _a (x)
    {}

    ~a ()
    {}
    int _a;
}
third, design a class can only create objects on the stack

By the analysis of the above question, we know that to make an object can only be created on the stack, that is, can not create objects on the heap, that is, you can not use the new operator in the heap space to new object, it is OK to disable the new operator, which is good to do, overload a operator new (), Private when the overloaded function is set.

Class A
{public
:
    A (int x = 0)
        : _a (x)
    {}

    ~a ()
    {}

private:
    void* operator New ( size_t N)
    {return
        NULL;
    }

    void operator Delete (void* p)
    {}

    int _a;
};

Summary:
1. Design can not be inherited classes, need to take into account the object model;
2. Only create objects on the stack, restrict the access of destructors to subscript character or protection;
3. Objects can only be created on the heap so that the new operator cannot be used outside the class to open up space on the heap.

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.