Why is only derived class member function called? - c++

In the following code:
Please tell me why only derived class member function is called, is it because of hiding? And why an error doesn't occur in b.func(1.1);, the parameter is int x.
#include <bits/stdc++.h>
using namespace std;
class A {
public:
virtual int func(float x)
{
cout << "A";
}
};
class B : public A {
public:
virtual int func(int x)
{
cout << "B";
}
};
int main()
{
B b;
b.func(1); // B
b.func(1.1); // B
return 0;
}

Yes it's because of hiding. This is one of the main reasons you should always add the special identifier override on functions you intend to override:
class B : public A {
public:
virtual int func(int x) override // <- Note the override here
{
cout << "B";
}
};
This will cause the compiler to complain about not actually overriding.
And floating point values can be implicitly converted to integers.

Related

Error: cannot convert '<unresolved overloaded function type>' to 'function pointer'

#include<iostream>
#include<bitset>
#include<string.h>
#include<string>
#include<vector>
#include<math.h>
#include<stdarg.h>
class b {
public:
b();
void ef(void(*f)());
};
class d : public b{
public:
d();
void print();
};
b::b() {}
void b::ef(void(*f)()) { f(); }
d::d(): b(){}
void d::print() { cout<<"WORKS"<<endl; }
int main() {
d obj;
obj.ef(obj.print);
}
I have a problem with a derived class method, I would execute d::print() as parameter of b::ef(), compiling I got this error:
"error: cannot convert '' to
'void (*)()'"
Can you help me to fix it? Thank you
Here's your code, fixed. But I can see a dozens of things "wrong" with it, in the sense "does what you asked, but not what you (probably) want."
The print method needs to act on a d object. But that means the base class has to know about the derived class. That's awkward. If the base class had a virtual print function, then it could have that passed in, and would call the derived classes override of that virtual function. But that's not what we have here.
#include <iostream>
using std::cout;
namespace {
class d;
class b {
public:
b();
void ef(d&, void(d::*)());
};
class d : public b {
public:
d();
void print();
};
b::b() {}
void b::ef(d& dobj, void(d::*f)()) {
(dobj.*f)();
}
d::d() : b() {}
void d::print() {
cout << "WORKS\n";
}
} // anon
int main() {
d obj;
obj.ef(obj, &d::print);
}

Namehiding and overriding - Is there a way to make a function explicitly not overriding

I would like to hide a virtual method instead of override. I know for historic / compatibility reasons the override specifier is optional and overriding happens implicitly.
To stop overriding I usually adjusted the signature by adding a defaulted "Dummy" parameter. Is there a better way?
Assume this code:
#include <iostream>
class A{
public:
virtual void Foo()
{
std::cout << "A::Foo";
}
};
class B : public A
{
public:
void Foo() /*not override, just hide*/
{
std::cout << "B::Foo";
}
};
int main()
{
B b{};
A& a = b;
a.Foo(); //should print A::Foo - but prints B::Foo
}
What I did so far is this:
#include <iostream>
class A{
public:
virtual void Foo()
{
std::cout << "A::Foo";
}
};
template<typename T>
class reintroduce{};
class B : public A
{
public:
void Foo(reintroduce<B> = {}) /*not override, just hide*/
{
std::cout << "B::Foo";
}
};
int main()
{
B b{};
A& a = b;
a.Foo(); //should print A::Foo
}
The question is not too clear on the requirements of "hiding" but the following effectively "hides" the inherited method in the derived class, while not changing its visibility/accessibility in the base class.
#include <iostream>
class A {
public:
virtual void Foo()
{ std::cout << "A::Foo"; }
};
class B : public A
{
private:
using A::Foo;
};
int main()
{
B b;
b.Foo(); // error, cannot access private member
b.A::Foo(); // ok, calls A::Foo
A& a = b;
a.Foo(); // ok, calls A::Foo
}

Multiple inheritance in c++ using abstract base classes [duplicate]

