How to design a class The can ' t be inherited (C + +)

Source: Internet
Author: User

encapsulation, inheritance and polymorphism are the three main features of object-oriented, and recently thought about how to design a class that cannot inherit. 

C + + There are many ways to implement a class that cannot be inherited. Use friends, private constructors, virtual inheritance, and so on to make a class impossible to inherit, but why must it be a virtual inheritance? What is the principle behind it?

~ The constructor is set to private okay.

Because of that, the subclass has no way to access the constructor of the base class, thereby preventing the implementation of the task of constructing the object of the subclass and achieving the non-inheritable purpose.

But, suppose so, how do we use this class in other places? The use of such a child has also created some obstacles.

All right. Do you also think of defining a static method, implementing an object inside the method, and then returning its pointer.

Ok? How do you release it? Then design a free memory function, the problem will be solved.

Ok. Follow this logical analysis. The sample code is as follows:

Click (here) to collapse or open

  1. #include <iostream>
  2. using namespace Std;
  3. Class A
  4. {
  5. Public
  6. Static A * CONSTRUCT (int n)
  7. {
  8. A *pa = new A;
  9. pa->num= N;
  10. cout<< "num is:" <<pa->num<<endl;
  11. Return PA;
  12. }
  13. static void Destruct (A * pintance)
  14. {
  15. Delete pintance;
  16. Pintance = NULL;
  17. }
  18. Private
  19. A () {}
  20. ~a () {}
  21. Public
  22. int num;
  23. };
  24. void Main ()
  25. {
  26. A *f = a::construct (9);
  27. cout<<f->num<<endl;
  28. A::D estruct (f);
  29. }

Well, this class is like this. According to our theoretical analysis, the results of our practice are fully established.

But, this question, it is more challenging, what does it mean? Do not you find that we are only qualified for the interview, but also can not be an exception to hire.

What's wrong? You might ask me. Don't you really understand? Sure you don't see it? If it is true, then I will tell you!

Our class cannot be implemented to create objects on the stack. That is, only one object can be built on the heap, and there is nothing on the stack.

The great limitations of private constructors are so sweeping.

All right! We modify it, so-called "patch Bar" for it, see the sample code:

Click (here) to collapse or open

#include <iostream>

using namespace Std;

Template <typename t>

Class Base

{

Friend T;

Private

Base () {}

~base () {}

};

Class Finalclass:virtual Public base<finalclass>

{

Public

Finalclass () {}

~finalclass () {}

};

void Main ()

