Class scope under Inheritance

Source: Internet
Author: User

The constructor and the constructor In the constructor are also in stages. That is to say, from the non-base class object to the derived class object, from the derived class object to the base class object, then to none.

There is a state in the middle that is the base class object. In this case, virtual functions can be called directly or indirectly, but only the versions in the base class are called, because the latter is not yet formed.

Because if you use the version in the derived class,PossibleYou need to access the members of the derived class object, and these do not exist. To avoid this risk of crash, it is blocked.

Class scope of inheritance:

The scope of the derived class is nested in the base class scope. If the name cannot be determined in the scope of the derived classPeripheralSearch for the definition of this name in the base class scope.

Static type priority

Add a function to the disc_item In The Middle Of item_base and bulk_item to statically bind the function...Static binding is performed during compilation rather than runtime, that is, the discount_policy () location is queried during compilation.

The pointer and reference are dynamic. In this example, there is no virtual function. In this way, bulk_item first finds itself, nesting according to the scope, and then directly finds the base class disc_item. if the pointer is of the base class type, the discount_policy () function cannot be found because it is not declared at all.

class Disc_item : public Item_base {public:std::pair<size_t, double> discount_policy() const {return std::make_pair(quantity, discount);}};

Bulk_item *bulkP = &bulk;//ok:static and dynamic types are the sameItem_base *itemP = &bulk;//ok:static and dynamic types differbulkP->discount_policy();//ok:bulkP has type Bulk_item*itemP->discount_policy();//error:itemP has type Item_base*

Name Conflict and inheritance:

There is nothing, but it is the scope operator.

int get_mem() { return mem; }//returns Derived::memint get_base_mem() { return Base::mem; }//returns Base::mem

The rule is such a rule, but it should be avoided as much as possible.
Just like the typical setdata () {This. Data = data ;}

The difference is that it is a member of the function body parameter override class. Here, the member of the derived class overwrites the base class member of the same name.

Pe23_2.cpp the original question has too many definitions of the base class and derived class. This is a revision.

Strange discoveries: first, the base class's foo_BAR does not conflict with the derived class's foo_BAR (), while the base class's bar conflicts with the derived class's Bar (base * pb)

Second, not only does the name conflict of the base class derived classes solve the name blocking problem, but also encountersThe derived class cannot access the base class protected member.

// If the problem persists, modify # include <iostream> struct base {void Foo (INT); protected: int bar; double foo_BAR ;}; struct derived: public base {void Foo (STD: string); bool bar (base * pb); void foo_BAR (); protected: STD: String bar;}; // Question 2, the error is the same. The attempt to assign a value of 1024 to base: bar is blocked. The result is that bar considers 1024 to be an inappropriate initial address of the string, prompting whether it is missing & // void derived:: foo_BAR () {bar = 1024;} // The third question seems to be correct. Unless the definition of the question is wrong, is it the method of the derived class foo_BAR () to shield the foo_BAR of the base class, // In fact, members of the base class and member functions of the derived class cannot have the same name ...... // In fact, there is still a problem. The base class is protected, and neither static binding nor static binding is allowed for direct access ~!!!!!!!!!!!!!!!! // Bool derived: bar (base * pb) // {return base: foo_BAR = Pb-> foo_BAR;} int main () {// locate the errors in each of the following examples and describe how to correct them (but the above errors are still true) // no matter the class definition error, the first mistake was to call the foo of the INT-type parameter in the base, which was blocked. // derived D; // D. fool (1024 );}

Scope and member functions:

Derivedoverload. cpp

Summary: Like a local function that does not overload a global function, as long as the function name is the same, the parameter list does not matter. The override function of a derived class is greater than the overload function, under normal circumstances, the derived class either does not overload the base class members or completely overwrites the base class members.

With the using declaration, you can introduce the base class members (equivalent to copying them all over). After the introduction, it is equivalentScope of a derived classExpanded and overloaded

// The member functions of the base class and derived class cannot be overloaded or overwritten. If the member functions of the derived class are redefined, they cannot be found even if the parameters are incorrect, the base class is not found either. // However, you can also use base: to directly call base class members. // Of course, use using base: memfcn to introduce base class members, you can reload it .. # Include <iostream> struct base {int memfcn () {STD: cout <"base: memfcn ()" <STD: Endl; return 1 ;}}; struct derived: Base {using base: memfcn; // hide base: memfcn () before import. You can reload int memfcn (INT) {STD :: cout <"derived: memfcn ()" <STD: Endl; return 1;} // hides memfcn in the base}; int main () {derived D; base B; B. memfcn (); D. memfcn (10); D. memfcn (); // error: memfcn with no arguments is hidden, correct after using D. base: memfcn (); // OK: callbase: memfcnd. base: memfcn (10); // indicates that the overload is only within the scope of the derived class, and only one function in the scope of the base class}

Virtual functions and scopes:
Review: a prerequisite for dynamic binding-calling virtual members through pointers or references.

When we do this, the compiler will look for the function in the base class (why not find the function in the derived class later ~). If the name is found, the compiler checks whether the real parameter matches the form parameter.

This is fine.UnderstandingWhy do virtual functions require base classes and derived classes to haveSame prototype.

If the real parameters are different, there is no wayPassThe PTR and ref of the base class type call the function of the derived class. The text is not easy to understand. Let's look at the code.

