Resolves virtual functions of virtual declarations in C + + programming and a single inherited _c language

Source: Internet
Author: User

virtual function

A virtual function is a member function that should be redefined in a derived class. When you use a pointer or a reference to a base class to reference a derived class object, you can invoke the virtual function for that object and execute the derived class version of the function.
The virtual function ensures that the correct function is called for the object, regardless of the expression used for the function call.
Suppose the base class contains a function declared virtual, and the derived class defines the same function. Calls a function in a derived class for an object of a derived class, even if it is invoked using a pointer or a reference to a base class. The following example shows a base class that provides implementations of the Printbalance function and two derived classes

Deriv_virtualfunctions.cpp//compile with:/EHsc #include <iostream> using namespace std;
  Class Account {Public:account (double d) {_balance = D;}
  Virtual Double getbalance () {return _balance;} virtual void Printbalance () {cerr << "Error. Balance not available for base type. "<< Endl;
} private:double _balance;

}; Class Checkingaccount:public Account {Public:checkingaccount (double D): Account (d) {} void Printbalance () {cout

<< "Checking account balance:" << getbalance () << Endl;}; Class Savingsaccount:public Account {Public:savingsaccount (double D): Account (d) {} void Printbalance () {cout &L

t;< "Savings account Balance:" << getbalance ();};
  int main () {//Create objects of type Checkingaccount and SavingsAccount.
  Checkingaccount *pchecking = new Checkingaccount (100.00);

  SavingsAccount *psavings = new SavingsAccount (1000.00);
 Call printbalance using a pointer. Account *paccount = pchecking;

  Paccount->printbalance ();
  Call printbalance using a pointer.
  Paccount = psavings;  
Paccount->printbalance ();

 }

In the preceding code, the call to Printbalance is the same, except for the object that Paccount points to. Because Printbalance is virtual, the version of the function defined for each object is invoked. The SavingsAccount function in the derived class Printbalance and Checkingaccount "overrides" the function in the base class account.
If the declared class does not provide an overriding implementation of the Printbalance function, the default implementation in the base class account is used.
functions in a derived class override these virtual functions only if they are of the same type as the virtual functions in the base class. A function in a derived class cannot just be different from a virtual function of the base class in its return type, and the argument list must also be different.
When you invoke a function by using a pointer or reference, the following rule applies:
Resolves a call to a virtual function based on the base type of the object that is invoked for it. The
resolves a call to a non-virtual function based on the type of pointer or reference. The
The following example illustrates the behavior of virtual and non-virtual functions when called by a pointer:

Deriv_virtualfunctions2.cpp//compile with:/EHsc #include <iostream> using namespace std;  Class Base {public:virtual void nameof ();
  Virtual function.  void Invokingclass ();
nonvirtual function.

};
Implement the two functions.

void Base::nameof () {cout << "base::nameof\n";}

void Base::invokingclass () {cout << "invoked by base\n";}  Class Derived:public Base {public:void nameof ();
  Virtual function.  void Invokingclass ();
nonvirtual function.

};
Implement the two functions.

void Derived::nameof () {cout << "derived::nameof\n";}

void Derived::invokingclass () {cout << "invoked by derived\n";}
  int main () {//Declare an object of type Derived.

  Derived aderived; Declare two pointers, one of type Derived * and the other/of type Base *, and initialize them to point to aderived
  .
  Derived *pderived = &aDerived;

  Base *pbase = &aDerived;
  Call the functions. Pbase->nameof();
  Call virtual function.  Pbase->invokingclass ();
  Call nonvirtual function.    Pderived->nameof ();
  Call virtual function. Pderived->invokingclass ();
Call nonvirtual function.

 }

Output

Derived::nameof
invoked by Base
derived::nameof
invoked by Derived

Note that the function of Derived is invoked whether the Nameof function is invoked by pointing to a pointer to Base or by a pointer to a Derived. It calls the Derived function because the nameof is a virtual function, and both pbase and pderived point to Objects of type Derived.
You cannot declare a global function or a static function as virtual because it is called only for objects of the class type.
You can use the virtual keyword when declaring an overriding function in a derived class, but it is not required, and the override of a virtual function is always virtual.
Virtual functions in the base class must be defined unless they are declared using Pure-specifier. (For more information about pure virtual functions, see abstract classes.) )
You can use the range resolution operator (::) Explicitly qualify the function name to disable the virtual function invocation mechanism. Consider an example that previously involved the account class. To invoke the printbalance in the base class, use the code shown below:

Checkingaccount *pchecking = new Checkingaccount (100.00);

