This question already has answers here:
Why does an overridden function in the derived class hide other overloads of the base class?
(4 answers)
Closed 3 years ago.
I have a Base class where there are 2 overloaded expanded() functions
I am overloading one of them in Derived class and trying to call the other one inside it.
class Base
{
public:
bool expanded()
{
return false;
}
void expanded(bool isit)
{
}
};
class Derived : public Base
{
public:
void expanded(bool isit)
{
expanded();
}
};
This fails with compilation error: 'Derived::expanded': function does not take 0 arguments
The new method i.e. the method in child class hides the scope of the old one. To call it, you need to be explicit with the scope:
class Derived : public Base
{
public:
void expanded(bool isit)
{
Base::expanded();
}
};
and if you want to maintain the same interface, you'll need to redefine in the derived class.
class Derived : public Base
{
public:
void expanded(bool isit)
{
Base::expanded();
}
bool expanded()
{
return Base::expanded();
}
};
The followings will work:
Solution 1:
class Derived : public Base
{
public:
void someOtherMethod(bool isit)
{
expanded();
}
};
Solution 2:
class Derived : public Base
{
public:
void expanded(bool isit)
{
// Will call child's expanded(bool) and will become recursive.
expanded(false);
}
};
Solution 3:
class Derived : public Base
{
public:
void expanded(bool isit)
{
Base::expanded();
}
};
When you define a method same as parent method in your child class, then any time that method name is encountered in the child class, the compiler will search for the definition in the child class only. That is what is happening here. As the child class' expanded takes 1 argument, compiler is expecting a parameter to be passed.
Similar question has already been answered in Overloads of inherited member functions
Adding to the previous answer. There is no overloading across scopes – derived class scopes are not an exception to this general rule. You can easily solve your error by declaring Baseclass like this
class Derived : public Base
{
public:
using Base::expanded;
void expanded(int isit)
{
expanded();
}
};
Related
Executing the code below will give an error to the line Child(){/**........code*/} saying: no matching function for call to 'Base::Base()' and that canditate Base::Base(int) expects 1 argument, and none is provided.
class Base
{
public:
Base(int test)
{
};
};
class Child : public Base
{
public:
Child ()
{
/**....
....
code*/
};
Child(int test):Base(test)
{
};
};
So I would like to know if there is a way to use a constructor in the derived class - for example: Child(){}; - that doesn't have any association with its base class.
No.
By your definition a Child inherits from Base and it is not possible to create a Child without the Base subobject.
Instead you should provide an argument (whatever is a good default):
Child() : Base(42) {};
Alternatively Base could provide a default constructor (one that can be called without arguments), that would be
class Base {
public:
Base(int test = 42) {};
};
then your Child would be ok as is.
You still need to call the user defined constructor. You can however pass a dummy argument to it if your application will tolerate that. Otherwise, it is bad application design and something will break somewhere later on.
class Child : public Base
{
public:
Child ()
: Base(0)
{
/**....
....
code*/
};
Child(int test):Base(test)
{
};
};
I have a base class with an implemented function and a pure virtual function which share a name, but not arguments. I can't call the function implemented in the base class from an instance of the derived class.
I've tried adding the function to the derived class instead of the base class and it works, but that would mean I have to add the function to every derived class instead of implementing it once in the base class.
I've also tried changing the functions name and it works. It seems to be due to a collision between the two overloaded functions.
template <typename T>
class Base {
public:
virtual T some_function(int x) = 0;
T some_function() {
// some code
}
}
class Derived final: public Base<int> {
int some_function() {
// some code
}
}
int main() {
Derived var = Derived();
var.some_function(3);// Compilation error
}
The above code does not compile indicating that it doesn't find the function: some_function(int).
The name some_function in Derived hides the name some_function inherited from Base. You have to bring it back into scope with a using declaration:
class Derived final: public Base<int> {
public:
using Base<int>::some_function;
int some_function() {
// some code
}
}
This question already has answers here:
How to call a parent class function from derived class function?
(7 answers)
Closed 7 years ago.
C++ newbie here. Is there a way to call an overloaded function in a base class from the same function name with the same signature in a derived class? In Smalltalk, I can do it the "super" keyword. Is there any C++ equivalent?
class MyBaseClass {
void initialize() { doSomething(); }
};
class MyDerivedClass : public MyBaseClass {
void initialize() {
super initialize(); // first, call MyBaseClass::initialize()
doLocalInitialize(); // now initialize non-inherited members
}
Thanks,
Norm
You literally said the correct syntax in your comment :)
class MyBaseClass {
void initialize() { doSomething(); }
};
class MyDerivedClass : public MyBaseClass {
void initialize() {
MyBaseClass::initialize(); // first, call MyBaseClass::initialize()
doLocalInitialize(); // now initialize non-inherited members
}
How would I do so without making base method virtual?
class Base {
public:
bool foo() const;
}
class Derived : public Base{
public:
bool foo() const;
}
There is no any sense to call isEmpty of a derived class from isEmpty of the base class because the base class knows nothing about its derived classes. Take into account that the base class is single while there can be numerous derived classes. So of what derived class are you going to call function isEmpty?
There is sense to call isEmpty of the base class in a derived class. it can be done the following way
bool Derived::isEmpty() const
{
return Base::isEmpty();
}
You cannot. That's why there is a virtual keyword. If your class forbids use of this keyword, I'd rather not use it as a starting point to learn OOP.
If you really need this, you can store a null pointer to a function with the foo's signature in your base class instances, and use the base implementation until this pointer is null. Then you can change this pointer in your derived class and associate is with your derived implementation. Then your base class can call that function via the pointer.
Below is some schematic code for this:
class Base {
public:
bool foo() const {
if (NULL == internalFoo) {
// base implementation;
} else {
return internalFoo();
}
}
private:
bool (*internalFoo)() = NULL;
}
class Derived : public Base{
public:
bool foo() const;
}
I don't understand why the compiler doesn't like this, here is and example of the problem:
class A
{
public:
virtual void Expand() { }
virtual void Expand(bool flag) { }
};
class B : public A
{
public:
virtual void Expand() {
A::Expand(true);
Expand(true);
}
};
When I try to compile this the A::Expand(true); compiles fine, but the non scoped Expand(true); gets this compiler error:
'B::Expand' : function does not take 1 arguments
You don't need virtual methods for that behaviour. Methods in a derived class hide methods with the same name in the base class. So if you have any function named Expand in your derived class (even if it is an override of a virtual method from the base class), none of the base classes methods with the same name are visible, regardless of their signature.
You can make the base classes methods visible with using. For that you would add using A::Expand; to the definition of B:
class B : public A
{
public:
using A::Expand;
virtual void Expand() { Expand(true); }
};
That's because besides overriding the base Expand(), you're also hiding the base Expand(bool).
When you introduce a member function in a derived class with the same name as a method from the base class, all base class methods with that name are hidden in the derived class.
You can fix this by either qualifying (as you have) or with the using directive:
class B : public A
{
public:
using A::Expand;
virtual void Expand() {
A::Expand(true);
Expand(true);
}
};