That is to say, PTR and ref indicate dynamic binding. dynamic binding must be called with parameters. If the parameters do not match, base * does not care about derived.

/* Virtualandscope. cpp * // virtual function and scope. For example, the emphasis is on D2 and D2, which includes both virtual functions and redefinition overwrite... # Include <iostream> class base {public: Virtual int FCN () {STD: cout <"base: FCN ()" <STD: Endl; return 1 ;}}; class D1: public base {public: // hides FCN in the base; this FCN is not virtualint FCN (INT) {STD :: cout <"D1: FCN (INT)" <STD: Endl; return 1;} // parameter list differs from FCN in base // D1 inherits definition of base:: FCN () // parameter list mismatch is not a virtual function. Although it inherits base: FCN (), D1: FCN () still does not exist}; Class D2: Public D1 {public: int FCN (INT) {STD :: cout <"D2: FCN (INT)" <STD: Endl; return 1;} // nonvirtual function hides D1: FCN (INT) int FCN () {STD: cout <"D2: FCN ()" <STD: Endl; return 1;} // redefines virtual FCN from base}; int main () {Base B; D1 D1; d2 D2; B. FCN (); STD :: cout <"======================================== ==== "<STD:: Endl; d1.base: FCN (); d1.fcn (2); STD :: Cout <"======================================== ==== "<STD:: Endl; d2.fcn (); d2.fcn (3); STD :: cout <"======================================== ==== "<STD:: Endl; STD: cout <"original book example ~ Use the base class to call blocked virtual functions: "<STD: Endl; base bobj; D1 d1obj; d2 d2obj; base * bp1 = & bobj, * bp2 = & d1obj, * bp3 = & d2obj; // base class pointer bp1-> FCN (); // OK: virtual call, will call base: FCN at run timebp2-> FCN (); // OK: virtual call, will call base: FCN at run time // bp2-> FCN (2); // error: nonvirtual call, hides FCN in the base, this FCN is not virtualstd :: cout <"======================================== ==== "<STD:: Endl; STD: cout <"* bp3, important:" <STD: Endl; bp3-> FCN (); // OK: virtual call, will call D2: FCN at run time // bp3-> FCN (3); // error: nonvirtual call, hides FCN in the base, this FCN is not virtualstd :: cout <"* bp3 control group:" <STD: Endl; d2.fcn (); d2.fcn (3 );}

Minor revision: in the base, virtual, D1 plus virtual, base and D1 are removed. D1 and D2 virtual functions are bound, and then using base: FCN; virtual int D1: is dynamically called :: FCN (INT) {STD: cout <"D1: FCN (INT)" <STD: Endl; return 1;} D1 * dp2 = & d1obj, * dp3 = & d2obj; dp2-> FCN (); dp2-> base: FCN (); dp2-> FCN (2); dp3-> FCN (); dp3-> base: FCN (); dp3-> FCN (2 );

Key concepts: Name Search and inheritance

The key to understanding the C ++ hierarchy is to understand how to determine the function call and how to determine the function call follow the following four steps:

At the end of the P501 (original version 594...

Exercise 15.24

// Exercise, too lazy to implement, simple problem. One is that the item_base object is copied and constructed, and the other is dynamic. It identifies the bulk_item object and uses virtual

Pe15_25.cpp is a bit confusing. The overload does not seem to care about the return type, but it is a virtual function.

In addition, the front side can run normally, and even the derived D; won't be allowed. The prompt is very strange. I didn't call copy (). Do I have to complete the definition first? YesCopy () is special.. (Mark)

// 4. Add the virtual function in base to derived to define its own virtual function version and determine which declaration is wrong # include <iostream> class base {public: virtual base * Copy (base *); // a), B) // virtual STD: ostream & print (INT, STD: ostream & = STD: cout ); // C) // virtual void eval () const {STD: cout <"base: eval () called" <STD: Endl ;} // d)}; Class derived: public base {public: // base * Copy (derived *); // a) Judge Based on intent (rather than syntax ), the error is indicated by the return type. Actually, there are more ~! Different parameter types cannot be dynamically bound // derived * Copy (base *); // B) can be determined based on the intention (rather than the syntax), and the error lies in the parameter type. More than that, the syntax is also incorrect. The returned type does not match. // virtual STD: ostream & print (INT, STD: ostream &); // C) is correct, if no real parameter is set, it is not an error. // void eval () {STD: cout <"derived: eval () called" <STD: Endl;} // D) yes, const does not affect virtual functions}; int main () {derived D; // base * BP = & D; // BP-> eval ();} error message: G ++-wall-o "pe15_25" "pe15_25.cpp" (In directory:/home/huqinwei/cppworkspace/chap15)/tmp/ccl8gimw. o: In function 'base: Base () ': pe15_25.cpp :(. text. _ zn4basec2ev [_ zn4basec5ev] + 0x8): Undefined reference to 'vtable for base'/tmp/ccl8gimw. O :(. rodata. _ ztv7derived [vtable for derived] + 0x8): Undefined reference to 'base: Copy (base *) '/tmp/ccl8gimw. O :(. rodata. _ zti7derived [typeinfo for derived] + 0x8): Undefined reference to 'typeinfo for base' collect2: LD returned 1 exit statuscompilation failed.

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.