I have a linked list class (List) that deals only with objects of type Node. It can do all sorts of things with these Nodes assuming that they have boolean comparisons overloaded properly. The thing is, I want to use this List class with a special kind of Node called a Term (an algebraic term with a coefficient and an exponent or degree). How do I tell my List class to use the Term functions (Term has special versions of the Print() function and comparison operators) even though it deals with the Terms using Node pointers? For example, my Print() is something like:
Node* walker=head;
while(walker)
{
walker->Print();
walker=walker->next;
}
Except there is no Node::Print(), I want it to call Term::Print()! Do I have to make a whole new List class to deal with Term class objects?
This is a classic example of Polymorphism. You can add a function Print() to your Node class just like WhozCraig suggested. (Please read up Virtual Functions and Abstract classes in C++.) You can make Print() a virtual function. You can decide whether you want to make Print() a pure virtual function. If it's a pure virtual function, it will be declared like this in the base class.
class Node{
virtual void Print() = 0;
// If you don't want this to be pure virtual
// You can give a generic definition
}
In this case, since you did not define Print() in the base class, each derived class which is not meant to be abstract, must implement this method. Thus, the Term class can derive from Node class and implement it's Print() method accordingly :) And you can use the base class pointer to call this function. If in the future you decide to subclass Node and add a different implementation of Print(), you don't have to change Node at all :)
Hope this helps!
You're already diverging from usual list design - would recommend using templates instead of deriving from Node class. You then would want a foreach method which will do an operation on each node, in this case print. Strongly recommend using the C++ standard library containers instead of coding all this "raw".
Another option (less standard and with design flaws) would be to derive out a PrintList that will call the Print function, and it will need to be templated or to be done in terms of Term nodes as the compiler will expect this function.
Three choices:-
In the real world, you would use std::list or a similar container class
Or, you can add Print() as a virtual method to Node, (and make it abstract, potentially)
class Node {
...
virtual void Print() = 0;
}
Or, you can use cast the Node* to a Term*
Term *t = boost::polymorphic_cast<Term*>(walker);
t->Print();
Related
I asked a similar question earlier, but deleted it because I couldn't come up with a specific example. I was able to come up with one now. I often find myself designing codes such that virtual functions are only useful in some, but not all, of the subclasses.
Here is an example of a base class travel that is inherited by driving and flying. travel has a compute_travel_info() function that computes the velocity and altitude. The former is relevant for both driving and flying, but the latter is only relevant for flying.
In this design, driving::compute_altitude() does nothing, but we must define it because the function is pure virtual (I could alternatively made it a virtual function in travel and defined it, and then not override it in driving). Also, ideally, I wouldn't even want to call the compute_altitude() function in compute_travel_info if it was operating on a driving object, so the code can appear to be misleading the way it is written.
Is what I did considered to be bad practice? Is it frowned on to have a virtual function that is useless in one of the subclasses and to call the virtual function that isn't used in some of the subclasses?
Note that this is just a particular example, and ideally, I'd like an answer that applies generically, and not just to the specific example provided. In other words, I don't want readers to be too fixated on this example
class travel
{
public:
//function for representing the state in bits
void compute_travel_info()
{
compute_velocity();
compute_altitude();
}
private:
double velocity;
virtual void compute_velocity() = 0;
virtual void compute_altitude() = 0;
};
class flying : domain
{
void compute_velocity()
{
//compute the velocity
}
void compute_altitude()
{
//compute the altitude
}
};
class driving : travel
{
void compute_velocity()
{
//compute the velocity
}
void compute_altitude()
{
//do nothing (assume car is driving on a flat earth where altitude doesn't change)
}
};
Clearly compute_altitude is not supposed to be part of your virtual interface since calling it through a base pointer is not guaranteed to do anything reasonable if it is implemented as stub in the derived class.
However, compute_travel_info does seem to be part of the virtual interface that should always be callable through a base pointer.
Therefore compute_travel_info should be (pure) virtual and implemented in all derived classes. Some of these derived classes may have a compute_altitude function that is called and some might not, but that shouldn't matter to the base class. The base class should not have a compute_altitude function at all.
You can provide a default implementation for compute_travel_info in the base class which is only overridden when needed.
You can also call the base class implementation of compute_travel_info in the derived class with a qualified name (e.g. this->travel::compute_travel_info()) if you need to just add some additional work to it.
Or you can move the common behavior into another base class function that is called by the compute_travel_info implementations in the derived classes.
You could add an override of the function compute_travel_info in flying.
In this redefined function you can call back to the function of the parent class which would only hold the compute_velocity function and then call the compute_altitude function only in the overridden function.
I've a question regarding a concept. First, I'm a mechanical engineer and not a programmer, thus I have some C++ knowledge but not much experience. I use the finite element method (FEM) to solve partial differential equations.
I have a base class Solver and two child linSolver, for linear FEM, and nlinSolver for non-linear FEM. The members and methods that both children share are in the base class. The base class members are all protected. Thus using inheritance makes the child classes "easy to use", like there weren't any inheritance or other boundaries. The base class itself, Solver, is incomplete, meaning only the children are of any use to me.
The concept works actually pretty good - but I think that having an unusable class is a bad design. In addition I read that protected inheritance is not preferred and should be avoided if possible. I think the last point don't really apply to my specific use, since I will never use it allow and any attempt to do so will fail (since it is incomplete).
The questions are:
Is it common to use inheritance to reduce double code even if the base class will be unusable?
What are alternatives or better solutions to such a problem?
Is protected inheritance really bad?
Thank you for your time.
Dnaiel
Having "unusable" base classes is actually very common. You can have the base class to define a common interface usable by the classes that inherits the base-class. And if you declare those interface-functions virtual you can use e.g. references or pointers to the base-class and the correct function in the inherited class object will be called.
Like this:
class Base
{
public:
virtual ~Base() {}
virtual void someFunction() = 0; // Declares an abstract function
};
class ChildA : public Base
{
public:
void someFunction() { /* implementation here */ }
};
class ChildB : public Base
{
public:
void someFunction() { /* other implementation here */ }
};
With the above classes, you can do
Base* ptr1 = new ChildA;
Base* ptr2 = new ChildB;
ptr1->someFunction(); // Calls `ChildA::someFunction`
ptr2->someFunction(); // Calls `ChildB::someFunction`
However this will not work:
Base baseObject; // Compilation error! Base class is "unusable" by itself
While the (working) example above is simple, think about what you could do when passing the pointers to a function. Instead of having two overloaded functions each taking the actual class, you can have a single function which takes a pointer to the base class, and the compiler and runtime-system will make sure that the correct (virtual) functions are called:
void aGlobalFunction(Base* ptr)
{
// Will call either `ChildA::someFunction` or `ChildB::someFunction`
// depending on which pointer is passed as argument
ptr->someFunction();
}
...
aGlobalFunction(ptr1);
aGlobalFunction(ptr2);
Even though the base-class is "unusable" directly, it still provides some functionality that is part of the core of how C++ can be (and is) used.
Of course, the base class doesn't have to be all interface, it can contain other common (protected) helper or utility functions that can be used from all classes that inherits the base class. Remember that inheritance is a "is-a" relationship between classes. If you have two different classes that both "is-a" something, then using inheritance is probably a very good solution.
You should check the concept of Abstract class.
It's designed to provide base class that cannot be instantiated.
To do so you provide at least one method in the base class like this
virtual void f()=0;
Each child have to override the f function (or any pure virtual function from the base class) in order to be instantiable.
Don't think of the BaseClass as a class in its own right, but as an interface contract and some implementation help. Therefore, it should be abstract, if neccessary by declaring the dtor pure virtual but providing an implementation anyway. Some OO purists may frown upon any non-private element, but purity is not a good target.
I found there has many definition about polymorphism and overloading. Some people said that overloading is one type of polymorphism. While some people said they are not the same. Because only one function will be allocate in overloading. While the polymorphism need allocate the memory for each redefined member function. I really feel confusion about this, any one could explain this for me?
Further, whether overloading happens at compile time while the polymorphism happens at running time?
Polymorphism is the process to define more than one body for functions/methods with same name.
Overloading IS a type of polymorphism, where the signature part must be different. Overriding is another, that is used in case of inheritance where signature part is also same.
No, it's not true that polymorphism happens in runtime. What happens in runtime is called runtime polymorphism. That is implemented using virtual keyword in C++.
Hope it helped..
The polymorphism is the base of the OOP, the overloading is one of ways to implement to polymorphism, specially when are involved operators. More generally, speaking about polymorphism when there are two or more classes involved. While the overloading can be made also inside the same class, we can overload the name of a method with several signatures (different list of parameters). While overriding is designed exclusively for involving two or more classes. Note that the overrided methods have all the same signature.
this was told by Bjarne Stroustrup in his book,polymorphism is one which a single thing that act in many forms (i.e) A single function that act in many forms with different parameters. since in c++ constructor name have to be same as class name, you cant have different constructors with different name. so to overcome that function overloading came. many people confuse that function overloading is a type of of polymorphism. they are both at different ends they cant be tied together.
You cannot determine whether a method is a polymorphic method, or simply an overridden method based solely upon its signature. You need to see how the method is invoked.
Here is some sample code which may help illuminate the answer:
public class parentClass {
//Overridden method
public void disp()
{
System.out.println("Output: disp() method of parent class");
}
}
public class childClass extends parentClass {
//You cannot determine whether these methods are polymorphic
//or static polymorphic (aka overridden) simply by their signatures.
//It is by the way they are invoked which determines this.
public void disp(){
System.out.println(" Output: disp() method of Child class");
}
public long add(long a, long b){
return a + b;
}
public int add(int a, int b){
return a+b;
}
public String add(String a, String b){
return a + b;
}
public static void main( String args[]) {
//Here a child class has overridden the disp() method of the
//parent class. When a child class reference refers to the child
//class overriding method this is known as static polymorphism
//or more simply, overriding.
System.out.println("childClass referencing the childClass's overridden, or static polymorphic method");
childClass myChildObj = new childClass();
myChildObj.disp();
//Another example of static polymorphic, or overridden methods
System.out.println("The following are overridden, or static polymorphic methods:");
System.out.printf(" Long add()override method results: %d \n",
myChildObj.add(5999999, 1));
System.out.printf(" Integer add() override method results: %d \n", myChildObj.add(3,2));
System.out.printf(" String add() override method results: %s \n",
myChildObj.add(" First and ...", " Second"));
//When the parent class reference refers to the child class object
//then the overriding method is called.
//This is called dynamic method dispatch and runtime polymorphism
System.out.println("True polymorphism, when the parent class object calls the child class's method:");
parentClass myParentObj = new childClass();
myParentObj.disp();
}
}
The expected output:
childClass referencing the childClass's overridden, or static polymorphic method
Output: disp() method of Child class
The following are overridden, or static polymorphic methods:
Long add()override method results: 6000000
Integer add() override method results: 5
String add() override method results: First and ... Second
One example of true polymorphism, when the parent class object calls the child class's method:
Output: disp() method of Child class
The word itself exlains the clear meaning. 'Poly' means multiple, while 'morphism' (used in image technology) means the process of gradual change from one form to another. Thus, same thing will have different forms.
Technically, Polymorphism is way of implementing 'Single Interface (Skeleton or structure) multiple Implementation (content or body)'. Polymorphism is a general term which refers to both overloading and overriding. Overloading is done in same class where the functions or methods with the same name have different signatures (argument list or return type) while overriding comes in picture in case of inheritance where a function interface, in the Super class, has similar interface in the subclass and has different implementation than the one in super class.
The Super class and sub class form a hierarchy moving from lesser specialization to greater specialization and this should always be remembered while implementing overriding of functions.
Function overloading takes place with functions having same name, but with different parameters.
In polymorphism the functions having same name are chosen based on its objects.
Polymorphism is based on following 2 concepts:
Overloading(Compile-Time polymorphism): Methods with same name but different operation
Overriding(Run-Time polymorphism): Override a method in base class by creating similar method in derived class
-Corrected the Explainations
Shyam Kodase
Overloading is just a way of providing multiple ways of calling the same method/function/constructor with default values, less arguments etc.
Polymorphism is about object inheritance, sub classes etc.
Being new to C++, I have trouble understanding a linkage problem I'm having. The following is the file that's giving me a headache:
#pragma once
#include <string>
#include "finite_automaton.h"
template<typename RL>
class RegularLanguage {
public:
bool empty();
RegularLanguage<RL> minimize();
RegularLanguage<RL> complement();
RegularLanguage<RL> intersectionWith(RegularLanguage<RL> other);
RegularLanguage<RL> unionWith(RegularLanguage<RL> other);
RegularLanguage<RL> concatenate(RegularLanguage<RL> other);
RegularLanguage<RL> kleeneStar();
/*
* Returns a regular expression that describes the language of this automaton.
*/
std::string string();
bool disjoint(RegularLanguage<RL> other) {
return intersectionWith(other).empty();
}
bool containedIn(RegularLanguage<RL> super) {
return intersectionWith(super.complement()).empty();
}
bool contains(RegularLanguage<RL> sub) {
return complement().intersectionWith(sub).empty();
}
bool equals(RegularLanguage<RL> other) {
return contains(other) && containedIn(other);
}
};
When I compile the project, I get the following errors during the linking phase:
undefined reference to `RegularLanguage<FiniteAutomaton>::complement()'
undefined reference to `RegularLanguage<FiniteAutomaton>::intersectionWith(RegularLanguage<FiniteAutomaton>)'
undefined reference to `RegularLanguage<FiniteAutomaton>::empty()'
both for RegularLanguage<RL>::containedIn(..) and RegularLanguage<RL>::contains(..).
What am I doing wrong? I do get some related errors pertaining to the classes that implement this template class, but I left them out so as not to post unnecessarily much code.
So to summarize what you're trying to do, you have a class template:
template<typename RL> class RegularLanguage {...};
with some methods implemented and others only declared, but not implemented. Then you try to derive from this and in the derived class implement those other methods that weren't implemented in RegularLanguage:
class FiniteAutomaton : public RegularLanguage<FiniteAutomaton>
You seem to be conflating two concepts in C++: inheritance (specifically, polymorphism) and templates.
Your assumption was that by inheriting from RegularLanguage you can implement the missing stuff in the derived class. That's not how templates work, but polymorphism does work that way. You need to either:
Fully implement all methods in the class template RegularLanguage, and then derive FiniteAutomaton from that.
Make RegularLanguage an abstract base class -- not a class template -- with (possibly pure) virtual methods, and derive from that. The methods you want to be implemented in FiniteAutomaton can be. Those may or may not be pure. The methods you don't want to implement in the base class should be declared as pure (=0), and then implemented in the derived class.
It sounds to me like what you're really trying to do would be better accomplished with #2, so here's an incomplete example of how to do that:
class RegularLanguage {
public:
virtual RegularLanguage* Clone() = 0; // Creates a copy of this object
virtual RegularLanguage& complement() = 0; // pure virtual must be implemented in derived class
virtual bool containedIn(RegularLanguage& super) // non-pure, does not have to be implemented in derived
{
return intersectionWith(super.complement()).empty();
}
virtual ~RegularLanguage() {}
};
class FiniteAutomaton
:
public RegularLanguage
{
public:
RegularLanguage* Clone()
{
RegularLanguage* clone = new FiniteAutomaton (*this);
return clone;
}
RegularLanguage* complement()
{
RegularLanguage* comp = this->Clone();
comp->SetSomeStuff();
return comp;
}
};
There are a number of details hidden up there that I haven't mentioned. For one, the return type of complement is now a RegularLanguage pointer, rather than a RegularLanguage by-value. This is required1 in order to avoid the so-called Slicing Problem which would break polymorphism.
For another, I have abandoned the use of templates here because as I've implemented this, there is no apparent need for them. However the use of templates and polymorphism are not completely mutually exclusive. The base class could employ templates, and in fact the base class could be a class template and still be an abstract base class. But the derived class must derive from a concrete instantiation of that base class template. Things get somewhat complicated here. Just be careful that you're not seeing everything as a nail and get carried away with that hammer.
For another, I didn't implement a virtual destructor in the base class before (this is fixed now) but you must2. Just remember this: if a class is intended to be derived from, it should have a virtual destructor in virtually every case.
For another, I've added a Clone method to the base class as a pure virtual. This was in response to the suggestion that complement() shouldn't return this instance of the object, but a new instance which is the complement of this instance. In a polymorphic hierarchy, when we make copies of object we almost always need to do so through the base class pointer, so a Clone() type method is usually present in such a design.
1 "This is required [passing by pointer]: Actually, you could return a reference as well. Return a reference if you can, but here we need to return a pointer. (Actually we should be returning smart pointers, but that's a tangent.)
2 "You must [implement a virtual destructor]: Technically, you need to have a virtual destructor if you intend to delete the object through a base class pointer. I have never in my professional career seen an instance where I could not or should not implement a virtual destructor in the base class of a polymorphic hierarchy. It's close to correct to say you should always do this, even if you have no plans to delete through a base class pointer.
You need to declare bool empty() (and others not implemented in the base) as a pure virtual in the base class:
virtual bool empty() = 0;
and then override/implement them in a descendant class like this:
virtual bool empty(){
...
}
There is a series of problems with this code. The most obvious one has been pointed out: you need your functions pure virtual. But that's just the beginning.
When you make your functions pure virtual, you will immediately notice that the code does not compile any more. The tools will tell you that you cannot instantiate an abstract class. The reason is that you return objects of type ReguarLanguage<...> from your functions by value, thereby invoking the Curse of Object Slicing (look it up). The inability to instantiate an abstract class is just manifestation of Object Slicing.
In order to dispel the dreaded curse, you will have to do the Rite of Return by Pointer, and thereby invoke the lesser curse of Manual Memory Management (this is relatively easily defeated with a bit of Smart Pointer Magic these days).
But you are not only returning languages, you are also accepting them as arguments. Here you need a simpler incantation of Passing by Reference, which does not require any manual memory management. It looks like in your case you can implement the intersection and all the other things by using just the public interface of the "other" argument, so this simple change should suffice.
Oh, and don't forget the virtual destructor. Never forget the virtual destructor... only omit it if you know you don't need it, which is, if your class fits the OO paradigm, never.
If you look at your RegularLanguage class template, you may notice that it never use its template parameter. If this is the case, it can be safely de-templatized. No, wait, it does use the parameter — how else could it create e.g. a complement?
To put it simply, if you have a finite automaton that parses a language, the parser of the complement doesn't have to be a finite automaton. It may contain or reference a FA (or something else!) instead. So you may want to have a subclass of RegularLanguage called Complement that will contain a (polymorphic!) reference to another RegularLanguage — without even having to know what kind of parser is hidden inside that one.
I am working on a C++ project, specifically implementing a shunting yard algorithm.
I have a function that creates a vector of shared_ptr's of type super class, but the classes that are being pushed into this vector are all base class shared_ptrs.
I then need to take this vector and pass it into another function and carry out different logic for each element of the vector in a for loop. The logic that I carry out, however, depends on which base class is present in each element of the vector.
So basically what I don't know is how to identify which type of base class is in each element of the vector. When I debug they are all coming out as type super-class.
So generally I'd like to do something like this:
if(vectorElement == baseClass)
{
//do some logic
}
Or if there is some different method of carrying this out which I'm missing I'd be interested in carrying that out.
There are many solutions to your problem, frankly is the almost most common problem in OOP.
The most obvious is the virtual function doing different things in different classes:
class SuperClass {
public:
virtual void doSomething(/*someArgsIfNeeded*/) {
// some base implementation, possible empty
// or just use pure virtual function here
}
};
class SubClass : public SuperClass {
public:
virtual void doSomething(/*someArgsIfNeeded*/) {
// some base implementation
}
};
Then use it as follows:
int SomeArgs;
std::vector<std::shared_ptr<SuperClass>> objects;
for (auto it = objects.begin(); it != objects.end(); ++i)
it->doSomething(/*someArgsIfNeeded*/);
Other more sophisticated solution is to use visitor pattern.
It is considered a bad practice to use casting (dynamic_cast), so always search for more OO solutions than casting, like these two I presented above.
Off the top of my head, a simple solution would be to have a function in the base class, that returns an int signifying which class it is. And in each of the derived classes, override this function to return different values. You could use that value to determine which class is being stored in the vector
Edit: And Generally class specific details are to be left in the class, which is the point of polymorphism. Try to do the derived class specific calculations as an overided member function within each class, and use that just to fetch the value forgoing the need for large for loops (for each new derived class) outside.