1#include <iostream>2#include <string>3#include <map>4#include <vector>5#include"thread_pool.h"6 7 8 using namespacestd;9template<classT>Ten class Base{ OneFriend T;///Friend class A Private: - Base(){} -~Base(){} the }; - - classDerived: Public Virtual Base<derived> - { + Public: - derived () {} + voidShow () { Acout<<"can be instanced,but can inherited"<<Endl; at } -~derived () {} - }; - - classDderived: Publicderived{ - Public: in dderived () {} -~dderived () {} to }; + - the * intMain () $ {Panax Notoginsengcout <<"Hello world!"<<Endl; - derived D; the d.show (); + return 0; A}
View Code
As long as the constructors and destructors for Class A are defined as private types, you cannot create objects of classes outside of Class A, and you cannot inherit class A as a base class.
Because if the constructor of the base class is called when the object is built, because it is private, the derived class calls the base class constructor, and the link fails-the "cannot inherit, but we cannot define the object outside the class."
-------------
Class base{
Friend t;///Friend class
Private
Base () {}
~base () {}
};
Class Derived:public Virtual base<derived>
{
Public
Derived () {}
void Show () {
cout<< "can be instanced,but can inherited" <<endl;
}
~derived () {}
};
We can see the DriveD class virtual inheritance (!!!) This virtual can not be removed from the base class, when the template is expanded, the derived class is declared as the base class of the friend class, so it is possible to access the private part of base.
So you can call constructs and destructors that are defined as private in base, and there is no problem in defining objects of type derived.
----
Class Dderived:public derived{}
Dderived is not instantiated. Why??? < here should be a deep dive into the C + + object model of this book >.
In the C + + object model, the construction order is that the virtual base class---The base class---the virtual pointer---the statement inside the---constructor of the initialization list
In our case, the virtual base class (base)---base class (derived)---the virtual pointer---the---constructor (dderived () {}) in the initialization list.
So we can know that the constructor of the virtual base class base will be called first, but for Dderived, the constructor of base is inaccessible because the constructor of base is defined as private, and the dderived function
And ddrived is not the base of the friend class, so when using dderive constructs the object, link error, that is to say drived is not able to inherit.
The link error shown below "There should be an in-depth understanding of the C + + object Model"
|| = = = Build:debuginchRPC (COMPILER:GNU GCC compiler) ===|/home/lizhen/codeblocks/rpc/main.cpp| | In constructor ' dderived::d Derived () ': |/home/lizhen/codeblocks/rpc/main.cpp| -|error: 'Base<t>::Base() [With T = derived] ' is Private|/home/lizhen/codeblocks/rpc/main.cpp| -|error:within Thiscontext|/home/lizhen/codeblocks/rpc/main.cpp| -|error: 'Base<t>::~Base() [With T = derived] ' is Private|/home/lizhen/codeblocks/rpc/main.cpp| -|error:within Thiscontext|/home/lizhen/codeblocks/rpc/main.cpp| | In destructor ' dderived::~dderived () ': |/home/lizhen/codeblocks/rpc/main.cpp| -|error: 'Base<t>::~Base() [With T = derived] ' is Private|/home/lizhen/codeblocks/rpc/main.cpp| in|error:within Thiscontext| | | = = = Build failed:6Error (s),0Warning (s) (0Minute (s),0Second (s)) ===|
============================
However, if derived is not virtual inherit from the base class, then the link error will not occur.
How to use C + + to write classes that cannot be inherited, but can define objects outside the class