override virtual method with template method [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Can a member function template be virtual?
In a base class, the function my_func is defined as virtual. However, in the derived class I would like to have my_func to be a template method. Is this possible?
It seems it isn't. I get the error "cannot allocate an object of abstract type", which I believe it is related to the fact that the compiler does not acknowledge the override of the virtual my_func in the base class. Does this reveal a poor design maybe?
Thanks a lot.
UPDATE:
Thanks for the answers. Some of you are suggesting I should post some of the code, so here it is.
In the base class:
virtual void Fill(EventInfo* info, EasyChain* tree, vector<Muon*>& muons, vector<Electron*>& electrons, vector<Jet*>& jets, LorentzM& met) = 0;
But in the derived class I would like to have:
template<typename _Jet>
void Fill(EventInfo* info, EasyChain* tree, vector<Muon*>& muons_in, vector<Electron*>& electrons_in, vector<_Jet>& jets_in, LorentzM& met){
From your answers, I understand that a solution to the problem would be to define another function in the derived class:
void Fill(EventInfo* info, EasyChain* tree, vector<Muon*>& muons, vector<Electron*>& electrons, vector<Jet*>& jets, LorentzM& met){
//
}
but then, this function and the template function are the same for the case of _Jet being Jet*, wouldn't that be a problem as well?
Some have suggested a design problem here, I guess that's true, I'll have to think about how to go around this then.

Your templated method overloads the original (same name but different parameters). You still have to override the original as well, to make your derived class non-abstract. You can do both no problem, so you will have two versions of the method in the derived class, just be careful and conscious of which one will get called...
You can then make the overriden overload version of method to call the new template overload version. This may or may not do what you want to achieve, depending on what you want to achieve...
It might still be better for the template method to have a different name, to avoid confusion, because you can not call it directly anyway, unless you have pointer of the derived class type. If you have pointer to the abstract base class, you must call the method with the parameters defined there, even if it is virtual method and a derived class method is what actually gets called.

The problem is that the template is changing the signature of the function, so it's no longer overriding the virtual function in the base class, therefore you class continues to be abstract.
Templating a virtual function seems to defeat the polymorphic nature of the virtual function in the base class.

The function in the derived class needs to have the same signature in order to properly override the function of your base class (and get rid of the abstract type error).
That means :
same name
same parameter number and types
same qualifiers (constness for example)
compatible return types (even though that's technically not part of the signature iirc)
So indeed, using template in that case can lead to that kind of error. The best would be to post a code sample so people could get a better idea of your specific case.

You can’t do that because the my_func template version is not covariant with the base class one. It’s a design problem you have here, btw.

Related

Is it better to cast a base class to derived class or create a virtual function on the base class?

According to this answer, dynamic_cast'ing a base class to derived class is fine, but he says this shows that there is a fundamental problem with the code logic.
I've looked at other answers and using dynamic_cast is fine since you can check the pointer validity later.
Now in my real problem the derived class has a GetStrBasedOnCP function which is not virtual (only the derived class has it) and I have to access it.
What is better, to create a virtual void GetStrBasedOnCP on the base class and make it virtual on the derived OR, to just cast the base class pointer to derived class?
Oh also notice that this is a unsigned int GetStrBasedOnCP so the base class must also return a value...
There are more than two answers to the "what is better" question, and it all depends on what you are modeling:
If the GetStrBasedOnCP function is logically applicable to the base class, using virtual dispatch is the best approach.
If having the GetStrBasedOnCP function in the base class does not make logical sense, you need to use an approach based on the actual type; you could use dynamic_cast, or
You could implement multiple dispatch, e.g. through a visitor or through a map of dynamic types.
The test for logical applicability is the most important one. If GetStrBasedOnCP function is specific to your subclass, adding it to the base class will create maintenance headaches for developers using and maintaining your code.
Multiple dispatch, on the other hand, gives you a flexible approach that lets you access statically typed objects. For example, implementing visitor pattern in your base class lets you make visitors that process the subclass with GetStrBasedOnCP function differently from other subclasses.
Does it make sense for the base class you have to have the virtual function in it?
If it does not then you should not include the function in the base class. Remember that best practices cover the general case. There are times you need to do things you wouldn't normally do to get the code working. The key thing is you need is clear, concise, understandable code
There's a lot of "it depends".
If you can guarantee that the base pointer is the correct child pointer, then you can use dynamic_cast.
If you can't guarantee which child type the base pointer is pointing to, you may want to place the function in the base class.
However, be aware that all children of the base class will get the functionality of whatever you place into the base class. Does it make sense for all the children to have the functionality?
You may want to review your design.

Undefined reference to class_name<template_argument>function_name(variable)?

I'm getting a fatal linking error in the code below, it says:
]+0x10)||undefined reference to `base<node>::pass_derived(node)'|
I wanted to define a base class which has a pointer called poly_type and the base class can also "access" from within itself another class called derived. The problem I run into is line poly_type->pass_derived(n); where the compiler doesn't want to see the derived class where I tried to pass an object of type node. I'm guessing this is a limitation of C++, if so let me know. Heres the broken code,
edit seems like this has been asked somewhere else, I updated the source to reflect that opinion.
There is no definition of pass_derived in the base class.
You declare it as a virtual function but only define it in the derived class.
Because it instantiates base in the main function, the compiler tries to generate code for base but it does not find a definition for pass_derived.
You could add a default implementation - even if it is just empty.
As for whether you can eventually get it to call derived::pass_derived instead... :) good luck, it looks like fun. You are building your own version of inheritance?
The issue is here:
template < class T>
class base
{
// ...
virtual void pass_derived(T data);
};
You declared pass_derived as virtual but not pure virtual. Therefore, the linker raises an error if you don't provide an implementation.
Either you provide an implementation or (which I believe is your intent) you declare it pure virtual:
virtual void pass_derived(T data) = 0;
but then you cannot instantiate base<T> and must work only with pointers or references to base (which actually point/refer to derived).

Is there a way to call a base function outside of the class in C++?

This question is similar, but is about calling the function from inside the class: Can I call a base class's virtual function if I'm overriding it?
In that case, you'd specify Base::function() instead of function(), which will call the overridden definition.
But is there a way to do this outside of the class? My class doesn't define a copy constructor, so I couldn't figure out how to cast as the base class:
Base( derived_object ).function()
Is the appropriate thing to do here to cast & derived_object as Base* and then call ->function()?
Thanks for your insight.
Try derived_object.Base::function();
I believe the syntax:
derived_ptr->Base::function();
works just fine. Though I really question why you would want to do this in a function that's not part of your class. Especially if function happens to be a virtual function.
The reason why it's a questionable idea is that you're making whatever it is that uses that notation depend on the inheritance hierarchy of your class. Also, functions are usually overridden for a reason. And you're getting around that by using this syntax.
You probably want to use pointers to member functions of a class. Those give you the ability to map different base class functions to the pointer as needed, and the ability to use it as a variable or function parameter.
The syntax for a pointer to a member function looks like
class Base
{
public:
virtual bool Function();
virtual bool OtherFunction();
};
typedef bool (Base::*)() BaseFunc;
The list of caveats for using these things is a mile long- there is plenty online on how to use them (most of the answers are "don't"). However, they do give you a way of clearly binding to and calling a base class member function.

Why can't we create objects for an abstract class in C++?

I know it is not allowed in C++, but why? What if it was allowed, what would the problems be?
Judging by your other question, it seems you don't understand how classes operate. Classes are a collection of functions which operate on data.
Functions themselves contain no memory in a class. The following class:
struct dumb_class
{
void foo(){}
void bar(){}
void baz(){}
// .. for all eternity
int i;
};
Has a size of int. No matter how many functions you have ever, this class will only take up the space it takes to operate on an int. When you call a function in this class, the compiler will pass you a pointer to the place where the data in the class is stored; this is the this pointer.
So, the function lie in memory somewhere, loaded once at the beginning of your program, and wait to be called with data to operate on.
Virtual functions are different. The C++ standard does not mandate how the behavior of the virtual functions should go about, only what that behavior should be. Typically, implementations use what's called a virtual table, or vtable for short. A vtable is a table of function pointers, which like normal functions, only get allocated once.
Take this class, and assume our implementor uses vtables:
struct base { virtual void foo(void); };
struct derived { virtual void foo(void); };
The compiler will need to make two vtables, one for base and one for derived. They will look something like this:
typedef /* some generic function pointer type */ func_ptr;
func_ptr __baseTable[] = {&base::foo};
func_ptr __derivedTable[] = {&derived::foo};
How does it use this table? When you create an instance of a class above, the compiler slips in a hidden pointer, which will point to the correct vtable. So when you say:
derived d;
base* b = &d;
b->foo();
Upon executing the last line, it goes to the correct table (__derivedTable in this case), goes to the correct index (0 in this case), and calls that function. As you can see, that will end up calling derived::foo, which is exactly what should happen.
Note, for later, this is the same as doing derived::foo(b), passing b as the this pointer.
So, when virtual methods are present, the class of the size will increase by one pointer (the pointer to the vtable.) Multiple inheritance changes this a bit, but it's mostly the same. You can get more details at C++-FAQ.
Now, to your question. I have:
struct base { virtual void foo(void) = 0; }; // notice the = 0
struct derived { virtual void foo(void); };
and base::foo has no implementation. This makes base::foo a pure abstract function. So, if I were to call it, like above:
derived d;
base* b = &d;
base::foo(b);
What behavior should we expect? Being a pure virtual method, base::foo doesn't even exist. The above code is undefined behavior, and could do anything from nothing to crashing, with anything in between. (Or worse.)
Think about what a pure abstract function represents. Remember, functions take no data, they only describe how to manipulate data. A pure abstract function says: "I want to call this method and have my data be manipulated. How you do this is up to you."
So when you say, "Well, let's call an abstract method", you're replying to the above with: "Up to me? No, you do it." to which it will reply "##^##^". It simply doesn't make sense to tell someone who's saying "do this", "no."
To answer your question directly:
"why we cannot create an object for an abstract class?"
Hopefully you see now, abstract classes only define the functionality the concrete class should be able to do. The abstract class itself is only a blue-print; you don't live in blue-prints, you live in houses that implement the blue-prints.
The problem is simply this:
what should the program do when an abstract method is called?
and even worse: what should be returned for a non-void function?
The application whould proabably have to crash or thow a runtime exception and thus this would cause trouble. You can't dummy-implement every abstract function.
A class can simply be declared abstract where it has no abstract methods. I guess that could be instantiated in theory but the class designer doesn't want you to. It may have unintended consequences.
Usually however abstract classes have abstract methods. They can't be instantiated for the simple reason that they're missing those methods.
Because logically it does not make any sense.
An abstract class is a description that is incomplete.
It indicates what things need to be filled out to make it complete but without those bits its not complete.
My first example was a chess game:
The game has lots of pieces of different type (King,Queen,Pawn ... etc).
But there are no actual objects of type piece, but all objects are instances of objects derived from piece. How can you have an object of something that is not fully defined. There is not point in creating an object of piece as the game does not know how it moves (that is the abstract part). It knows it can move but not how it does it.
Abstract classes are non-instantiable by definition. They require that there be derived, concrete classes. What else would an abstract class be if it didn't have pure virtual (unimplemented) functions?
It's the same class of question as why can't I change the value of a const variable, why can't I access private class members from other classes or why can't I override final methods.
Because that's the purpose of these keywords, to prevent you from doing so. Because the author of the code deemed doing so dangerous, undesired or simply impossible due to some abstract reasons like lack of essential functions that need to be added by specific child classes. It isn't really that you can't instantiate because a class is virtual. It's that inability to instantiate a class defines it as virtual (and if a class that can't be instantiated isn't virtual, it's an error. Same goes the other way, if instance of given class makes sense, it shouldn't be marked as virtual)
Why we cant create an object of an abstract class?
simply abstract class contains abstract methods(means the functions which are without the body) and we cannot give functionality to the abstract methods. And if we try to give functionality to the abstract methods then there will be no difference between abstract class and virtual class. So lastly if we create an object Of an abstrast class then there is no fun to call the useless functions or abstract methods as they are without the functionality..so thats why any language doesnt allow us to create an object of an abstract class..
Abstract classes instantiated would be pretty useless, because you would be seeing a lot more of "pure virtual function called". :)
It's like: we all know that a car would have 3 pedals and a steering wheel and a gear stick. Now, if that would be it, and there'd be an instance of 3 pedals and gear stick and a wheel, I'm not buying it, I want a car, like with seats, doors, AC etc. with pedals actually doing something apart from being in existence and that's what abstract class doesn't promise me, the ones implementing it do.
Basically creation of object is responsible for allocation of memory for member variables and member functions. but here, in pure virtual function we have declaration and defination in derived class.so creation of object generates error.

Is there a way to prevent a method from being overridden in subclasses?

Is anyone aware of a language feature or technique in C++ to prevent a child class from over riding a particular method in the parent class?
class Base {
public:
bool someGuaranteedResult() { return true; }
};
class Child : public Base {
public:
bool someGuaranteedResult() { return false; /* Haha I broke things! */ }
};
Even though it's not virtual, this is still allowed (at least in the Metrowerks compiler I'm using), all you get is a compile time warning about hiding non-virtual inherited function X.
When you can use the final specifier for virtual methods (introduced with C++11), you can do it. Let me quote my favorite doc site:
When used in a virtual function declaration, final specifies that the function may not be overridden by derived classes.
Adapted to your example that'd be like:
class Base {
public:
virtual bool someGuaranteedResult() final { return true; }
};
class Child : public Base {
public:
bool someGuaranteedResult() { return false; /* Haha I broke things! */ }
};
When compiled:
$ g++ test.cc -std=c++11
test.cc:8:10: error: virtual function ‘virtual bool Child::someGuaranteedResult()’
test.cc:3:18: error: overriding final function ‘virtual bool Base::someGuaranteedResult()’
When you are working with a Microsoft compiler, also have a look at the sealed keyword.
A couple of ideas:
Make your function private.
Do not make your function virtual. This doesn't actually prevent the function from being shadowed by another definition though.
Other than that, I'm not aware of a language feature that will lock away your function in such a way which prevents it from being overloaded and still able to be invoked through a pointer/reference to the child class.
Good luck!
Sounds like what you're looking for is the equivalent of the Java language final keyword that prevents a method from being overridden by a subclass.
As others here have suggested, you really can't prevent this. Also, it seems that this is a rather frequently asked question.
(a) I dont think making function private is the solution because that will just hide the base class function from the derived class.The derived class can always define a new function with the same signature.
(b) Making the function non virtual is also not a complete solution because, if the derived class redefines the same function , one can always call the derived class function by compile time binding i.e obj.someFunction() where obj is an instance of the derived class.
I dont think there is a way of doing this.Also,i would like to know the reason for your decision to prohibit derived classes from overriding base class functions.
a compile time warning about hiding non-virtual inherited function X.
change your compiler settings to make it a error instead of warning.
I guess what the compiler warns you about is hiding !! Is it actually being overridden ?
compiler might give you a warning, but at runtime, the parent class method will be called if the pointer is of type parent class, regardless of the actual type of the object it points to.
This is interesting. Try making a small standalone test program for your compiler.
For clarification, most of you misunderstood his question. He is not asking about "overriding" a method, he is asking whether there is a way to prevent "hiding" or not. And the simple answer is that "there is none!".
Here's his example once again
Parent class defines a function:
int foo() { return 1; }
Child class, inheriting the Parent defines the same function AGAIN (not overriding):
int foo() { return 2; }
You can do this on all programming languages. There is nothing to prevent this code from compiling (except a setting on the compiler). The best you'll get is a warning that you are hiding the parent's method. If you call the child class and invoke the foo method, you'll get 2. You have practically broken the code.
This is what he is asking.
If you address the child class as a type of its parent, then a non-virtual function will call the parent class's version.
ie:
Parent* obj = new Child();
Unless you make the method virtual, the child class cannot override it. If you want to keep child classes from calling it, make it private.
So by default C++ does what you want.
Trying to prevent someone from using the same name as your function in a subclass isn't much different than trying to prevent someone from using the same global function name as you have declared in a linked library.
You can only hope that users that mean to use your code, and not others', will be careful with how they reference your code and that they use the right pointer type or use a fully qualified scope.
In your example, no function is overridden. It is instead hidden (it is a kind of degenerated case of overloading).
The error is in the Child class code. As csmba suggested, all you can do is changing your compiler settings (if possible) ; it should be fine as long as you don't use a third party library that hides its own functions.
Technically u can prevent virtual functions to be be overridden. But you will never ever been able to change or add more. That is not help full. Better to use comment in front of function as faq lite suggests.
I was searching for same and yesterday came to this [rather old] question.
Today I found a neat c++11 keyword : final . I thought it may be useful for next readers.
http://en.cppreference.com/w/cpp/language/final
C++ methods are private and un-overridable by default.
You cannot override a private method
You cannot override a non-virtual method
Are you perhaps referring to overloading?