Clearing out Function Hiding compiler warnings in C++ - c++

I'm getting "hiding" warnings in my compiler because a class inherits from its parent has the same name but different parameters.
Adding a function that merely pushes out a warning to say that this function does nothing (as is true in the base class, but without the warning) that matches the parameters and name of the base class function to the derived class clears this compiler warning. What are the potential knock-on effects of this on the derived class?
EDIT: Assume that I do not wish them to be able to use the base class function. (Don't ask).

Redefining the name in the derived class effectively hides the function in the base class. That's what the warning tells you! :-)
It is a warning, because usually this is a mistake. If it is on purpose, that is ok (but very rare).

The inability of your users to access the base class function through a derived instance without explicitly writing out myDerivedObj.Base::foo(), which they're not likely to do.
Make your function signatures match up, instead, or change the function name.

You need to unhide the base class function in the derived class as:
using Base::Function;
Example:
class Base
{
public:
void Function(int) { cout << "Function(int)" << endl; }
};
class Derived : public Base
{
public:
using Base::Function; //NOTE THIS LINE : Unhiding base class function!
void Function(const char *) { cout << "Function(const char *)" << endl; }
};
Derived d;
d.Function(10); //this calls Base::Function
Demo : http://ideone.com/OTBxg

Related

Calling base method however only second level base method exists

Imagine a huge code base with many many inheritance. At some point a line comes in your way in the class you have to work with.
inherited::Load();
This is do what it says. It loads the base object into memory.
inherited is a typedef for the base class.
However the actual parent class does not have a Load method.
As a quick example:
class Base {
public:
Base() {};
void Load() {
cout << "Base ok" << endl;
}
};
class Derived : public Base {
public:
Derived() {};
};
class MostDerived : public Derived {
public:
MostDerived(){};
void Load() {
Derived::Load();
cout << "Child ok"<< endl;
}
};
Here, if we call MostDerived.Load() it will call its parent's Load method, but the Derived class doesn't have its own Load, only Base's Load method.
What is actually going on here? Why there is no compilation issue?
Is the Derived class copies all the method of the base, so it will have a Load method what is prints "Base ok"? Or does Derived simply calls forward the Base method?
I found a related question Do ALL virtual functions need to be implemented in derived classes? and the answer says
It inherits the bar implementation from its ancestor class.
For me it still miss leading that explicitly calling the Derived::Load() method works. However, there is only a Base::Load() method exists.
What is actually going on here? Why there is no compilation issue? Is the Derived class copies all the method of the base, so it will have a Load method what is prints "Base ok"?
Yes. A derived class inherits all methods from the base class. (yes really all of them, whether it can access them depends on the access specified for the methods).
For me it still miss leading that explicitly calling the Derived::Load() method works. However, there is only a Base::Load() method exists.
Sloppy speaking the Derived:: only tells the compiler to look for names accesible from Derived. As Derived does inherit from Base, it does have a Load method.
Maybe your confusion can be cleared up a bit by noting that Derived::Load indeed does refer to Base::Load:
#include <type_traits>
#include <iostream>
struct Base {
void Load() {}
};
struct Derived : Base {};
int main() {
std::cout << std::is_same_v< decltype(&Derived::Load), void (Derived::*) ()>;
std::cout << std::is_same_v< decltype(&Derived::Load), void (Base::*) ()>;
}
This prints 01, because Derived::Load is indeed a method of Base.
I hope the example is not adding confusion ;). It uses std::is_same to see if two types are the same. &Derived::Load gives me a member function pointer to the Load method in Derived whose type I infer via decltype. I compare that once to pointer to method of Derived and then to pointer to method of Base. It turns out that Derived::Load is a method of Base.

Virtual function hiding in derived class