{

Finalclass *p = new Finalclass; Objects on the heap

Finalclass FS; Object on Stack

}

    Ok. Now look at our Finalclass class.

    Inherits from Base,base as a virtual base class, because it is a friend of base, so it can access the private constructors of the base class, as well as the destructor. The compile run time is correct.

    That is, you can create objects on the heap, and you can build objects on the stack.

    Can it be inherited? If it is inherited by a class as a base class, it can be fully passed at compile time.

    There is no doubt about this, the problem is at runtime:

    When a subclass constructs an object, because it is a virtual inheritance, the constructor of the subclass directly calls the constructor of the base class, and the constructor of base is private. Run Error error!!!

    This is a class that really cannot be inherited.

    idea two: The main idea is that the subclass cannot construct the part of the parent class, and there is no way for the class to instantiate the entire subclass. This restricts the inheritance of subclasses. So we can declare the parent class's constructor private, but so that the parent class cannot be instantiated and continue to think 、、、
       we can take advantage of the characteristics of friends who cannot be inherited!
    The first hypothesis is that cparent cannot be inherited. Let Cparent is a class of friends and subclasses, Cparent can be constructed, but Cparent subclass Cchild cannot inherit that friend attribute, So we can not be constructed. So we introduce a cfinalclassmixin.
     This is what we expect from the functionality of this class:
    Any class inheriting from it cannot be instantiated, and the class itself does not want it to be instantiated.
    It is OK to implement a constructor and destructor that are private classes. At the same time, we declare our cparent as friends in this category. The code is as follows:
    Class Cfinalclassmixin
    {
    Friend class Cparent;
    Private
    Cfinalclassmixin () {}
    ~cfinalclassmixin () {}
    };
    Our cparent code should look like this:
    Class Cparent
    {
    Public
    Cparent () {}
    ~cparent () {}
    };
    This class (note, at this point it can still be inherited), and now we need it to not be inherited. So just change the code to
    Class Cparent:public Cfinalclassmixin
    {
    Public
    Cparent () {}
    ~cparent () {}
    };
    On the line. Now inherit a subclass from Cparent try
    Class Cchild:public cparent{};
    Compile the code to try to find: unexpectedly no effect!!
    Now think back to the reason we're doing this, which is the idea that the parent class has access to the constructor of the Mixin class, but the subclass cannot access it.
    Now look at our code and discover that the parent class is a friend of the Cfinalclassmixin class and can access its constructors. Because friends cannot inherit, Cchild cannot access Cfinalclassmixin's constructors. So it should not be instantiated.
    Cchild does not have access to the Cfinalclassmixin constructor, but it does not have to call it! I think that's the reason for the problem. Cchild is constructed by cparent to Cfinalclassmixin, so this friend is useless to him!
    Now the problem is found. It's easy to solve. Just let Cchild have to call Cfinalclassmixin's constructor, so how do you get there?
    Do you remember the virtual inheritance?a feature of virtual inheritance is that the constructor of the virtual base class is constructed by the final subclass!Therefore, the cparent from the Cfinalclassmixin inheritance to inherit from the Cfinalclassmixin virtual. The code is as follows:
    Class Cparent:virtual Public Cfinalclassmixin
    {
    Public
    Cparent () {}
    Cparent () {}
    };
    Try it now, all right.
    But maybe some people will be afraid of multiple inheritance! But there's no need for us to be so worried! Because our Cfinalclassmixin class is pure!pure! That means it doesn't have a member variable at all! Then we don't have to worry about the biggest problem of multiple inheritance. Data redundancy resulting from diamond inheritance. and ambiguity.
    There's still a shortage! That's why we can't use this cfinalclassmixin class every time. Add a friend statement to a class! That's a lot of trouble! Although it is not a big problem, but I think it is to solve, because I fully trust c++!
    The solution is also very simple! That's the use of templates! The specific description is omitted, and the code is given. you'll see.
    Here is the complete code for my test program (where the cfinalclassmixin has been changed to a template)

    #include "stdafx.h"
    #include <iostream>
    using namespace Std;

    Template<class t>//Application Template
    Class Cfinalclassmixin
    {
    Friend T;

    Private
    Cfinalclassmixin () {}
    ~cfinalclassmixin () {}
    };


    Class Cparent:virtual Public cfinalclassmixin<cparent>//virtual inheritance
    {
    Public
    Cparent () {}
    ~cparent () {}
    };

    Class Cchild:public cparent{}; Subclass Inherits Parent Class

    int main (int argc, char* argv[])
    {
    Cparent A; Can construct
    Cchild b; Cannot construct
    return 0;
    }

    Now just add a cfinalclassmixin mixed class to the class that you don't want to inherit as a parent class.
    By restricting constructors, we achieve the goal of restricting inheritance. But there are some exceptions to this, such as classes that are all static functions. These classes themselves do not need to be constructed. So we have no way of doing it. But in most cases, a class that is full of static functions implies that the design of the program itself may need to be considered.
    In fact, this is just a small example of the use of the Mixin class (mixed Class). There are many other uses, such as Uncopiale and so on. Don't say much. What I would like to say is that we may be more disgusted with multiple succession. But too much negation is not worth the candle. It is still at the stage of debate over whether multi-inheritance should be used or not. I think a method is used properly, the key is to use the person.




How to design a class The can ' t be inherited (C + +)

Related Article

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.