Virtual inheritance ambiguous function [duplicate] - c++

This question already has answers here:
Virtual Inheritance: Error: no unique final overrider
(2 answers)
Multiple (diamond) inheritance compiles without "virtual", but doesn't with
(2 answers)
Closed 6 years ago.
I have this part of code
#include <iostream>
using namespace std;
class A {
public:
int i;
A(){i = 0; }
virtual void f() { cout << i; }
};
class B1 : virtual public A {
public:
B1() { f(); }
void f() { cout << i+10; }
};
class B2 : virtual public A {
public:
B2() { f(); }
void f() { cout << i+1; }
};
class C : public B1, public B2 {
public:
C() {}
};
void main(){
C c;
//c.A::f();
}
First, I understand the main idea behind using virtual inheritance (diamond) in order to create only one A object in memory.
In this example, I get compilation error in C class:
override of virtual function "A::f" is ambiguous
If I remove the virtual inheritance. The code compiles, there is no error in class C as before.
If I remove the comment from the last code line it still compiles. I understand that in this case the f() function that will be executed is the one from the first class that C inherits from.
Now, if I replace c.A::f() with c.f() I get a compilation error at this specific line.
Can someone please explain this behaviour and the differences between these cases?

The problem is with C not with your expression call. As f is virtual and redefined twice in B1 and B2 then the C class is malformed because a call to fwould be ambiguous (which override to choose?). Add an override of f in Cand everything will be ok.

Within the class C you must choose which variant of f to usr. That is, using B1::f; or using B2::f.

Related

Is it valid to override virtual function with pure specifier? [duplicate]

This question already has answers here:
Can I override a virtual function with a pure virtual one?
(2 answers)
Turning a non-pure virtual function into pure in a subclass
(2 answers)
Closed 2 years ago.
Note: I do not ask whether or not this is reasonable thing to do or if this is good design. I'm just asking if this is well-defined behaviour and if the results are as expected.
I came upon a following class hierarchy:
struct A
{
virtual void foo() = 0;
};
struct B: public A
{
void foo() override
{
std::cout << "B::foo()\n";
}
};
struct C: public B
{
virtual void foo() = 0;
};
struct D: public C
{
void foo() override
{
std::cout << "D::foo()\n";
}
};
int main()
{
A* d = new D;
d->foo(); //outputs "D::foo()"
// A* c = new C; // doesn't compile as expected
}
Is this code well defined? Are we allowed to override definition with pure-specifier?
[class.abstract/5] of the current draft Standard:
[Note: An abstract class can be derived from a class that is not abstract, and a pure virtual function may override a virtual function which is not pure. — end note]
The very same note is included even in the C++11 Standard. So, the answer is yes, it is valid.

How to resolve function name collision in c++ muti-inheritance? [duplicate]

This question already has answers here:
C++ multiple inheritance function call ambiguity
(3 answers)
Closed 3 years ago.
I am inheriting from two classes. Both classes contain the same function name, but one being implemented and one being pure virtual. Is there any way that I can just use the one already implement?
#include <iostream>
using namespace std;
class BaseA {
public:
void DoSomething() {
value += 1;
std::cout<<"DoSomething():"<< value<<endl;
}
int value;
};
class BaseB {
public:
virtual void DoSomething() =0;
};
class Derived : public BaseA, public BaseB {
public:
Derived() { value = 0; }
// Compiler complains DoSomething() is not implemented.
// Can we just use BaseA.DoSomething()?
};
int main() {
Derived* obj = new Derived();
obj->DoSomething();
}
You need to define a function because DoSomething is a pure-virtual function in BaseB class. But you can call the DoSomething from BaseA class in your implementation:
void DoSomething(){
BaseA::DoSomething();
}

Are only virtual methods overridden [duplicate]

This question already has answers here:
Why do we need virtual functions in C++?
(27 answers)
Closed 7 years ago.
I am trying to understand virtual and pure-virtual functions in C++. I came to know that in the derived class the virtual methods are overridden with the implementation given in the derived class.
Here is the code that i used to test this :
#include <iostream>
using namespace std;
class Base
{
protected:
int a;
public :
virtual void modify ()
{
a=200;
}
void print ()
{
cout<<a<<"\n";
}
};
class Derived : public Base
{
int b;
public :
void modify()
{
a=100;
b=10;
}
void print ()
{
cout<<a<<"\t"<<b<<"\n";
}
};
int main ()
{
Base b;
b.modify ();
b.print ();
Derived d;
d.modify ();
d.print ();
return 0;
}
Output :
200
100 10
This means that the print () is also overridden along with the modify ().
My Question :
Then why do we need virtual methods at all...?
Consider this case with your code sample:
Base* b = new Derived();
b->modify();
b->print();
Even though b points to an instance of Derived, the invocation of virtual method b->modify would correctly call Derived::modify. But the invocation of b->print, which is not declared virtual, would print 200\n without the leading \t char as you have in Derived::print.

Why does an overridden virtual function get called in the base class during construction? [duplicate]

This question already has answers here:
C++ virtual function from constructor [duplicate]
(7 answers)
Closed 7 years ago.
There is a c++ program:
# include <iostream>
using namespace std;
class base
{
public:
base()
{
cout<<"base"<<endl;
f();
}
virtual void f() {
cout<<"base f"<<endl;
}
};
class derive: public base
{
public:
derive()
{
cout<<"derive"<<endl;
f();
}
void f() {
cout<<"derive f"<<endl;
}
};
int main()
{
derive d;
return 1;
}
and it outputs:
base
base f
derive
derive f
I am wondering why base f appears?
I quess in base the constrctor expands to:
cout<<"base"<<endl;
this.f();
But this should point to derive so why base f is print out?
During construction, in the baseclass constructor, the actual type of the object is base, even though it lateron continues to become a derived. The same happens during destruction, btw, and you can also verify the type using typeid.

multiple virtual inheritance in C++ complains on specific function call

In C++ multiple inheritance with virtual base
i understand why could this code be ambiguous , but why it still complains when i specifically call a derived class method ?
class A {
public:
virtual void f() { cout << 1 ;}
};
class B :virtual public A {
public:
virtual void f() { cout << 2; }
};
class C :virtual public A {
public:
virtual void f() { cout << 3; }
};
class D : public B, public C {};
void main(){
D* d = new D();
d->B::f();
getch();
}
i would expect that it will run the B:f() method but i get :
"ambiguous inheritance of 'void A::f(void)'
The problem is that your function is virtual which means it overrides address in vtable. You can't override one address with two functions.
Without virtual qualifier there would be just ambiguity during the call which can be avoided just like you did specifying base class B::f()
The problem is that your class D has two final overriders of function f. See http://en.cppreference.com/w/cpp/language/virtual about final overrider.