I have two classes related by inheritance:-
class Base
{
public:
virtual void f(int x)
{
cout << "BASE::int" << endl;
}
virtual void f(double x)
{
cout << "BASE::double" << endl;
}
};
class Derived : public Base
{
public:
virtual void f(str::string s)
{
cout << "DERIVED::string" << endl;
}
};
I have provided same method in derived class with different parameters. That means rather than overriding I am hiding base class versions of this function. So, below calls are expected and clear to me.
std::string str("Hello");
Base b;
b.f(1); //calls base class version.
b.f(str); //error.
Derived d;
d.f(1); //error.
d.f(str); //calls derived class version.
But I am not able get clarification for this last scenario.
Base *b = new Derived;
b->f(str); //results in error.
Would compiler not bind this call to derived version of f using vtables and vptrs. But instead it's doing something else. Can anyone provide me complete path how compiler would try to resolve this call as per language mechanisms.
If your pointer is of type Base* then you can only "see" members that are defined in class Base. The compiler doesn't (or pretends not to) "know" that the variable really points to an instance of Derived, even if you just assigned one to it on the previous line.
When you declare a variable to be of type Base*, you're telling the compiler: treat this as something that could point to a Base or to any class derived from it. So you can't access members that are defined in a particular derived class, because there's no guarantee that the pointer actually points to an instance of that derived class.
The vtable only enters the picture at runtime. The generated assembly would have a lookup of the vptr value for a function and a jump to that address. This also means that the polymorphism is "restricted" to functions that Base knows about. Note that this is what makes more sense as well - the definition of a class should only depend on itself and its parents. If you wanted to make Base* b aware of the virtual functions implemented by Derived, you would end up with the number of vtable entries in Bases depending on its children.

C++ pure virtual function inheritance (same signature) [duplicate]

This question already has answers here:
Overriding C++ virtual methods with multiple signatures [duplicate]
(2 answers)
Closed 6 years ago.
Why is this not compiling?
error C2660: 'Concrete::WriteLine' : function does not take 1 arguments
I know if i add the Line:
//using AbstractBase::WriteLine;
it works, but i dont understand why.
#include "iostream"
class AbstractBase
{
public:
virtual void WriteLine() = 0;
virtual void WriteLine( int i )
{
std::cout<<"AbstractBase"<<std::endl;
}
};
class Concrete : public AbstractBase
{
public:
//using AbstractBase::WriteLine;
virtual void WriteLine()
{
std::cout<<"Concrete Sub Class"<<std::endl;
}
};
int main()
{
Concrete ff;
ff.WriteLine();
ff.WriteLine(1);
return 0;
}
Can someone explain me what happens here.
Thanx
Does anyone knows if this behavior is a defined behavior from the C++ standart.
Is it mentioned in the C++ standart?
Or is it just a kind of compiler behavior?
Once you declare a function:
void WriteLine()
in derived class it hides all the base class functions with the same name.
The above function which takes no parameters hides the function with same name and taking one parameter, Since compiler cannot find a function with one parameter it reports a error.
The line:
using AbstractBase::WriteLine;
enables(brings in scope) all the hidden names from the Base class in your derived class and hence the function taking one parameter is available.
Good Read:
What's the meaning of, Warning: Derived::f(char) hides Base::f(double)?
Method hiding happens. The other function in the base class is hidden by the function with the same name, although it has a different signature.
To solve this, you can use a using directive:
using AbstractBase::WriteLine;
in the derived class:
class Concrete : public AbstractBase
{
public:
using AbstractBase::WriteLine;
//using AbstractBase::WriteLine;
virtual void WriteLine()
{
std::cout<<"Concrete Sub Class"<<std::endl;
}
};
Declaring a function in a derived class hides all functions with the same name in the base class - they are not considered as potential overloads of the derived class functions.
Adding the using declaration brings the hidden functions back into the scope of the derived class, and they are considered as potential overloads along with the derived class functions.
The problem is that Concrete::WriteLine is hiding all AbstractBase::WriteLines. You can add
using AbstractBase::WriteLine;
to your derived class.

C++ extend inherited functions

