Virtual functions and dynamic binding

Source: Internet
Author: User

When defining a base class, we want some functions in the base class to be redefined in the derived class. For example, we define a base-class record book to find out how much it costs to buy a book. In a derived class, we define a discount book, you still need to calculate the amount of money spent on the books you have bought. In this case, you need to redefine the function for calculating the amount of money. Note that the definition here is different from the previously mentioned function overload or operator overload: the latter two classes use different parameters, the Return Value Type allows the compiler to determine which function is used, and can be determined before the program is executed. The definition here is only because the content of the function body is different, parameters and return values are identical to accumulation. Only when the program is running can you determine the level of the function to be used (this process becomes a dynamic binding), in order to unify the interface of the program.
By declaring a function as a virtual function (this function cannot make the class constructor or static function), we can redefine it in the derived class. When declaring a virtual function, you must add the keyword Virtual. This keyword cannot appear outside the class. This is different from the statement of youyuan: youyuan can be declared either inside the class or outside the class. When a function is declared as a virtual function, this function is a virtual function for future generations of the base class, without adding the virtual keyword. (You can also add it to emphasize that it is a virtual function ).

Dynamic binding can occur only when a virtual function is called by referencing a base class or a pointer. Because the reference or pointer can refer to both the base class object and the base class part of the derived class object, the virtual function called by reference or pointer.
For example:

Class item_base {public: // constructor item_base (const STD: string & book = "", double sales_price = 0.0): ISBN (book), price (sales_price) {}// return ISBN No. STD: String book () {return ISBN;} // The base class does not require a discount policy virtual double net_price (STD: size_t N) const {return N * price;} // destructor virtual ~ Item_base () {}; PRIVATE: STD: String ISBN; protected: Double price ;}; class bulk_item: Public item_base {public: // constructor bulk_item (const STD :: string & book = "", double sales_price = 0.0, STD: size_t qty = 0, double disc_rate = 0.0): item_base (book, sales_price), quantity (qty ), discount (disc_rate ){}~ Bulk_item () {} double net_price (STD: size_t) const; private: // discount on the number of books bought before STD: size_t quantity; // double discount;}; Discount margin ;};

 

Where:

double Bulk_item::net_price(std::size_t cnt)const{if(cnt > quantity)return cnt * (1 - discount) * price;elsereturn cnt * price;}

Let's define another function to print the result:
Let's define another function for printing the result:

void print_total(std::ostream& os,const Item_base& item,std::size_t n){os<<"ISBN: "<<item.book()<<"\tnumber sold: "<<n<<"\ttotal price: "<<item.net_price(n)<<std::endl;}

In the main function:

int main(){Item_base b1("aaa",10);Bulk_item d1("bbb",10,5,0.5);print_total(cout,b1,10);print_total(cout,d1,10);return 0;}

Although the input parameter of the print_total function is a reference of the base class, we can also access it through a derived class. When a base class is used to access it, The net_price function of the base class is called. When a derived class accesses it, The net_price function of the derived class is called. This call rule cannot be determined during compilation. It must be determined only when the program is running. So it is called "Dynamic Association ". In contrast, it is a static association, such as function overloading and operator overloading. Before the program is executed, you can determine which function is called.

In particular, we sometimes encounter this situation: we define a class that also has its own data and functions, but we do not want users to create objects of this class, instead, you can only create objects of classes derived from this base class. Some people think that since we do not want to create a class object, why should we define this class? In fact, many times, the base class is an abstraction of some problems, and it does not make sense to create objects for it. We just use it to derive other, specific classes. For example, we have created an "animal" class, defined the "height" and "weight" of an animal, and defined the animal's actions: "eating" and "sleeping ". Derived from the "animal" class, such as the "tiger" class. At this time, we should also feel that defining an animal object does not make much sense.
How can we achieve the above ideas? Is to use pure virtual functions. The definition of a pure virtual function is very simple, that is, adding = 0 to the list of form parameters of a function. But this action is of extraordinary significance: First, we define this function (instead of defined in a derived class), so we have to provide a unified and writable interface for such functions, to facilitate subsequent management. Second, when a class contains (OR) pure virtual functions, this class becomes an "abstract base class" and we cannot create objects of this class, you can only use it to derive other classes and create the objects of the derived classes. This rule also prevents misuse of this class (because it is used for inheritance and many Members are not perfect .) For example:

Class annimal {public: Virtual void eat () = 0; void sleep () {}; PRIVATE: double height; double weight ;}; class Tiger: Public annimal {public: void eat () {STD: cout <"Eat meat" <STD: Endl;} void Merge () {STD :: cout <"sleep at night" <STD: Endl ;};}; class bat: Public annimal {public: void eat () {STD :: cout <"eat blood" <STD: Endl ;}; void hour () {STD: cout <"sleep at day" <STD :: endl ;}}; int main () {// you cannot create an abstract class Object // annimal A1; Tiger T1; t1.eat (); BAT B1; b1.eat (); return 0 ;}

 

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.