C ++ FAQ Lite [24] - inheritance (private and protective inheritance) (Update)

zhaozj2021-02-08  226

[24] Inheritance - Private Inheritance and Protection Inheritance (Part of C FAQ Lite, Copyright © 1991-2001, Marshall Cline, Cline@parashift.com)

体,, nicrosoft @ sunistudio.com (East day production room, East day document)

FAQS in section [24]:

[24.1] How to express "private inheritance"? [24.2] What is the private inheritance and a combination? [24.3] Who should I choose: Is the combination or private inheritance? [24.4] Does the parent type conversion from a private inheritance class? [24.5] What is the relationship between protecting inheritance and private inheritance? [24.6] What is the access rule of private inheritance and inheritance?

[24.1] How to express "private inheritance"?

Use: private instead: public, for example

Class foo: private bar {public:

// ...

}

[TOP | BOTTOM | Previous Section | Next Section]

[24.2] What is the private inheritance and a combination?

[Recently changed the syntax to using Engine :: start; and added the sixth distinction thanks to Stan Brown; added the third similarity; added "aggregation" as another synonym;. General wordsmithing (on 4/01) Click here to go to the Next FAQ in the "chain" of Recent Changes

]

Private inheritance is a combination of syntax deformation (polymerization or "one")

For example, "There is a (HAS-A) engine" relationship can be expressed as a single combination:

Class Engine {public: engine (int numberlinders); void start ();

// Starts this Engine

}; Class car {public: car (): e_ (8) {}

// Initializes this car with 8 cylinders

Void start () {e_.start ();

// start this car by starting its engine

PRIVATE: ENGINE E_;

// car HAS-A ENGINE

}

The same "there is a" relationship can also be used in handling:

Class car: private engine {

// car HAS-A ENGINE

Public: car (): Engine (8) {}

// Initializes this car with 8 cylinders

Using Engine :: Start;

// start this car by starting its engine

}

There are many similar places in two forms:

In both cases, only one engine is exactly in both cases in both cases, and the car * cannot be converted to Engine * in both cases, and the CAR class has a start () method, and all are The START () method is called in the ENGINE object.

There are also some differences:

If you want each Car's all kind of engine, you can only use a single combination of a private inheritance form that may introduce unnecessary multi-inheritance private inheritance forms allowing members to convert CAR * to Engine * Private inheritance forms Allow access Protected member private inheritance form Allow CAR to rewrite the virtual inheritance of Engine private inheritance to assign a CAR a more concise (20 characters than 28 characters) Note that only the start () method called by Engine is Note, private inheritance usually It is used to get access: members of the base class, but this is just a short-term solution (meter of power)

[TOP | BOTTOM | Previous Section | Next Section]

[24.3] Who should I choose: Is the combination or private inheritance?

[Recently Changed SO IT Uses New-Style Headers and the Std :: Syntax (on 7/00). Click Here To Go To The Next Faq in The "Chain" of Recent Changes

]

As much as possible, you must use private inheritance usually you won't want to access other categories inside, and private inheritance gives you some privileges (and responsibilities). But private inheritance is not harmful. Just because it increases someone to change some things, destroy your code's possibility, so that the cost of maintenance is more expensive. When you want to create a Fred class, it uses the Wilma class code, and these code for the Wilma class needs to call the member function of your newly built Fred class. In this case, Fred calls Wilma's non-virtual functions, while Wilma calls (usually pure virtual functions) are rewritten by FRED. This situation is difficult to complete with a combination.

Class Wilma {Protected: Void Fredcallswilma () {std :: cout << "Wilma :: FredCallswilma () / n"; Wilmacallsfred ();} Virtual Void WilmacallsFRED () = 0;

// Pure virtual function

}; Class fred: private Wilma {public: void barney () {std :: cout << "Fred :: barney () / n"; wilma :: fredcallswilma ();} protected: virtual void wilmacallsfred () {std: : cout << "fred :: wilmacallsfred () / n";}};

[TOP | BOTTOM | Previous Section | Next Section]

[24.4] Does the parent type conversion from a private inheritance class?

Generally, not.

For member functions or friends of the private inheritance class, the relationship between the base class is known, and this conversion from Privatelyder * to Base * (or Privatelyder & to Base &) is safe, no need Recommended for type conversion. However, this unsafe conversion should be avoided for users of the private inheritance (Privatelyder). Because it is based on private implementation of Privatelyder, it can change itself.

[TOP | BOTTOM | Previous Section | Next Section] [24.5] What is the relationship between protective inheritance and private inheritance?

[Recently Renamed "Subclass" to "Derived Class" (on 7/00). Click Here to Go To The Next FAQ in The "Chain" of Recent Changes

]

The same point: All virtual functions of the private / protect the base class are all allowed, and the school is not shown "a Kind-of) base class.

Different points: Protection inheritance allows derived derivatives to know inheritance relationships. Thus, children and grandchildren can effectively learn the details of the ancestors. This is also the advantageous (it allows the association of the subclass of protecting inheritance to use it and protects the base class) also has a price (protected party category "to change this association without divecaling).

Protection inheritance: protected grammar:

Class Car: protected eNGINE {public:

// ...

}

[TOP | BOTTOM | Previous Section | Next Section]

[24.6] What is the access rule of private inheritance and inheritance?

[Recently Renamed "Subclass" to "Derived Class" (on 7/00). Click Here to Go To The Next FAQ in The "Chain" of Recent Changes

]

Take these classes:

Class b {

/*...

}; Class D_Priv: private b {

/*...

}; Class D_Prot: protected b {

/*...

}; Class D_Publ: Public B {

/*...

}; Class userclass {b;

/*...

}

Subclasses cannot access the private parts of B. In D_PRIV, B's public and protective parts are private. In D_PROT, B's public and protective parts are protected. In D_Publ, the public part of B is public, and the protective portion of B is protected (D_Publ is a b). The UserClass class can only access the public part of B. To make B's public members are also public in D_PRIV or D_PROT, use the name of the B:: Prefix declaration member. For example, to make B :: F (int, float) member in D_PROT, you should write:

Class D_Prot: protected b {public: using b :: f;

// Note: Not Using B :: F (int, float)

}

[TOP | BOTTOM | Previous Section | Next Section]

E-mail the author [C FAQ Lite | Table of Contents | Subject Index | About The Author | © | Download Your Own Copy] Revised Apr 8, 2001

转载请注明原文地址:https://www.9cbs.com/read-2070.html

New Post(0)