025 - C++ interface (pure virtual function)

In the last issue, we learned about virtual functions. In this issue, we learn about a special kind of virtual function, pure virtual function.

C++ pure virtual functions are essentially the same as abstract methods or interfaces in other languages. Basically, pure virtual functions allow us to define a function without implementation in the base class, and then force the subclass to implement the function.

We can look at the previous example about virtual functions.

oqK315.png

You can see that there is a virtual function GetName in the Entity class, and then we override that function in the Player class, and in the base class, this GetName function has a function body, which means that rewriting it in a certain class is just a Optional, even if you don't override it, you can still call it.

In some cases, however, it doesn't make sense to provide such a default implementation, and we may actually want to force subclasses to provide their own definitions for certain functions.

In object-oriented programming, it is very common to create a class consisting only of unimplemented methods, and then force subclasses to implement their operations. Such classes are often called interfaces.

Thus, an interface in a class contains only unimplemented methods as templates, and since this interface doesn't actually contain method implementations, we can't actually instantiate that class.

pure virtual function

Let's see if the GetName function in the Entity class can be made pure virtual.

oqgf9T.png

In the above code, we still define the GetName function as a virtual function, but equal to 0 makes it a pure virtual function, which means it must be implemented in a subclass, if you want to instantiate this subclass, Some changes do need to be made.

First, let's take a look at the main function, and we can see that we don't have the ability to instantiate the Entity class now, we must give it a subclass to implement this function.

Use the Player class.

oqgYxr.png

You can see that the Player class is working fine.

This is only because we implemented the GetName function in the Player class, you can try to comment out the GetName function in the Player, and you will find that the Player cannot be instantiated either.

Essentially, you can only instantiate after implementing all these pure virtual functions, or in a higher-level class. For example, if the Player class is a subclass of another class (a subclass of Entity), and this class implements the GetName function, that is also possible.

Pure virtual functions must be implemented in order to create an instance of this class.

Let's look at another, better example.

oqgk0c.png

We write a function to print the class names of these classes, ensuring that obj has the GetClassName function. Now we need a type that can provide the GetClassName function, this is called an interface.

We call the position of the question mark Printable, and set it.

oqgg4h.png

Above, we create a new class called Printable, which has only these contents, and it creates a public virtual string function that returns a string. This function is a pure virtual function. Then have the Entity implement that interface.

Note that the Player is now an Entity, so we don't need to implement the Printable interface.

What's more, although I call Printable interface interface, it is actually just a class, so it is still called class instead of interface, because it just has a pure virtual function, nothing more.

In fact, other languages ​​have the interface keyword instead of calling it class, but C++ doesn't. Interfaces are just C++ classes.

Now all classes need to implement this GetClassName function.

Let's go ahead and add a GetClassName function to the Entity class,

oqkCGD.png

Our inability to instantiate has been fixed, and that functionality is now provided.

However, you may notice that we haven't provided an override function for the Player yet, if you call the function Print now and run it, you can see that the Entity is printed twice because we haven't provided a definition in the Player yet.

oqgybb.png

We directly copy the specific code and make some modifications, and run it again.

oqk5Io.png

As you can see, now we get the correct class names, all from a Print function. This function accepts Printable as a parameter, it doesn't care what kind it is.

For example, we can create a completely different class, such as A, which is a subclass of the Printable class, and it must have corresponding functions.

oqguaK.png

I have now created a brand new class and implemented the Printable interface, that is, implemented this function, and called print as before, and you will see that the result is normal.

oqghk1.png

Note: This way of writing is not recommended, it is easy to cause memory leaks, but it is no problem as a test.

final words

This is the whole working principle of pure virtual function, it knows anything Printable, they have a GetClassName function to call, if you don't implement this function, you can't instantiate the class.

This is the interface in C++, that is, the pure virtual function in C++. It is a very useful tool that can be used in the scene just now. If you want to ensure that the class has a specific method, you can use this The class is put into a generic function as a parameter, and then you can call the method or do other things.

That's all for this issue, see you next time.

Supongo que te gusta

Origin blog.csdn.net/qq_40186237/article/details/130511165
Recomendado
Clasificación