Ambiguity in Multiple Inheritance - c++

Let's say i have this simple code
#include <iostream>
using namespace std;
class A {
public:
void show() {
cout << "A" << endl;
}
};
class B {
public:
void show() {
cout << "B" << endl;
}
};
class C:public A, public B {
};
int main()
{
C obj;
obj.show();
}
this throws a compile time error because the call to function show() is ambiguous. I want to know how does the compiler understand this? Object creation is a run time process, so, how does the compiler know before hand that an object of Class C is going to be created which would invoke show(). Can anybody please tell me the concept behind this?

You are inheriting both the base classes A and B which has the same method show in C. This is the reason you are facing the compiler error ambiguous access of 'show'.
To get over it, you need to be more explicit on which `show method you would want to invoke. It would be easy to do it using the scope resolution operator.
To invoke show method of A: obj.A::show();
To invoke show method of B: obj.B::show();

This concept is called "Late Binding" in "Polymorphism". It means, the code tells the compiler to understand what to do on runtime. You should use virtual functions in this manner; and it is only available when you use this with "pointers". Let me give you a little example.
class Teacher { //base class
string name;
int numOfStudents;
public:
Teacher( const string &, int ); // constructor of base
virtual void print() const; // a virtual (polymorphic) function
};
class Principal : public Teacher{ // derived class
string SchoolName;
public:
Principal( const string &, int , const string & );
void print() const; // also virtual (polymorphic)
};
If you create a Principal object on main function and then call its print() function, compiler will run the function which is defined in "Principal" class. But if you don't define a print() function in a class which you derived from "Teacher" class, then when you call a print() function of that class' object pointer it will run the print() defined in "Teacher" class.
But again do not try this with the object itself, you should do it with pointers.
Best regards.

Here is the answer you are looking for: obj is of type C which means it is both type A and type B. I am trying to be careful not to say "has-a" when it is "is-a", but, in my mind, an object of type C has also an object of type A and type B. When you call a constructor for type C, you would also call the constructors of type A and B.
So, up to the point of creation of obj, everything is fine. But, after that the compiler has to decide which of the two show()'s to call. And that is when it is getting confused.

You are inheriting from both the classes A and B. That's why it is showing you an error, namely because it is ambiguous. To handle this you can refer explicitly to the function or method should be invoked at the time of calling by the object of the C's object. This way the compiler doesn't get confused and doesn't show any error to you.
CODE :
class A{
public:
void show(){ cout<<"Class A"; }
};
class B{
public:
void show(){ cout<<"Class B"; }
};
class C : public A , public B{
public:
void disp(){ A::show(); } // Here You can make explicit from which class the method
// shall be called. I refer to method "show" from class A.
}
main(){
C obj;
obj.disp(); // Ambiguity in Multiple Inheritance Problem Solved
}

Related

Is it possible to force non-const virtual methods from superclasses to take precedence over const methods of the same name in a subclass?

Consider the following class definitions:
class foo {
virtual absl::Span<const Input *const> GetInputs() const = 0;
virtual absl::Span<Input *const> GetInputs() {
auto mutable_inputs = GetMutableInputs();
return absl::MakeSpan(mutable_inputs.begin(), mutable_inputs.end());
}
}
class bar : public foo {
absl::Span<const Input *const> GetInputs() const override {
return absl::MakeConstSpan(inputs_);
}
}
When calling bar.GetInputs() it seems like the only implementation found is the the one that returns a span of constant inputs. If I have an instance of bar, and want to create a span of non-const inputs, then I must cast bar to foo, and then call GetInputs.
If I cast bar to foo, then call GetInputs, I am then able to assign the result to a span of non-const inputs. Why does the compiler fail to identify the inherited non-const method with the correct return type? Is there a way to make the subclass identify that method?
In other words, is there a way to make the following code compile:
absl::Span<Input *const> tmp = bar.GetInputs()
If I understand your question, it has nothing to do with virtual functions or "precedence" of const, but is plain old "name hiding".
#include <iostream>
class Base {
public:
virtual void f(int) { std::cout << "Base(int)\n"; }
virtual void f(double) { std::cout << "Base(double)\n"; }
};
class Derived : public Base {
public:
virtual void f(double) { std::cout << "Derived(double)\n"; }
};
int main() {
Derived d;
int x=0;
d.f(x);
}
output: Derived(double)
The issue is, name lookup doesn't work the way it seems you expect.
For a given scope, it searches for names to build an overload set. Within the context of Derived, there is only one f(), so when it's found, the compiler stops searching further for more overloads.
It finds Derived(double) and that's the entire overload set, and so it is selected. When you cast your derived class to a reference to the base, and then call something, both functions (declared in the base) are considered, and overload resolution selects the best match.
Now, normally, for polymorphic types you are working with the objects in terms of pointers/references to the base, so it's not an issue. But if you are calling directly on the derived class (perhaps from inside a member of derived?) then it'll have this issue of the derived declaration hiding the base names.
To make the base names visible in the derived class, it's easy:
class Derived : public Base {
public:
using base::f; // <<<<<<<< just add this
virtual void f(double) { std::cout << "Derived(double)\n"; }
};
you should add
using foo::GetInputs;
in bar class to expose the base class function.
you will be able to call the base class function if the object is non-const

Pointer type object in inhertiance

In this code I am storing the address of object B in pointer type object of A.
If I call the function then the program must run the function of second class but it doesn't work and run function of 1st class.
If I put virtual before the parental class function then it moves towards other class function.
When I stored 2nd class address in pointer type object, program have to show 2nd class function. But it couldn't do this.
Why this is so?
#include<iostream>
using namespace std;
#include<conio.h>
class a
{
public:
void fun()
{
cout << "1st";
}
};
class b:public a
{
public:
void fun()
{
cout << "2nd";
}
};
class c :public a
{
public:
void fun()
{
cout << "3rd";
}
};
void main()
{
a *A;
b B;
c C;
A = &B;
A->fun();
_getch();
}
When i stored 2nd class address in pointer type object, program have to show 2nd class function...
Not, it does not. In C++ functions are associated with classes (types), not objects. So compiler looks at the type of the pointer your functions is called through. Then, it tries to find such function in the corresponding class definition.
In your case compiler sees "call to the function fun() through the pointer of type A" and it simply translates it to the address of fun() from class A.
*The callable function is stored elsewhere, but not inside the object.
Indeed, this is the point of "statically typed" languages: compiler looks at your object through the prism of the object`s type.
However, as was mentioned, if you want to make association of a function with particular object, you need to use the keyword virtual. This will create a virtual table for each object of class A (and all inherited from A). Then addresses of all functions marked is virtual will be stored inside this virtual table. Consequently, when inheriting class has its own implementation of a virtual function, the address of the new implementation will override the previous address inside the object`s virtual table.
Now, when you call fun() through the pointer of class A the control flow (now during the runtime) will make a lookup to the objects virtual table and will find an address to the function you expect.
class A
{
public:
virtual void fun()
{
cout << "1st";
}
};
class B
{
public:
void func() override
{
cout << "2nd";
}
}
void main()
{
a *A;
b B;
A = &B;
A->fun(); // -> "2nd"
// function address deduced at runtime
}
You need to use virtual keyword, otherwise inheritance might not work as you expected.
So change your class a as follows:
class a
{
public:
virtual void fun()
{
In c++, pointers are static. This means that they are always looking for the parent's functions, even if they are pointing to a child class. You can avoid this by declaring a:fun as virtual. Take a look at this:
http://www.cplusplus.com/doc/tutorial/polymorphism/

C++ : Automatically run function when derived class is constructed

So I recently accidentally called some virtual functions from the constructor of a base class, i.e. Calling virtual functions inside constructors.
I realise that I should not do this because overrides of the virtual function will not be called, but how can I achieve some similar functionality? My use-case is that I want a particular function to be run whenever an object is constructed, and I don't want people who write derived classes to have to worry about what this is doing (because of course they could call this thing in their derived class constructor). But, the function that needs to be called in-turn happens to call a virtual function, which I want to allow the derived class the ability to override if they want.
But because a virtual function gets called, I can't just stick this function in the constructor of the base class and have it get run automatically that way. So I seem to be stuck.
Is there some other way to achieve what I want?
edit: I happen to be using the CRTP to access other methods in the derived class from the base class, can I perhaps use that instead of virtual functions in the constructor? Or is much the same issue present then? I guess perhaps it can work if the function being called is static?
edit2: Also just found this similar question: Call virtual method immediately after construction
If really needed, and you have access to the factory.
You may do something like:
template <typename Derived, typename ... Args>
std::unique_ptr<Derived> Make(Args&&... args)
{
auto derived = std::make_unique<Derived>(std::forward<Args>(args));
derived->init(); // virtual call
return derived;
}
There is no simple way to do this. One option would be to use so-called virtual constructor idiom, hide all constructors of the base class, and instead expose static 'create' - which will dynamically create an object, call your virtual override on it and return (smart)pointer.
This is ugly, and what is more important, constrains you to dynamically created objects, which is not the best thing.
However, the best solution is to use as little of OOP as possible. C++ strength (contrary to popular belief) is in it's non-OOP specific traits. Think about it - the only family of polymorphic classess inside standard library are streams, which everybody hate (because they are polymorphic!)
I want a particular function to be run whenever an object is constructed, [... it] in-turn happens to call a virtual function, which I want to allow the derived class the ability to override if they want.
This can be easily done if you're willing to live with two restrictions:
the constructors in the entire class hierarchy must be non-public, and thus
a factory template class must be used to construct the derived class.
Here, the "particular function" is Base::check, and the virtual function is Base::method.
First, we establish the base class. It has to fulfill only two requirements:
It must befriend MakeBase, its checker class. I assume that you want the Base::check method to be private and only usable by the factory. If it's public, you won't need MakeBase, of course.
The constructor must be protected.
https://github.com/KubaO/stackoverflown/tree/master/questions/imbue-constructor-35658459
#include <iostream>
#include <utility>
#include <type_traits>
using namespace std;
class Base {
friend class MakeBase;
void check() {
cout << "check()" << endl;
method();
}
protected:
Base() { cout << "Base()" << endl; }
public:
virtual ~Base() {}
virtual void method() {}
};
The templated CRTP factory derives from a base class that's friends with Base and thus has access to the private checker method; it also has access to the protected constructors in order to construct any of the derived classes.
class MakeBase {
protected:
static void check(Base * b) { b->check(); }
};
The factory class can issue a readable compile-time error message if you inadvertently use it on a class not derived from Base:
template <class C> class Make : public C, MakeBase {
public:
template <typename... Args> Make(Args&&... args) : C(std::forward<Args>(args)...) {
static_assert(std::is_base_of<Base, C>::value,
"Make requires a class derived from Base");
check(this);
}
};
The derived classes must have a protected constructor:
class Derived : public Base {
int a;
protected:
Derived(int a) : a(a) { cout << "Derived() " << endl; }
void method() override { cout << ">" << a << "<" << endl; }
};
int main()
{
Make<Derived> d(3);
}
Output:
Base()
Derived()
check()
>3<
If you take a look at how others solved this problem, you will notice that they simply transferred the responsibility of calling the initialization function to client. Take MFC’s CWnd, for instance: you have the constructor and you have Create, a virtual function that you must call to have a proper CWnd instantiation: “these are my rules: construct, then initialize; obey, or you’ll get in trouble”.
Yes, it is error prone, but it is better than the alternative: “It has been suggested that this rule is an implementation artifact. It is not so. In fact, it would be noticeably easier to implement the unsafe rule of calling virtual functions from constructors exactly as from other functions. However, that would imply that no virtual function could be written to rely on invariants established by base classes. That would be a terrible mess.” - Stroustrup. What he meant, I reckon, is that it would be easier to set the virtual table pointer to point to the VT of derived class instead of keep changing it to the VT of current class as your constructor call goes from base down.
I realise that I should not do this because overrides of the virtual function will not be called,...
Assuming that the call to a virtual function would work the way you want, you shouldn't do this because of the invariants.
class B // written by you
{
public:
B() { f(); }
virtual void f() {}
};
class D : public B // written by client
{
int* p;
public:
D() : p( new int ) {}
void f() override { *p = 10; } // relies on correct initialization of p
};
int main()
{
D d;
return 0;
}
What if it would be possible to call D::f from B via VT of D? You will use an uninitialized pointer, which will most likely result in a crash.
...but how can I achieve some similar functionality?
If you are willing to break the rules, I guess that it might be possible to get the address of desired virtual table and call the virtual function from constructor.
Seems you want this, or need more details.
class B
{
void templateMethod()
{
foo();
bar();
}
virtual void foo() = 0;
virtual void bar() = 0;
};
class D : public B
{
public:
D()
{
templateMethod();
}
virtual void foo()
{
cout << "D::foo()";
}
virtual void bar()
{
cout << "D::bar()";
}
};

Missunderstanding in virtual function call

I have the following code, and I don't understand why it calls the A class function instead of B class function. Could someone tell me why??
#include<iostream>
using namespace std;
class A{
public:
virtual void f(int n){
f(n);
cout << "A";
}
};
class B :public A{
public:
virtual void f(float f){
cout << "B";
}
};
int main(){
A*p= new B;
p->f(5.1);
}
These are completely different functions. A function is identified by its name and its arguments. You have no overriding here: you have two distinct functions.
If you'd used the override keyword, the compiler would have immediately told you this.
I Modified your Code slightly as under. And I get the desired result.
i.e.: when accessing a derived class reference from a base class pointer I get the compiler to map my function call correctly to the derived class' implementation.
I guess the following facts apply:
A derived class would have to first implement(override: which doesn't say change the signature) the Virtual functions defined by the base class to be able to call/access them polymorphically.
After a base class has implemented the virtual functions they can very well be overloaded.
One other thing, If we see the VTable creation mechanism, Only when the derived class implements a virtual function defined at a base calss an entry for the same function name would be made. Otherwise the pointer A is still a map of the Class A and has no idea how to resolve the call to and ends up in implicitly casting the 5.1 double to int according to the implementation of function f in class A. this is pretty much what I mentioned in point#1
virtual functions and pure virtual functions are a means of providing/creating an interface which can be shared across different layers of your software, where the you simply share the interface and the can hide the implementation from the user. So having same function name/ interfaces defined by two classes would only cause more confusion.
#include<iostream>
using namespace std;
class A{
public:
virtual void f(int n){ cout << "A" << endl; }
};
class B :public A{
public:
void f(int f){ cout << "B" << endl; }
void f(float f){ cout << "B" << endl; }
};
int main(){
A*p= new B;
p->f(5.1);
}
Since there are lot of pros in this forum, ff there is anything incorrect in my answer, please put in your comments.
Thanks.

why I changed parent virtual function arguments in child hides the father function c++?

I made a class with virtual function f() then in the derived class I rewrote it like the following f(int) why can't I access the base class function throw the child instance ?
class B{
public:
B(){cout<<"B const, ";}
virtual void vf2(){cout<<"b.Vf2, ";}
};
class C:public B{
public:
C(){cout<<"C const, ";}
void vf2(int){cout<<"c.Vf2, ";}
};
int main()
{
C c;
c.vf2();//error should be vf2(2)
}
You have to do using B::vf2 so that the function is considered during name lookup. Otherwise as soon as the compiler finds a function name that matches while traversing the inheritance tree from child -> parent -> grand parent etc etc., the traversal stops.
class C:public B{
public:
using B::vf2;
C(){cout<<"C const, ";}
void vf2(int){cout<<"c.Vf2, ";}
};
You are encountering name hiding. Here is an explanation of why it happens ?
In C++, a derived class hides any base class member of the same name. You can still access the base class member by explicitly qualifying it though:
int main()
{
C c;
c.B::vf2();
}
You were caught by name hiding.
Name hiding creeps up everywhere in C++:
int a = 0
int main(int argc, char* argv[]) {
std::string a;
for (int i = 0; i != argc; ++i) {
a += argc[i]; // okay, refers to std::string a; not int a;
a += " ";
}
}
And it also appears with Base and Derived classes.
The idea behind name hiding is robustness in the face of changes. If this didn't exist, in this particular case, then consider what would happen to:
class Base {
};
class Derived: public Base {
public:
void foo(int i) {
std::cout << i << "\n";
}
};
int main() {
Derived d;
d.foo(1.0);
}
If I were to add a foo overload to Base that were a better match (ie, taking a double directly):
void Base::foo(double i) {
sleep(i);
}
Now, instead of printing 1, this program would sleep for 1 second!
This would be crazy right ? It would mean that anytime you wish to extend a base class, you need to look at all the derived classes and make sure you don't accidentally steal some method calls from them!!
To be able to extend a base class without ruining the derived classes, name hiding comes into play.
The using directive allows you to import the methods you truly need in your derived class and the rest are safely ignored. This is a white-listing approach.
When you overload a member function in a base class with a version in the derived class the base class function is hidden. That is, you need to either explicitly qualify calls to the base class function or you need a using declaration to make the base class function visible via objects of the derived class:
struct base {
void foo();
void bar();
};
struct derived: base {
void foo(int);
using base::foo;
void bar(int);
};
int main() {
derived().foo(); // OK: using declaration was used
derived().bar(); // ERROR: the base class version is hidden
derived().base::bar(); // OK: ... but can be accessed if explicitly requested
}
The reason this is done is that it was considered confusing and/or dangerous when a member function is declared by a derived function but a potenially better match is selected from a base class (obviously, this only really applies to member functions with the same number of arguments). There is also a pitfall when the base class used to not have a certain member function: you don't want you program to suddenly call a different member function just because a member function is being added to the base class.
The main annoyance with hiding member functions from bases is when there is a set of public virtual functions and you only want to override one of them in a derived class. Although just adding the override doesn't change the interface using a pointer or a reference to the base class, the derived class can possibly not used in a natural way. The conventional work-around for this to have public, non-virtual overload which dispatch to protected virtual functions. The virtual member function in the various facets in the C++ standard library are an example of this technique.