Virtual functions are the key mechanism for implementing polymorphism in C, allowing the function version of a derived class to be called through base class pointers or references. 1. The virtual function is declared as virtual in the base class and can be rewritten in the derived class; 2. When using virtual functions, the actual function version of the type to which the object belongs; 3. C realizes dynamic binding through virtual function tables (vtables) and virtual pointers (vptr), bringing certain performance overhead and increasing the object size; 4. If the destructor is inherited, it should be declared as a virtual function, and the static function and constructor cannot be virtual functions; 5. It is recommended to use virtual functions only when needed, combine the override keyword to explicitly rewrite, and use pure virtual functions to force derived classes to implement specific methods; 6. Be careful to avoid calling virtual functions in constructors or destructors, and the default parameters must be consistent to prevent misunderstandings.
Virtual functions in C are key mechanisms used to implement polymorphism. Simply put, it allows us to call the function version of the derived class through a pointer or reference, rather than the base class's own version.

What is a virtual function?
Virtual functions are member functions declared as virtual
in the base class and can be override in derived classes. When you call this function through a base class pointer or reference, the actual execution is the function version of the type to which the object belongs.

Let's give a simple example:
#include <iostream> using namespace std; class Animal { public: virtual void sound() { cout << "Animal makes a sound" << endl; } }; class Dog : public Animal { public: void sound() override { cout << "Dog barks" << endl; } }; int main() { Animal* animal = new Dog(); animal->sound(); // Output: Dog barks delete animal; return 0; }
In this example, animal
is a pointer to Animal
, but it actually points to a Dog
object. Since sound()
is a virtual function, the Dog
version is called.

Virtual function table and runtime binding
C uses virtual function tables (vtables) to support dynamic binding. Each class with virtual functions has a virtual function table, which stores the actual addresses of each virtual function. When the object is created, a pointer (vptr) to this table is saved.
This means:
- Virtual functions bring certain performance overhead (indirect addressing)
- The object size of the class will increase (because vptr is stored)
- If polymorphism is not needed, don't add
virtual
at will
The following points should be paid attention to when using virtual functions:
- If the destructor is possible, it is best to declare it as a virtual function, otherwise it may cause resource leakage.
- Static functions cannot be virtual functions
- The constructor cannot be a virtual function either (because the object has not been fully constructed yet)
How to use virtual functions correctly?
If you intend to have a class inherited as a base class and want the subclass to override certain methods, then these methods should be declared as virtual functions.
suggestion:
- Use virtual functions only when needed
- When providing a default implementation to a derived class, virtual functions can be retained but not forced to override
- Use the
override
keyword to explicitly indicate that you are rewriting the parent class method to avoid spelling errors - If you want to force a derived class to implement a method, you can set it as a pure virtual function (
= 0
), so that the base class becomes an abstract class
For example:
class Shape { public: virtual void draw() = 0; // Pure virtual function};
In this way, any class that inherits Shape
must implement draw()
method.
Pay attention to small details
- If you accidentally forget to set the function as a virtual function, then the multimorphism will not take effect
- Calling virtual functions in constructors or destructors will not trigger polymorphic behavior (because the object has not been constructed or has been deconstructed)
- Virtual functions can have default parameters, but it is recommended to keep them consistent, otherwise it will easily cause misunderstandings.
Basically that's it. Virtual functions are the core of C polymorphism, and understanding them is very helpful in writing flexible and extensible code.
The above is the detailed content of C virtual function example. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

The main difference between Java and other programming languages ??is its cross-platform feature of "writing at once, running everywhere". 1. The syntax of Java is close to C, but it removes pointer operations that are prone to errors, making it suitable for large enterprise applications. 2. Compared with Python, Java has more advantages in performance and large-scale data processing. The cross-platform advantage of Java stems from the Java virtual machine (JVM), which can run the same bytecode on different platforms, simplifying development and deployment, but be careful to avoid using platform-specific APIs to maintain cross-platformity.

C is widely used in the fields of game development, embedded systems, financial transactions and scientific computing, due to its high performance and flexibility. 1) In game development, C is used for efficient graphics rendering and real-time computing. 2) In embedded systems, C's memory management and hardware control capabilities make it the first choice. 3) In the field of financial transactions, C's high performance meets the needs of real-time computing. 4) In scientific computing, C's efficient algorithm implementation and data processing capabilities are fully reflected.

Reducing the use of global variables in C can be achieved by: 1. Using encapsulation and singleton patterns to hide data and limit instances; 2. Using dependency injection to pass dependencies; 3. Using local static variables to replace global shared data; 4. Reduce the dependence of global variables through namespace and modular organization of code.

The main differences between C# and C are memory management, polymorphism implementation and performance optimization. 1) C# uses a garbage collector to automatically manage memory, while C needs to be managed manually. 2) C# realizes polymorphism through interfaces and virtual methods, and C uses virtual functions and pure virtual functions. 3) The performance optimization of C# depends on structure and parallel programming, while C is implemented through inline functions and multithreading.

In C, the bit field is a structure member that specifies the number of bits, used to save memory and directly manipulate hardware. Example: structMyStruct{inta:2;intb:5;intc:1;}. The advantage of bit domains is memory savings, but there are cross-platform issues, access restrictions and assignments that require caution. Example of usage: structStateMachine{unsignedintpower:1;unsignedintmode:2;unsignedinterror:1;}. Performance recommendations include arranging bit fields by size, avoiding overuse and adequate testing.

The syntax of the trigonometric operator in C is condition?expression1:expression2, which is used to select and execute different expressions according to the condition. 1) Basic usage example: intmax=(x>y)?x:y, used to select the larger value in x and y. 2) Example of nested usage: intresult=(a>0&&b>0)?a b:(a==0||b==0)?a*b:a-b, used to perform different operations according to different conditions. 3) Error handling example: std::stringerrorMessage=(errorCode==0)?"Successful&quo

C is not dead, but has flourished in many key areas: 1) game development, 2) system programming, 3) high-performance computing, 4) browsers and network applications, C is still the mainstream choice, showing its strong vitality and application scenarios.

The usage of logical non-operator! in C includes: 1) Basic usage: inverse the Boolean value; 2) Conditional judgment: simplify the code, such as checking whether the container is empty; 3) Loop control: processing elements that do not meet the conditions; 4) Function return value processing: determine whether the operation has failed. Pay attention to potential pitfalls such as pointer processing and operator priority when using!, but it can help write more concise and efficient code.