considering a simple inherited class:
class Base
{
void func() {
cout << "base" << endl;
}
};
class Derived : public Base
{
void func() {
cout << "derived" << endl;
}
};
if I run Derived::func() I get
derived
I would like to modify this code to get
base
derived
Something more similar to an extension than an overriding.
I've been able to get something similar with constructors, but not with normal functions.
Many thanks,
Lucio
class Derived : public Base
{
void func() {
Base::func(); // Call the base method before doing our own.
cout << "derived" << endl;
}
};
To access the base-class function from the derived class, you can simply use:
Base::func();
In your case, you would have this as the first line of the derived implementation of func().
Using Base::func(); is correct like a few others already stated.
Remember the constructor for the base class will always get called first, then the constructor for the derived class.
You've talked about constructor, a derived class's constructor will call base class's one, no matter whether you use an inherited constructor, it makes sense because a derived class should be able to construct the members inherited from the base class. And by default, constructor wouldn't be inherited.
But, the "normal" method goes the much different way.
First, please sure that in most of the time, it's not necessary for a method in derived class to call the same-name method in base class, and on the contrary, it will cover base class's one, although it did inherit it.
So if you really want to call base class one, you should tell complier explicitly. Using baseclass::somemethod will fulfill your request.
You can't do so.
You'll have to do like
Void derived:: func()
{
this->func(); /*you should use 'this pointer' to
access the base class functions*/
cout<<"derived";
}

Implicit upcasting question

I find when writing functions (that use function overloading) that accept either a main class or subclass argument, that often implicit upcasting will occur (the subclass is upcasted as the main class and the main class function called). I don't want this implicit upcasting to occur as it means subtle bugs sneak in and cause problems later on down the line.
I have searched on google for information on this, but there is little coherent information I can make use of and only indirect references to it.
How do I disable, stop or prevent implicit upcasting (and even downcasting) from occurring?
(I can't supply any example code as this is a general problem that occurs from time to time).
No, this isn't to do with methods (I would have specified methods) but functions.
No example code, but pseudo idea:
void Function(BaseClass &A);
void Function(SubclassClass &B);
Function(ASubclass); //Implicit upcasting occurs, calls BaseClass instead
The above situation won't happen conventionally (say that the SubclassClass function gets knocked out/erased), but Subclass will be upcast to the BaseClass for use with the BaseClass function, instead of, say, reporting an error or generating a warning - either would be helpful as I don't want implicit upcasting to occur.
Please don't confuse upcasting with non-virtual method calls.
class Base
{
};
class Derived1:public Base
{
};
class Derived2:private Base
{
};
void doSomething(Base *ptr)
{
}
int main()
{
Derived1 *ptr1 = new Derived1;
Derived2 *ptr2 = new Derived2;
doSomething(ptr1); //works fine
doSomething(ptr2); //Gives error
return 0;
};
Upcasting:
A Base class pointer can always point to a derived class object as long as the derived class is publically derived from the Base class. Eg: First Function Call.
This upcasting happens implicitly.
If the derivation is private this upcasting does not happen implicitly and compiler will issue an error.
Though, using private inheritance is not the way to achieve this behavior. You should use private inheritance if it suits your design and it will implicitly gaurantee you that upcasting never happens implicitly.
The "up-casting" you are talking about is normal. The symptoms you are describing sound like you are overloading a non-virtual parents member function.
For example
#include <iostream>
using namespace std;
struct A
{
void sayHello() {cout << "hello from A" << endl;}
};
struct B : public A
{
void sayHello() {cout << "hello from B" << endl;}
};
void hello(A& a)
{
a.sayHello();
}
int main()
{
A a;
B b;
hello(a);
hello(b);
}
will produce
hello from A
hello from A
but if you add the virual to A::sayHello everything works as you would expect
struct A
{
virtual void sayHello() {cout << "hello from A" << endl;}
};
I'm not 100% sure what's going on, but if base class methods are being called when you supply a derived-class object to a method with a base-class parameter type, then either a) you didn't override the base-class method in your derived class, or more likely b) you forget the 'virtual' keyword in your base-class declaration. Otherwise the derived-class method will be called as expected.
#Als your example wont work if derivation is in protected mode.Implicit upcasting is allowed within the derived class only (within methods of the derived class) because protected members can only be accessed inside the class that derives or base class.