Pchecking->account::P rintbalance (); EXPLICIT qualification.

Account *paccount = pchecking; Call Account::P rintbalance

paccount->account::P rintbalance ();  EXPLICIT qualification.

In the previous example, the call to Printbalance disables the virtual function invocation mechanism.


Single inheritance
in "Single Inheritance" (a common form of inheritance), a class has only one base class. Consider the relationship illustrated in the diagram below.

Simple single inheritance Diagram
Note the progress from general to specific in this diagram. Another common feature found in the design of most class hierarchies is that derived classes have a "certain" relationship with the base class. In the figure, book is a printeddocument, and Paperbackbook is a book.
Another note in the diagram is that the book is both a derived class (from Printeddocument) and a base class (Paperbackbook derived from the book). The framework for such a class hierarchy declares an example that looks like this:

Deriv_singleinheritance.cpp
//compile with:/ld
class Printeddocument {};

The book are derived from Printeddocument.
Class Book:public Printeddocument {};

Paperbackbook is derived from book.
Class Paperbackbook:public book {};

Printeddocument is regarded as the "direct base" class of the book; it is the "indirect base" class of Paperbackbook. The difference is that the direct base class appears in the underlying list of the class declaration, but not in the indirect base class.
Declares the base class from which each class is derived before declaring a derived class. It is not sufficient to provide a forward reference declaration for a base class;
In the previous example, the access descriptor is public. The meaning of public, protected, and private inheritance is described in member access control.
A class can be used as a base class for multiple specific classes, as shown in the following illustration.

Attention
Non-circular graphs are not unique to single inheritance. They are also used to represent multiple inheritance graphs. This topic is described in multiple inheritance.
In inheritance, a derived class contains members of the base class and all new members that you add. Therefore, derived classes can reference members of the base class (unless they are redefined in a derived class). When a member of a direct or indirect base class is redefined in a derived class, the scope resolution operator (::) Can be used to reference these members. Take a look at the following example:

Deriv_singleinheritance2.cpp
//compile with:/ehsc/c
#include <iostream>
using namespace std;
Class Document {public
:
  Char *name;  Document name.
  void Printnameof ();  Print name.
};

Implementation of printnameof function from class Document.
void Document::P rintnameof () {
  cout << Name << endl;
}

Class Book:public Document {public
: Book
  (char *name, long PageCount);
Private:
  long PageCount;
};

constructor from class book.
Book::book (char *name, long PageCount) {
  name = new char[strlen (name) + 1];
  strcpy_s (name, strlen (name), name);
  PageCount = PageCount;
};

Note that the book's constructor (Book::book) has access to the data member Name. In your program, you can create and use objects of type book, as follows:

Create a new object of type book. This invokes the
//  constructor Book::book.
Book LibraryBook ("Programming Windows, 2nd Ed", 944);

...

Use Printnameof function inherited from class Document.
Librarybook.printnameof ();

As shown in the previous example, class members and inherited data and functions are used in the same way. If the implementation of the class book calls the Printnameof function, only functions that belong to:: Class can be invoked by using the scope resolution (Document) Operator:

Deriv_singleinheritance3.cpp
//compile with:/ehsc/ld
#include <iostream>
using namespace std ;

Class Document {public
:
  Char *name;     Document name.
  void Printnameof () {}//Print name.
};

Class Book:public Document {book
  (char *name, long PageCount);
  void Printnameof ();
  Long PageCount;
};

void book::P rintnameof () {
  cout << "Name of Book:";
  Document::P rintnameof ();
}

If there is an accessible, unambiguous base class, you can implicitly convert the pointer and reference of a derived class to a pointer and reference to its base class. The following code demonstrates this concept using pointers (the same principle applies to references):

Deriv_singleinheritance4.cpp
//compile with:/w3
struct Document {
  char *name;
  void Printnameof () {}
};

Class Paperbackbook:public Document {};

int main () {
  Document * doclib[10];  Library of ten documents.
  for (int i = 0; i < i++)
   doclib[i] = new Document;
}

In the previous example, different types were created. However, because these types derive from the document class, there is an implicit conversion to document *. Therefore, DocLib is a "heterogeneous list" (which contains all the objects that are not of the same type), and the list contains different types of objects.
Because the document class has a printnameof function, it can print the name of each book in the library, but it may omit certain document-specific information (the page count of books, the number of bytes in HelpFile, and so on).
Attention
Enforcing the use of a base class to implement functions such as printnameof is usually not the best design. Virtual functions provide additional design alternatives.


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.