I know there are a few different ways to achieve polymorphism in c++.
I know of 3 ways to do this:
by using inheritance (through the use of a pointer to a base class)
by using virtual function
by using abstract classes
During a technical discussion on the topic I was told I am missing something and was left hanging...hence I asked the question here.
Is there another way in c++ to to this or is something I said wrong?
Your three ways are really just one: whether the base class is
abstract is an implementation detail; you need virtual
functions, which can be overridden in a derived class.
Other than that: both function overloading and templates provide
a form of polymorphism as well, although it is resolved at
compile time, and not run time. For that matter, you can define
a class in a header file, and provide several different
implementations for it, depending on compile time switches;
that's also a form of polymorphism. (This is often done for
system dependent code. The polymorphism is resolved as
a function of the system you're compiling for.)
I think your discussion was related to different types of polymorphism.
Compile time polymorphism - Ex: Function Overloading, Operator Overloading.
Run time polymorphism - Ex: Inheritance + virtual functions + base class pointer.
Related
A followup to this question : C++ : Is there a good way to choose between 2 implementations?
My goal here is that both of these classes can be called at the same runtime. So Polymorphism would be a good and easy way to go with.
I have the following diagram :
But the problem here is that each one of them(a.cpp/h and a_mockup.cpp/h) uses the singelton pattern(contains static functions) and static functions cannot be virtually declared in the baseclass.
Is there a way to solve this problem?
In C++ Virtual functions are invoked during run-time, when you have a pointer/reference to an instance of a class. Static functions aren't bind to a particular instance, they're bind to a class during compile-time. Moreover, C++ doesn't have pointers-to-class functionality. So, there is no such way to solve this.
You must have CRTP as your default design when aiming for static polymorphism.
This question already has answers here:
Is there any reason not to make a member function virtual?
(7 answers)
Closed 4 years ago.
What will be the purpose of using non-virtual method in terms of functionality with C++? Is there any merit to change a object's method by its object handle rather than its object type? I found many articles about how virtual method will be utilized but I could not find how non-virtual method will be utilized.
Other languages I know of such as Java, Ruby and Python only have virtual method. So functionally non-virtual method is not needed and just be used for performance reason?
OK. I hadn't read the article marked duplicate of. But your answers are still valuable to me in the point the telling the origin of C++ and comparing C++ to other object oriented languages. Thanks everyone to answer.
The answer is very simple : because C++ is not Java.
Programming languages have different philosophies and different ways to accomplish the same result.
Java (and other "OOP-language-where-every-object-is-GCed-and-is-a-reference-type", like C#) encourage you to think about objects in a very specific way: Inheritance and Polymoprphism are the main ways to achieve flexibility and generalization of code. Objects are almost always reference type, meaning that Car car can actually point to Toyota, Ford and whatever. objects are garbaged-collected and dynamically allocated. All objects anyway inherit from an Object class, so inheritance and dynamic polymorphism is anyway imbued into the language objects by the very language design.
C++ is different. the concept of object might be central to the language, but an object is basically a unit of data and functionality. it's a leaner form of a "real" OOP-language object and it usually allocated on the stack, uses RAII to handle its own resources, and is a value type.
Inheritance and Polymorphism exist, but they are inferior to composition and compile-time-polymorphism (templates).
C++ doesn't encourage you to think about objects as a reference type. objects might be a reference type, they might have virtual functions, but this is only one way to achieve flexibility and generalization in C++, as opposed to Java. you might use templates instead, function pointers and opaque types (a-la C style polymorphism), inheritance + overriding function (a-la Java style), Hence, C++ doesn't force you to take the Java route to flexibility - it gives you the opportunity to choose the best way to accomplish things.
When marking a method as virtual, every time such method will be called, the program will have to check the virtual table inside the object that you're calling the method on, it's called dynamic dispatch. It creates quit a bit of overhead compared to normal methods that are resolved using static dispatch.
As big part of C++ is giving the programmer the choice what he wants to do, you can choose if you want static of dynamic linking.
C++ method lookup mechanisms won't allow for polymorphism if it's non-virtual. Defining classes as non-virtual will prevent the overhead and confusion.
Have a look at This question and answers
If a method is not virtual, the compiler knows the address in memory where this method's code will be located right at compile time, and can use it right away. If a method is virtual, it will have to be determined at runtime, which implementation should be called, based on the object type. It adds overhead on every call. So, by making a method non-virtual, you make it more efficient.
It should be mentioned that in some languages it's the other way around: the methods are "virtual" by default, but you can explicitly mark them as "non-virtual" (usually called final).
Non-virtual methods can add additional functionalities specific only to the derived class.
class animal {
public:
virtual string name() = 0;
};
class rhino :public animal {
public:
string name() override { return "Rhino"; }
int getHornSize() { return 10; } // non-virtual method add functionality only specific to rhino class
};
I have run into an annoying problem lately, and I am not satisfied with my own workaround: I have a program that maintains a vector of pointers to a base class, and I am storing there all kind of children object-pointers. Now, each child class has methods of their own, and the main program may or not may call these methods, depending on the type of object (note though that they all heavily use common methods of the base class, so this justify inheritance).
I have found useful to have an "object identifier" to check the class type (and then either call the method or not), which is already not very beautiful, but this is not the main inconvenience. The main inconvenience is that, if I want to actually be able to call a derived class method using the base class pointer (or even just store the pointer in the pointer array), then one need to declare the derived methods as virtual in the base class.
Make sense from the C++ coding point of view.. but this is not practical in my case (from the development point of view), because I am planning to create many different children classes in different files, perhaps made by different people, and I don't want to tweak/maintain the base class each time, to add virtual methods!
How to do this? Essentially, what I am asking (I guess) is how to implement something like Objective-C NSArrays - if you send a message to an object that does not implement the method, well, nothing happens.
regards
Instead of this:
// variant A: declare everything in the base class
void DoStuff_A(Base* b) {
if (b->TypeId() == DERIVED_1)
b->DoDerived1Stuff();
else if if (b->TypeId() == DERIVED_2)
b->DoDerived12Stuff();
}
or this:
// variant B: declare nothing in the base class
void DoStuff_B(Base* b) {
if (b->TypeId() == DERIVED_1)
(dynamic_cast<Derived1*>(b))->DoDerived1Stuff();
else if if (b->TypeId() == DERIVED_2)
(dynamic_cast<Derived2*>(b))->DoDerived12Stuff();
}
do this:
// variant C: declare the right thing in the base class
b->DoStuff();
Note there's a single virtual function in the base per stuff that has to be done.
If you find yourself in a situation where you are more comfortable with variants A or B then with variant C, stop and rethink your design. You are coupling components too tightly and in the end it will backfire.
I am planning to create many different children classes in different
files, perhaps made by different people, and I don't want to
tweak/maintain the base class each time, to add virtual methods!
You are OK with tweaking DoStuff each time a derived class is added, but tweaking Base is a no-no. May I ask why?
If your design does not fit in either A, B or C pattern, show what you have, for clairvoyance is a rare feat these days.
You can do what you describe in C++, but not using functions. It is, by the way, kind of horrible but I suppose there might be cases in which it's a legitimate approach.
First way of doing this:
Define a function with a signature something like boost::variant parseMessage(std::string, std::vector<boost::variant>); and perhaps a string of convenience functions with common signatures on the base class and include a message lookup table on the base class which takes functors. In each class constructor add its messages to the message table and the parseMessage function then parcels off each message to the right function on the class.
It's ugly and slow but it should work.
Second way of doing this:
Define the virtual functions further down the hierarchy so if you want to add int foo(bar*); you first add a class that defines it as virtual and then ensure every class that wants to define int foo(bar*); inherit from it. You can then use dynamic_cast to ensure that the pointer you are looking at inherits from this class before trying to call int foo(bar*);. Possible these interface adding classes could be pure virtual so they can be mixed in to various points using multiple inheritance, but that may have its own problems.
This is less flexible than the first way and requires the classes that implement a function to be linked to each other. Oh, and it's still ugly.
But mostly I suggest you try and write C++ code like C++ code not Objective-C code.
This can be solved by adding some sort of introspection capabilities and meta object system. This talk Metadata and reflection in C++ — Jeff Tucker demonstrates how to do this using c++'s template meta programming.
If you don't want to go to the trouble of implementing one yourself, then it would be easier to use an existing one such as Qt's meta object system. Note that this solution does not work with multiple inheritance due to limitations in the meta object compiler: QObject Multiple Inheritance.
With that installed, you can query for the presence of methods and call them. This is quite tedious to do by hand, so the easiest way to call such a methods is using the signal and slot mechanism.
There is also GObject which is quite simmilar and there are others.
If you are planning to create many different children classes in different files, perhaps made by different people, and also I would guess you don't want to change your main code for every child class. Then I think what you need to do in your base class is to define several (not to many) virtual functions (with empty implementation) BUT those functions should be used to mark a time in the logic where they are called like "AfterInseart" or "BeforeSorting", Etc.
Usually there are not to many places in the logic you wish a derived classes to perform there own logic.
I'm writing a large abstract base class with 30 something purely virtual methods*.
Finding all the functions to implement in a base class in the implementation classes is a little tedious, mostly because MSVC++ does not tell you which function you failed to implement with compiler error "Cannot construct abstract class"
So, I'm wondering is my large abstract base class a bad idea, or should I split it up into several interfaces, or is there a compiler warning I can activate that'll tell me WHICH method I failed to provide an implementation for.. or is this just a part of coding with abstract classes and I should get used to it.
*What it does is provide a layer of common functionality between a few different rendering subsystems.
There's no obvious correct answer to this question. Deciding whether to factor apart the base class into multiple abstract base classes should probably be a decision you make based on whether or not the base class logically represents several different concepts, rather than on poor compiler error messages. If the only reason you'd do this is for the compiler error messages, you might want to check and see if you can upgrade the compiler or if there's some other reason to do this. Most modern compilers should provide very nice, detailed errors about this.
Splitting the interface into pieces may be a good idea if your design suggests that you might actually want to have multiple different classes that implement just small pieces of the base class. If you expect to do this, it may be advantageous to factor the interface apart. You will see some added complexity from this, however. For example, if you have a pointer of one interface type to an object implementing multiple interfaces, you may have to do some sort of cross-cast to obtain the correct type, or you may have to introduce a new abstract class that represents something inheriting from all the different interface types. Multiple inheritance with interface classes might also lead to some name collisions, though this typically isn't a problem if the interfaces are designed correctly.
In short, I'd strongly suggest not doing this for the compiler error reason, but if you think it's a good design decision then by all means go for it. Compilers are good enough these days that you rarely (but not never) need to build your design around them.
Interface classes in my opinion are inherently bad, however the question as posed makes this particular application sound suspect.
If you have classes that are deriving from this interface, and it's not clear exactly what functions you need to override, that seems to indicate that all those functions may not be necessary.
When you craft an abstract base class, the number of pure virtual methods isn't important (to me), but it should be clear why every class that derives from this interface has to implement each pure virtual function. If you find yourself thinking "Why do I have to implement this function?", it may be appropriate to break the abstract class up into several distinct interfaces.
Anyway such a big class is a mess, God class antipatern. Use aggregation/composition to split a class and take a look at SOLID development principles, looks like 30 methods for a single class do not follows single responsibility principle, at least... so I wold like recommend to reconsider a design of class. Good luck!
Usually, right after the error "Cannot instantiate abstract class" (which is thrown at the line it was called), if you copied and pasted the interface into the class before writing the implementations, you'll get a linker error "Unresolved external error"pointing to the method you forgot to implement.
Let me start with a concrete example. In C++, I have a hierarchy of classes under the abstract base class CollisionVolume. Any collision volume needs to be able to detectCollision with any other volume. This collision code is specialized based on the two subclasses in presence, but it is commutative: detectCollision(a, b) == detectCollision(b, a).
I need to use a mechanism similar to virtual functions since the objects will typically be of the abstract base class. However, if I use typical virtual methods, the chosen function can only depend on the type of one of the operand, not both. The only way I was able to do this is using RTTI or an RTTI-like mechanism.
Is there any cleaner way to do this?
You're looking for multiple dispatch. C++ doesn't have it because it's hard to implement efficiently. Most other statically typed/efficiency-oriented languages don't either. Your RTTI solution is probably about the best way of faking it.
There are several solutions to emulate multimethods in C++.
Here some references that can helps you to solve your problem:
S.Meyers "More effective C++", Item 31: Making functions virtual with respect to more than one object.
A.Alexandrescu "Modern C++ design", Chapter 11. Multimethods
MultiMethods in C++: Finding a complete solution by Danil Shopyrin
Multiple Dispatch. A new approach using templates and RTTI by Dr. Carlo Pescio, C++ Report, June 1998.
Draft proposal for adding Multimethods to C++, here and here
My initial idea, which upon reading appears to be the visitor pattern(?), is to make a virtual function that returns some vital information about the object, then, in detectCollision(), compare the vital information returned by the two objects. That way, each object can return specialized information, but they can be compared in a generalized way.
This may not be the most efficient way of doing it, but it seems relatively simple.