I tried this code:
class A
{
virtual void foo() = 0;
};
class B
{
virtual void foo() = 0;
};
class C : public A, public B
{
//virtual void A::foo(){}
//virtual void B::foo(){}
virtual void A::foo();
virtual void B::foo();
};
void C::A::foo(){}
void C::B::foo(){}
int main()
{
C c;
return 0;
}
It is OK when using the commented part, but when I try to write the definitions outside the class declaration, the compiler reports errors.
I am using the MSVC11 compiler, does anyone know how to write this?
I need to move the code into the cpp file.
Thank you~~
A function overrides a virtual function of a base class based on the name and parameter types (see below). Therefore, your class C has two virtual functions foo, one inherited from each A and B. But a function void C::foo() overrides both:
[class.virtual]/2
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.
As I already stated in the comments, [dcl.meaning]/1 forbids the use of a qualified-id in the declaration of a (member) function:
When the declarator-id is qualified, the declaration shall refer to a previously declared member of the class or namespace to which the qualifier refers [...]"
Therefore any virtual void X::foo(); is illegal as a declaration inside C.
The code
class C : public A, public B
{
virtual void foo();
};
is the only way AFAIK to override foo, and it will override both A::foo and B::foo. There is no way to have two different overrides for A::foo and B::foo with different behaviour other than by introducing another layer of inheritance:
#include <iostream>
struct A
{
virtual void foo() = 0;
};
struct B
{
virtual void foo() = 0;
};
struct CA : A
{
virtual void foo() { std::cout << "A" << std::endl; }
};
struct CB : B
{
virtual void foo() { std::cout << "B" << std::endl; }
};
struct C : CA, CB {};
int main() {
C c;
//c.foo(); // ambiguous
A& a = c;
a.foo();
B& b = c;
b.foo();
}
You've got just one virtual function foo:
class A {
virtual void foo() = 0;
};
class B {
virtual void foo() = 0;
};
class C : public A, public B {
virtual void foo();
};
void C::foo(){}
void C::A::foo(){}
void C::B::foo(){};
int main() {
C c;
return 0;
}
I stepped into the same problem and accidentially opened a second thread. Sorry for that. One way that worked for me was to solve it without multiple inheritance.
#include <stdio.h>
class A
{
public:
virtual void foo(void) = 0;
};
class B
{
public:
virtual void foo(void) = 0;
};
class C
{
class IA: public A
{
virtual void foo(void)
{
printf("IA::foo()\r\n");
}
};
class IB: public B
{
virtual void foo(void)
{
printf("IB::foo()\r\n");
}
};
IA m_A;
IB m_B;
public:
A* GetA(void)
{
return(&m_A);
}
B* GetB(void)
{
return(&m_B);
}
};
The trick is to define classes derived from the interfaces (A and B) as local classes (IA and IB) instead of using multiple inheritance. Furthermore this approach also opens the option to have multiple realizations of each interface if desired which would not be possible using multiple inheritance.
The local classes IA and IB can be easily given access to class C, so the implementations of both interfaces IA and IB can share data.
Access of each interface can be done as follows:
main()
{
C test;
test.GetA()->foo();
test.GetB()->foo();
}
... and there is no ambiguity regarding the foo method any more.
You can resolve this ambiguity with different function parameters.
In real-world code, such virtual functions do something, so they usually already have either:
different parameters in A and B, or
different return values in A and B that you can turn into [out] parameters for the sake of solving this inheritance problem; otherwise
you need to add some tag parameters, which the optimizer will throw away.
(In my own code I usually find myself in case (1), sometimes in (2), never so far in (3).)
Your example is case (3) and would look like this:
class A
{
public:
struct tag_a { };
virtual void foo(tag_a) = 0;
};
class B
{
public:
struct tag_b { };
virtual void foo(tag_b) = 0;
};
class C : public A, public B
{
void foo(tag_a) override;
void foo(tag_b) override;
};
A slight improvement over adigostin's solution:
#include <iostream>
struct A {
virtual void foo() = 0;
};
struct B {
virtual void foo() = 0;
};
template <class T> struct Tagger : T {
struct tag {};
void foo() final { foo({}); }
virtual void foo(tag) = 0;
};
using A2 = Tagger<A>;
using B2 = Tagger<B>;
struct C : public A2, public B2 {
void foo(A2::tag) override { std::cout << "A" << std::endl; }
void foo(B2::tag) override { std::cout << "B" << std::endl; }
};
int main() {
C c;
A* pa = &c;
B* pb = &c;
pa->foo(); // A
pb->foo(); // B
return 0;
}
Assuming that the base classes A and B are given and cannot be modified.

