Virtual inheritance and same name members - c++

I have the the following classes:
class Base
{
public:
Base() { x = 3; }
int x;
virtual void foo() {};
};
class Med1 : public virtual Base
{
public:
int x;
Med1() { x = 4; }
virtual void foo() {};
};
class Med2 : public virtual Base
{
public:
virtual void goo() {};
virtual void foo() {};
};
class Der : public Med1, public Med2
{
public:
Der() {}
virtual void foo() {};
virtual void goo() {};
};
And the following code:
Base* d = new Der;
d->foo();
cout << d->x;
Output:
3
Why is that? Med1 constructor is called after Base constructor. I'm guessing it's setting Med1::x, and not Base::x, but why is Der::x the same as Base::x and not Med1::x. Why is there no ambiguity?

d is a pointer to Base, so d->x refers unambiguously to Base::x. There would only be an ambiguity if it were a pointer to Der.

Since it is pointer to Base x will be of Base.
And the order of constructor is super class and then derived class. So constructor of Base class is called first and then of Der.

The variable x is not virtual, so the compiler has to scratch its head and say - hang on you Base. Therefore it goes to Base->x

Related

How to call virtual functions of a derived class through base class pointers, assuming functions in base class are not virtual

class Base
{
public:
virtual void f()
{
g();
}
virtual void g()
{
cout<<"base";
}
};
class Derived : public Base
{
public:
virtual void f()
{
Base::f();
}
virtual void g()
{
cout<<"derived";
}
};
int main()
{
Base *pBase = new Derived;
pBase->f();
return 0;
}
In this program I have kept both derived and base class functions as virtual. Is it possible call virtual functions of derived class through base class pointer and base class functions are not virtual.
Thanks in advance..
assuming functions in base class are not virtual
This can be achieved via type erasure. But there are caveats.
Your "base" class should decide between the two:
Being a view class (can't be called delete on or created by itself)
Being a resource owning class (implemented similar to 1, but stores a smart pointer).
Here is an example for case 1: https://godbolt.org/z/v5rTv3ac7
template <typename>
struct tag{};
class base
{
public:
base() = delete;
template <typename Derived>
explicit base(tag<Derived> t)
: _vTable(make_v_table(t))
{}
int foo() const { return _vTable.foo(*this); }
protected:
~base() = default;
private:
struct v_table
{
virtual int foo(const base &b) const = 0;
protected:
~v_table() = default;
};
template <typename Derived>
static const v_table& make_v_table(tag<Derived>){
struct : v_table
{
int foo(const base &b) const {
return static_cast<const Derived&>(b).foo();
}
} static const _vTable{};
return _vTable;
}
private:
const v_table& _vTable;
};
class derived : public base
{
public:
explicit derived()
: base(tag<derived>{})
{}
int foo() const { return 815; }
};
// example
#include <iostream>
int main(){
derived d{};
const base& b = d;
std::cout << b.foo() << '\n';
}
Take notice, that you can only take a pointer or a reference (cv-qualified) to a base class. The base class can't be created on its own.
Also tag<T> is needed to call a templated constructor.
DO NOT CALL DERIVED METHODS IN THE BASE CONSTRUCTOR OR DESTRUCTOR
Simple answer is no, if the function you are calling is not virtual. The Compiler would have no Idea that you are trying to call a function from the Derived Class, and won't make and I'm paraphrasing here since I do not know the proper term for,"Won't make proper entries in the Virtual Table".
class Base
{
public:
void f()
{
std::cout<<"Base f() Called\n";
g();
}
virtual void g()
{
std::cout<<"Base g()\n";
}
virtual ~Base(){std::cout<<"Base Destroyed\n";}
};
class Derived : public Base
{
public:
void f()
{
g();
}
virtual void g()
{
std::cout<<"Derived g()\n";
}
~Derived(){std::cout<<"Derived Destroyed\n";}
};
int main()
{
Derived* D1 = new Derived();
Base* B1 = D1;
B1->f();
delete B1;
return 0;
}
Have a look at the following code, I have not declared Base::f() as virtual,calling B1->f() calls the Base Method, but the base method calls a virtual function Base::g() and this allows the "Derived" method be called.
Have a look at this thread or this blogpost to understand Virtual Tables.
(1) and you must ALWAYS declare the destructor of a base class virtual when destroying Derived Object through a Base Pointer, else the resources used by the Derived Object will never get destroyed and it's memory will leak until the program closes.
Don't Take my word as gospel, I am simply passing on knowledge I have acquired from first hand experience, Except for (1), specially if you are not using smart pointers

convert an object created with base class ctor to a derived class

I have the following classes:
class Base {
public:
virtual ~Base(){}
Base() {}
virtual void foo() = 0;
};
class Derived : public Base {
public:
virtual ~Derived(){}
Derived() : Base() {}
void foo() { printf("derived : foo\n"); }
};
class IInterface {
public:
virtual ~IInterface() {}
virtual void bar() = 0;
};
class C : public Derived, public IInterface {
public:
virtual ~C(){}
C() : Derived(){}
void bar() { printf("C : bar\n"); }
};
now I have a bunch of Derived* objects and I want to apply different interfaces on them :
Derived* d = new Derived();
C* c = dynamic_cast<C*>(d);
c->bar();
c->foo();
dynamic_cast returns nullptr and with c-style cast i get seg fault.
is there anyway to achieve this?
note that my objects are already created with Derived ctor.
i just want to treat them differently using Interfaces
The only way to achive this is to create a new object and move the data over from the old object.
Try encapsulating the behaviour that needs to change at runtime. Instead of inheriting from the IInterface, you have a member variable that is an IInterface pointer. Then instead of overriding bar in the child class, you pass the call to bar through to whatever is being pointed at. This allows modular behavior that looks just like polymorphism, but is more flexible:
class IInterface {
public:
virtual ~IInterface() {}
virtual void bar() = 0;
};
class Derived : public Base {
public:
IInterface* m_bar;
virtual ~Derived(){}
Derived() : Base(){}
void bar() {return m_bar->bar(); }
void foo() { printf("derived : foo\n"); }
};
You then derive and create IInterface objects and can associate any of them with Derived objects.

How can specify the base class from whom I derive in multiple inheritance?

I have a homework for my programming course that asks me to designs an abstract from whom derive two classes, and from those two derived classes derives another class.
This brings the Deadly Diamond of Death problem. Which can be solved by virtual inheritance, though I need instance the objects of my first two classes to a pointer of my abstract class. And this can't be done with any kind of virtual inheritance. So, if there is a way to specify the base class from which the multiple inheritance class will derive, it would be astronomically useful.
Example:
#include <iostream>
using namespace std;
class Base {
public:
virtual void foo(){};
virtual void bar(){};
};
class Der1 : public Base {
public:
virtual void foo();
};
void Der1::foo()
{
cout << "Der1::foo()" << endl;
}
class Der2 : public Base {
public:
virtual void bar();
};
void Der2::bar()
{
cout << "Der2::bar()" << endl;
}
class Join : virtual Der1, virtual Der2 {
private:
int atribb;
};
int main()
{
Base* obj = new Join();
((Der1 *)(obj))->foo();
}
Compiler error:
nueve.cpp: In function ‘int main()’:
nueve.cpp:43:30: error: ‘Base’ is an ambiguous base of ‘Join’
Base* obj = new Join();
Use virtual inheritance.
class Der1 : public virtual Base {
public:
virtual void foo();
};
class Der2 : public virtual Base {
public:
virtual void bar();
};
If virtual is declared while deriving from base class, as shown in below example, the most derived class object contains only one base class sub object, which helps in resolving the ambiguity in your case.
After doing some code changes, your final executable code:
Code changes in below sample:
Added vitual key word, while deriving the child classes.
Removed "virtual" keyword while deriving most derived class.
Modified main to invoke the member function properly.
#include <iostream>
using namespace std;
class Base {
public:
virtual void foo(){};
virtual void bar(){};
};
class Der1 : public virtual Base {
public:
virtual void foo();
};
void Der1::foo()
{
cout << "Der1::foo()" << endl;
}
class Der2 : public virtual Base {
public:
virtual void bar();
};
void Der2::bar()
{
cout << "Der2::bar()" << endl;
}
class Join : public Der1, public Der2 {
private:
int atribb;
};
int main()
{
Base* obj = new Join();
obj->foo();
}
It's not clear what you're asking for, although you seem to be saying that virtual inheritance from Base is not suitable. So, assuming that's correct, you can replace Base* obj = new Join(); with Base* obj = (Der1*)new Join(); and you'll get a pointer to the Base object that's the base of Der1. Similarly, you can replace it with Base* obj = (Der2*)new Join(); and you'll get a pointer to the Base object thats the base of Der2.

get derived classes access the member data and functions of each other

how to make derived classes access the member data and functions of each other. both classes are inherited from base class as pure abstract.
here my scenario
class Base
{
public:
virtual void do_something() = 0;
};
class Derived1 : public Base
{
public:
virtual void do_something()
{
// need to use a2
// need to use func
}
private:
int a1;
};
class Derived2 : public Base
{
public:
virtual void do_something()
{
// need to use a1
}
void func(){}
private:
int a2;
};
Probably you need to re-think your design. There will be no memory allocated to a1 for Derived2's object and similarly for a2 and Derived1. What you are asking is equivalent to saying, both cat and dog are animals, I want to use cat::whiskers in dog.
You probably need this:
class Base
{
public:
virtual void do_something() = 0;
};
class Derived : public Base
{
public:
int a1;
int a2;
void func(){}
};
class Derived1 : public Derived
{
public:
virtual void do_something()
{
// can use a2 and func here
}
};
class Derived2 : public Derived
{
public:
virtual void do_something()
{
// need to use a1
}
void func() override {}
};

Which method will this inherited class call (virtual function)? c++

Say I have a base class
class Base
{
public:
void A() {do stuff};
void B() {A(); do stuff};
};
and a derived class
class Derived : public Base
{
public:
void A() {do things}
};
Derived derived1;
derived1.B();
will B call A of the base class or the A of the derived class?
I suspect B will call the A of the base class, and that in order for it to use the new redefined A, I have to make it virtual:
class Base
{
public:
virtual void A() {do stuff};
void B() {A(); do stuff};
};
Is that correct? Is that what virtual functions are used for?
Yes, correct on both counts...
try this
class Base
{
public:
virtual void A() {do stuff};
void B() { do stuff};
};
class Derived : public Base
{
public:
void A() {do things}
void B() {do things}
};
and
Derived d;
Base *p = &d;
p->A();
p->B();
function B will not be overrided