class Base{
//...
public:
int get()const{ // const
// Do something.
}
int get(int x){
// Do Someting.
}
//...
};
class Derived:public Base{
//....
public:
int get(){ // not const (not the same signature as the one is the base class)
//Dosomething
}
//...
};
I know that get() in Derived class will hide get() and get(int x) methods inside Base class. so My question is:
1) is this consedred overloading or overriding ?
2) does making get() const in the derived class will change something about (hiding or not hiding Base class methods).
Quote from a c++ book:
"It is a common mistake to hide a base class method when you intend to override it, by
forgetting to include the keyword const. const is part of the signature, and leaving it off
changes the signature, and thus hides the method rather than overrides it. "
It is neither overloading nor overriding. Rather, it is hiding.
If the other function were also visible, it would be overloading, which you can achieve with using:
class Derived : public Base
{
public:
using Base::get;
int get();
};
Even if you declared int get() const in the derived class, it would merely be hiding the base function, since the base function is not virtual.
Neither, it's just "hiding".
No. Hiding occurs based on function name, not on function signature.
Your quote is only relevant if you've declared the base-class functions virtual; you cannot override a non-virtual function.
Overloading is a function named the same, but with a different signature.
Overriding is overriding a signature that already exist.
You have just "hidden", which is neither.
A quick google search reveals this:
http://users.soe.ucsc.edu/~charlie/book/notes/chap7/sld012.htm which you may find helpful.
Related
So here is the base class:
class MovieRepo {
protected:
MyLista<Movie> all;
public:
MovieRepo();
void store(const Movie& m);
}
And this one is the override:
class RepoFile : public MovieRepo
{
private:
string filename;
void loadFromFile();
void storeToFile();
public:
RepoFile(string _filename) : filename{ _filename } { this->loadFromFile(); };
void store(const Movie& m) override { // here is the error
MovieRepo::store(m);
storeToFile();
}
}
It says:'RepoFile::store': method with override specifier 'override' did not override any base class methods
MovieRepo::store() is not a virtual function. The override specifier only works with virtual functions. Change the base class method to a virtual method to fix the issue.
The override keyword can only be used when the function it's overriding is virtual. (It is, effectively, just a 'safer' way of specifying virtual in a derived class, so that you can spot cases where there is no matching base-class function.)
cppreference
Fix: Either remove the override keyword (the base-class function will still be overriden) or add virtual to the base-class function).
The key to the solution is the keyword virtual.
The virtual specifier specifies that a non-static member function is virtual and supports dynamic dispatch. It may only appear in the decl-specifier-seq of the initial declaration of a non-static member function (i.e., when it is declared in the class definition).
See this for why do we need virtual functions?. With "virtual" we get "late binding". Which implementation of the method is used gets decided at run time based on the type of the pointed-to object - what it was originally constructed as (not on the type of the pointer that you call through!).
If you want such "late binding" and want to invoke the right method (store) at run-time irrespective of the type of the pointer that you use to call store(), then go ahead with virtual functions with the implementation below:
Try this:
class MovieRepo {
public:
// ....
virtual void store(const Movie& m);
}
class RepoFile: public MovieRepo {
public:
void store(const Movie& m) override
{
// ....
}
}
More details on compilation warning/error:
The override keyword serves two purposes:
It shows the reader of the code that "this is a virtual method, that is overriding a virtual method of the base class."
The compiler also knows that it's an override, so it can "check" that you are not altering/adding new methods that you think are overrides.
In your case, compiler is warning you that the method your virtual function (in class RepoFile) isn't overriding any virtual function in base class.
In Cplusplus, in a derived class, if we define a member function to override a member function in its parent class, do we need to declare the one in the derived class to be virtual?
For example, do we need to declare g to be virtual in B in order for it to override A::g? which one of the following is correct for the above purpose?
class A{
public:
void f(){printf("A");}
virtual void g(){printf("A");}
}
class B : public A{
public:
void f(){printf("B");}
void g(){printf("B");}
}
or
class A{
public:
void f(){printf("A");}
virtual void g(){printf("A");}
}
class B : public A{
public:
void f(){printf("B");}
virtual void g(){printf("B");}
}
Thanks.
Once a method is virtual in a class, its child class has also these virtual class even if you don't add virtual to them.
Adding override is a good habit to avoid subtle error:
class A{
public:
void f() { printf("A"); }
virtual void g() { printf("A"); }
};
class B : public A{
public:
void f() { printf("B"); }
void g() override { printf("B"); }
};
No you don't. The function is virtual from the first point in the hierarchy where you declare it as such.
You can and should specify it as override in c++11 and onward. It specifies explicitly to the compiler that you are trying to override a virtual function in a base class. It than emits an error if you misspell the function name, mistype the parameters or do anything else that can be considered as adding an overload of the function. Prior to c++11, the previous mistakes would silently compile.
Defining member functions virtual in derived classes is optional. You can make the override explicit using C++11's override.
They both do the same thing. You don't need to explicitly say virtual in the derived class, as long as it is virtual in the base class.
In Cplusplus, in a derived class, if we define a member function to override a member function in its parent class, do we need to declare the one in the derived class to be virtual?
From the working draft, [class.virtual]/2 (emphasis mine):
If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, a member function vf with the same name, parameter-type-list, cv-qualification, and ref-qualifier (or absence of same) as Base::vf is declared, then Derived::vf is also virtual (whether or not it is so declared) and it overrides Base::vf.
So, no. It is not required.
In pre-C++11 era, declaring virtual also the member functions in the derived classes helped the readers understanding what's going on under the hood.
Since C++11, override is the preferred way, for it not only helps the readers, but also it forces a compile-time check so that typos in the declarations don't introduce subtle errors.
I have a class template where some methods are defined as virtual to give the ability for the user of my class to give an implementation for them in his derived class. Note that in my template class there is some non-virtual methods that makes use of the virtual one (a virtual class that should return a value is called in a non-virtual class).
Can you give me a simple example of a correct code where the virtual method of the parent class should return a value (but it's implementation is provided in a child class) and the value returned by the virtual method in the parent class is used in other methods of that class. Because I saw somewhere (for example here: Safely override C++ virtual functions) that this can cause some problems and the user defined method will note override the virtual method of the parent class.
Note: I program with Code::Blocks using g++ compiler.
EDIT: as requested here a simple example of what I want:
template<typename T>
class parent {
public:
// Public methods that user can call
int getSomething(T t);
void putSomething(T t, int x);
// public method that user should implement in his code
virtual float compute(T t) { }
// protected or private methods and attributes used internally by putSomething ...
float doComplexeThings(...); // this can call
};
The method compute() should be implemented by the user (the child class). However, this method compute() is called by putSomething() and doComplexeThings() for example.
If you can use C++11 features in your compiler then overrides can be tagged as so with the override special identifier:
float compute() override;
The above line in a derived class will cause a compiler error as the function does not override a member function in the base (incorrect signature, missing argument). But note that this must be done in each derived class, it is not a solution that you can impose from the base class.
From the base class you can only force the override by making the function pure virtual, but that changes the semantics. It does not avoid problems while overriding, but rather forces overriding in all cases. I would avoid this approach, and if you are to follow it and there is a sensible implementation for the base type, make the function virtual and provide a definition so that your derived classes's implementation can just call the functions the base type (i.e. you force the implementation, but in the simplest cases it will just forward the call to the parent)
You just have to make sure that the methods have the same signature (including const/mutable modifiers and argument types). You can use a pure virtual definition to provoke compiler errors if you fail to override the function in a subclass.
class parent {
public:
// pure virtual method must be provided in subclass
virtual void handle_event(int something) = 0;
};
class child : public parent {
public:
virtual void handle_event(int something) {
// new exciting code
}
};
class incomplete_child : public parent {
public:
virtual void handle_event(int something) const {
// does not override the pure virtual method
}
};
int main() {
parent *p = new child();
p->handle_event(1); // will call child::handle_event
parent *p = new incomplete_child(); // will not compile because handle_event
// was not correctly overridden
}
This question is asked in 2013. It's pretty old but I found something new which doesn't exist in the answers.
We need to understanding three concept is overload, overwrite, and hide.
Short answer, you want to overload the inheritance function from base class.
However, overload is the mechanism to add multiple behavior for function which needs all these functions under the same scale. But the virtual function is in the Base class obviously.
class A {
public:
virtual void print() {
cout << id_ << std::endl;
}
private:
string id_ = "A";
};
class B : A {
public:
using A::print;
void print(string id) {
std::cout << id << std::endl;
}
};
int main(int argc, char const *argv[]) {
/* code */
A a;
a.print();
B b;
b.print();
b.print("B");
return 0;
}
Add using A::print; in your derive class will do the work!
Though I don't feel it's a good idea since the philosophy behind the overload and inheritance is different, it may not a good idea to nest them together.
class Base{
public:
void counter();
....
}
class Dervied: public Base{
public:
....
}
void main()
{
Base *ptr=new Derived;
ptr->counter();
}
To identify that the base class pointer is pointing to derived class and using a derived member function, we make use of "virtual".
Similarly, can we make derived data members "virtual"? (the data member is public)
virtual is a Function specifier...
From standard docs,
7.1.2 Function specifiers
Function-specifiers can be used only in function declarations.
function-specifier:
inline
virtual
explicit
So there is nothing called Virtual data member.
Hope it helps...
No, but you can create a virtual function to return a pointer to what you call virtual data member
No, in C++ there are no virtual data members.
I think not, but you might simulate it using virtual getters and setter perhaps?
To identify that the base class pointer is pointing to derived class and using a derived member function, we make use of "virtual".
That is not correct. We make virtual functions to allow derived classes to provide different implementation from what the base provides. It is not used to identify that the base class pointer is pointing to derived class.
Similarly, can we make derived data members "virtual"? (the data member is public)
Only non static member functions can be virtual. Data members can not be.
Here's a link with some more info on that
No, because that would break encapsulation in a myriad of unexpected ways. Whatever you want to achieve can be done with protected attributes and/or virtual functions.
Besides, virtual functions are a method of dispatch (i.e. selecting which function is going to be called), rather than selecting a memory location corresponding to the member attribute.
A class cannot have a virtual member, see for instance this answer.
However, you can have something similar using pointers, inheritance
and runtime polymorphism.
In the following snippet I define the prototype for a geometrical shape,
that has an area method. The picture class has a member shape* s;
and the methods of that shape pointed by s are used by picture::show().
In this setup it is undesirable to have an instance of picture before
an actual implementation of a shape has been given, hence we force picture to be
abstract by adding a dummy virtual function picture::make_real().
// prototypes
class shape
{
public:
virtual double area() = 0; // to be defined later
};
class picture
{
protected:
shape* s;
virtual void make_real() = 0; // force picture to be abstract
public:
picture(shape* ptr):
s{ptr}
{}
void show()
{
std::cout << s->area() << '\n';
}
};
Next, we actually implement a shape called square and a picture type
square_picture that (literally) has a square shape.
// actual implementation
class square : public shape
{
double len;
public:
square(double l):
len{l}
{}
double area() override
{
return len*len;
}
};
class square_picture : public picture
{
void make_real() override {} // square_picture is not abstract
public:
square_picture(double l):
picture{new square{l}}
{}
~square_picture()
{
delete s;
}
};
The class square_picture can be tested with the following snippet
int main()
{
square_picture A{2.0};
A.show();
//picture B{nullptr}; // error: picture is abstract
return 0;
}
which outputs:
4
I have a base class which uses an array of objects. From that class I derived a new class that uses an array of a different type of object. Both variables have exactly the same name. Virtual member functions were added to both classes to process the arrays. These member functions have no trouble finding the correct variable. The member functions and the variables they use are in a common scope.
The virtual member functions are nearly identical in both classes. Only the type of array changed.
C++ templates could have accomplished the same result.
Maybe you can see the problem in a equivalent way:
class VirtualDataMember{
public:
...
}
class DerviedDataMember: public VirtualDataMember{
public:
...
}
class Base{
public:
VirtualDataMember* dataMember;
void counter();
...
}
It must be something specific in my code, which I can't post. But maybe someone can suggest possible causes.
Basically I have:
class CParent
{
public:
void doIt(int x);
};
class CChild : public CParent
{
public:
void doIt(int x,int y,int z);
};
CChild *pChild = ...
pChild->doIt(123); //FAILS compiler, no method found
CParent *pParent = pChild;
pParent->doIt(123); //works fine
How on earth?
EDIT: people are talking about shadowing/hiding. But the two versions of doIt have different numbers of parameters. Surely that can't confuse the compiler, overloads in child class which can't possibly be confused with the parent class version? Can it?
The compiler error I get is:
error C2660: 'CChild::doIt' : function does not take 1 argument
You have shadowed a method. For example:
struct base
{
void method(int);
void method(float);
};
struct derived : base
{
void method(int);
// base::method(int) is not visible.
// base::method(float) is not visible.
};
You can fix this with a using directive:
class derived : public base
{
using base::method; // bring all of them in.
void method(int);
// base::method(int) is not visible.
// base::method(float) is visible.
};
Since you seem insistent about the number of parameters, I'll address that. That doesn't change anything. Observe:
struct base
{
void method(int){}
};
struct derived : base
{
void method(int,int){}
// method(int) is not visible.
};
struct derived_fixed : base
{
using base::method;
void method(int,int){}
};
int main(void)
{
{
derived d;
d.method(1, 2); // will compile
d.method(3); // will NOT compile
}
{
derived_fixed d;
d.method(1, 2); // will compile
d.method(3); // will compile
}
}
It will still be shadowed regardless of parameters or return types; it's simply the name that shadows. using base::<x>; will bring all of base's "<x>" methods into visibility.
You are hitting a classic problem. You need using CParent::doIt; in your CChild class. I'll scrounge up the duplicate questions.
Edit:
Here's my answer to essentially the same question: Overriding a Base's Overloaded Function in C++
I have never done this without having that method in the base class before. I think that adding "using CLASS::METHOD" in derived class will give you access to the other version of the overloaded method.
class CParent
{
public:
void doIt(int x);
};
class CChild : public CParent
{
public:
void doIt(int x,int y,int z);
using CParent::doIt;
};
The problem is CChild doesn't actually inherit from CParent.
And so it doesn't have a doIt method that takes only one argument.
When you override a function in the derived class, only that function in the derived class is visible to the user of that class. The base class version becomes hidden.
Therefore, your pChild pointer calling doIt(int x) will fail since you are using a derived class pointer to call the base class function. The pParent pointer calling doIt(int x) will work since you are using a base class pointer to call the base class function. Even though you have a child object being pointed to by a parent pointer (upcasted), the class type here is determined by the declaration of the pointer which is a CParent.
To be able to call that base class function using the derived class pointer, you can:
Qualify the base class name in the function call, as in the following:
pChild->CParent::doIt(123);
Use a using directive to bring the function name from the base class into the derived class, as seen in the previous posts.
I understand that this behavior is to give you flexibility to override the behavior of base class method in your derived class.
Lets assume that you have a function foo(int) in base class and you want to change the behavior of this function in your derived class. Now if the base class method is not hidden by your derived class method (which has same prototype as that of base class's method), it will introduce ambiguity in overload resolution.
The method in your child class has a different number of arguments than what you're trying to pass into it. Could it be related to that?