C++ overloading and overriding

This code generates the following compilation error :
error: no matching function for call to 'C::print(int)'
can you help me figuring out the procedure that the compiler did to generate that error , (why it ignored the function in class B)
#include <iostream>
using std::cout;
class A {
public:
virtual void print ()
{ cout << "A";}
};
class B : public A {
int x;
virtual void print (int y)
{cout << x+y;}
};
class C : public B {
public:
void print ()
{cout << "C";}
};
int main () {
C* ptr = new C;
ptr->print (5);
}
Each subsequent definition of print hides its parent's. You need a using statement to unhide it:
class A {
public:
virtual void print ()
{ cout << "A";}
};
class B : public A {
public:
int x=1;
using A::print;
virtual void print (int y)
{cout << x+y;}
};
class C : public B {
public:
using B::print;
void print ()
{cout << "C";}
};
Demo
Your pointer is to C*, not B*. You wouldn't technically need to 'unhide' any print functions if your code looked like this:
B* ptr = new C;
However that this sort of hiding is not a particularly good idea... you should prefer overriding and just naming functions different things.
The compiler resolves overloads for the closest (class) type seen. So class C effectively hides the function signature inherited from class B.
To call for that specific function you have to qualify its scope explicitely:
ptr->B::print (5);
// ^^^
overloading means two things(eg functions) have same name in same space or scope like in same class but in overriding we rewrite the definition of function in different scope(class) but the name still remains same.

How to deal with name hiding when base class function already overloaded with different access

Class foo act as interface, it has a pure virtual function and also provide some public overloaded function with same name for convenience so that derived class won't need to provide them in every implementation.
But since derived class must override the pure virtual function, it hides foo's public function.
I tried with "using foo::A", but it won't work because "using" will bring all function including the private one and result in compiler error "error C2876: 'foo' : not all overloads are accessible".
class foo
{
private:
virtual void A(int a)=0;
public:
void A()
{
A(1000);
}
void A(int a, int b)
{
A(a+b);
}
};
class bar : public foo
{
private:
virtual void A(int a)
{
cout << a << "\n";
}
};
int main()
{
bar x;
x.A();
return 0;
}
I know I can redefine every overloaded function in every class which derived from foo, but this defeat the purpose of convenience.
Or I can cast bar to foo before calling A(), but this approach will get confused since I need to remember which function is define in which class. For example:
class foo
{
private:
virtual void A(int a)=0;
public:
void A()
{
A(1000);
}
void A(int a, int b)
{
A(a+b);
}
};
class bar : public foo
{
private:
virtual void A(int a)
{
cout << "bar:" << a << "\n";
}
public:
void A(int a, int b, int c)
{
A(a+b+c);
}
};
class foobar : public bar
{
private:
virtual void A(int a)
{
cout << "foobar:" << a << "\n";
}
};
int main()
{
foobar x;
x.foo::A();
x.bar::A(1,2,3);
return 0;
}
I need to clearly remember A withouth argument come from foo, and A with three arguments come from bar. This is also not good for convenience.
When using the non virtual interface idiom, it's safer, and more explicit, to name the two functions (the public non-virtual and the private virtual) differently.
This shows well what the code does, and would solve your problem:
class foo
{
private:
virtual void doA(int a)=0;
public:
void A()
{
doA(1000);
}
void A(int a, int b)
{
doA(a+b);
}
};
And of course don't forget to change in the hierarchy.