Here are my classes:
class Base1
{
public:
Base1();
~Base1();
virtual void main_func()=0;
}
class D1 : public Base1
{
public:
D1();
~D1();
virtual void main_func(do_d1_main(););
}
class D2 : public Base1
{
public:
D2();
~D2();
virtual void main_func(){do_d2_main();};
}
class Base2
{
public:
Base2();
~Base2();
int m_needed_by_b1;
}
class D12B2: public Base2, public D1, public D2
{
public:
D12B2();
~D12B2();
}
Here's the problem:
Both do_main_func1() and do_main_func2() need access to member m_needed_by_b1 in Base2. How?
Could I define the virtual function main_func for each within class D12B2? That would give them access to all of D12B2, including Base2. How would I specify each separately?
I thought about adding a (protected) member in Base1, that is a pointer to a Base2 object. That would have to be set by D12B2. It seems like there might be a more elegant way to do this.
TIA
ken
It seems like there might be a more elegant way to do this.
More than likely, there is - don't use multiple inheritance.
However, if you are going to insist on using multiple inheritance, there are some things you must note: D1 and D2 should be inherited virtually in D12B2 to avoid the diamond problem. Assuming do_d1_main and do_d2_main actually means main_func, then you can implement a D12B2::main_func that will be able to access m_needed_by_b1.
But back to the original note:
It sounds like Base1 and Base2 should not exist, and D1 and D2 should be pure abstract classes. Which would leave you with
class D1
{
public:
virtual void d1_func() = 0;
};
class D2
{
public:
virtual void d2_func() = 0;
};
class D12B2 : public virtual D1, public virtual D2
{
public:
D12B2();
~D12B2();
virtual void d1_func()
{
// do something
}
virtual void d2_func()
{
// do something else
}
private:
int m_myData;
};
Related
I have the following code.
#include <iostream>
class Base1
{
public:
void print(){std::cout<<"Printing Base1\n";}
};
class Derived1: public Base1
{
public:
void print_1(){std::cout<<"Printing Derived1 \n";}
};
class Base2
{
public:
void myFunction1( Base1& b1)
{
myFunction2(b1);
}
virtual void myFunction2( Base1& b1)
{
b1.print();
}
};
class Derived2: public Base2
{
public:
void myFunction2( Derived1& d1)
{
d1.print_1();
}
};
int main()
{
Base1 b1;
Derived1 d1;
Base2 b2;
Derived2 d2;
b2.myFunction1(b1);
d2.myFunction1(d1);
return 0;
}
It results in the following output:
Printing Base1
Printing Base1
I thought of getting the following output
Printing Base1
Printing Derived1
One of the ways to get the desired output is to do the following.
class Derived2: public Base2
{
public:
void myFunction2( Base1& b1)
{
Derived1* d1 = static_cast<Derived1*> (&b1);
d1.print_1();
}
};
I would like to allow Derived2 to only deal with Derived1 and not with Base1. Otherwise, Some user may call Derived2::myFunction2 with Base1 object which can crash the program in such cases.
Is there a good solution?
myFunction2() in Derived2 does not override myFunction2() in Base2.
A virtual function gets overridden only if its signature matches, exactly. The function in this derived class takes a different parameter than the one in the base class. Hence, it does not override.
You have to make it override, as your first step.
class Derived2: public Base2
{
public:
void myFunction2( Base1& d1) override;
};
Now it's overridden. If you explicitly specified the override qualifier, as I did here, your compiler would've yelled at you already.
Now, your goal is to have whatever myFunction2 does, only have it take in effect for Derived1 class, and for all other Base1 classes, use what the superclass does.
Ok. This will require a little bit more work, and it will be slightly difficult to follow along. What needs to happen is another virtual inheritance, in Base1 this time:
class Derived2: public Base2
{
public:
void myFunction2( Base1& d1) override
{
d1.print_from_Derived2( *this );
}
};
Now, you need to define Base1::printDerived2(), which will invoke print(), which is what should happen in this case, according to your question:
class Base1
{
public:
virtual void print_from_Derived2( Derived2 &)
{
print();
}
};
And now, override it in Derived1 in order to put the last piece of the puzzle together:
class Derived1 : public Base1
{
public:
void print_from_Derived2( Derived2 &) override
{
// Do whatever print() from Derived2 needs to do, for
// this object, which is Derived1.
}
};
And here, you will do whatever needs to be done for Derived2 to print only Derived1. It's a bit of a circuitous route, but you finally reached the place where both actors are Derived1 and Derived2, without breaking any rules, and without any ugly casts.
You will need to do a bunch of forward declarations here, in order to stitch together all of these moving pieces. My examples are just brief simplifications, and they obviously have mutual references to each one, and will have to be broken apart into separate declarations and definitions, with appropriate forward declarations.
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 {}
};
I have a basic base class and a couple of sub-classes which inherit from it.
Class Base{
public:
Base(){};
virtual ~Base();
virtual void foomethod()=0; //Marked as pure virtual
};
Class A : public Base{
A(){}; //Ctor
~A(){}; //Dtor
void foomethod(){ /* DO SOMETHING */ }
}
Class B : public Base{
B(){}; //Ctor
~B(){}; //Dtor
void foomethod(){ /* DO SOMETHING */ }
}
Use of the above is throwing an error in the following usage:
Base a = A();
Base b = B();
The compiler is complaining about the function foomethod() being pure virtual.
However, when the following is used, there is no problem.
A a = A();
B b = B();
I would have thought that the first instance should be accepted due to C++'s principles of polymorphism. I want to enforce a specific method implementation of the method in sub-classes. If it is marked as virtual only, there is not guarantee that it will be explicitly overrided.
There are several issues with your code, I'll try to get most of them:
You can't have a pure function without marking it as virtual
You can't create objects of an abstract Base class (there's no code for the methods)
When you write
Base b = A();
you're creating two objects and then assigning the A object to the Base b object. This cannot happen since Base is abstract but in cases where this can happen you could experience the slicing problem.
You marked the destructor as virtual in the derived classes but not in the Base (and no definition either), always mark it as virtual when using virtual polymorphism otherwise derived destructors will not be called
This is a more correct way of doing it:
#include <iostream>
using namespace std;
class Base{
public:
Base(){};
virtual ~Base() {};
virtual void foomethod()=0; //Marked as pure virtual
};
class A : public Base{
public:
A(){}; //Ctor
virtual ~A(){}; //Dtor
void foomethod(){ cout << "Hello from A"; }
};
class B : public Base{
public:
B(){}; //Ctor
virtual ~B(){}; //Dtor
void foomethod(){ /* DO SOMETHING */ }
};
int main() {
// Base obj; // Can't do that
Base *obj = new A();
obj->foomethod(); // A's one
delete obj;
return 0;
}
http://ideone.com/gvcL9S
Oh and there were some syntax errors here and there.. and a visibility problem if you intend to use those functions from the outside.. but I believe the excerpt was just a pseudocode one.
I've got the following class structure:
class Common {
//members and data here.
};
class Derived1 : public Common
{
};
class Derived2: public Common, public Derived1
{
};
As I understand this hierarchy both Derived1 and Derived2 will share any members from Common.
Is there a way with out making Derived1 private in Derived2 to allow Derived2 to still inherit from Common but have separate function overrides.
Basically i need to override a virtual function in Derived1, and Derived2 but still have Derived1's function run (it's a threading api).
Any help apreciated.
As #Walkerneo points out, you don't need to inherit from both Common and Derived1. You can simply inherit from Derived1 and you'll also get inheritance from Common. You can explicitly call Derived1's method from Derived2's method by doing the following:
void Derived2::overriddenMethod ()
{
// Do something unique here
Derived1::overriddenMethod ();
// Maybe do some more stuff
}
You can achieve this even with single inheritance:
struct Base
{
virtual void foo() = 0;
virtual ~Base() { }
};
struct Intermediate : Base
{
virtual void foo() { /* ... */ }
// ...
};
struct Derived : Intermediate
{
virtual void foo()
{
Intermediate::foo();
// new stuff
}
};
Have you tried using virtual functions for runtime polymorphism and assigning a variable of your Derived2 class to a pointer of Derived1 class
class Common {
//members and data here.
public:
virtual void commonFunction() = 0; //keeping it pure virtual
};
class Derived1 : public Common
{
virtual void commonFunction(){
//do something in derived1
}
};
class Derived2: public Common, public Derived1
{
void commonFunction(){
//do something in derived2
}
};
int main(){
Derived2 derived2;
Derived1 *derived1;
derived1 = &derived2;
derived1->commonFunction(); //calls the common function definition in Derived1
/* ... */
}
when does ambiguity arise in multiple inheritance?
When you have replicated base class in several paths of inheritance and you are trying to cast to it or call its member-function.
struct A { };
struct B : A { };
struct C : A { };
struct D : B, C { }; // has replicated A as the base class
D d;
A* a = static_cast<A*>(&d); // oops
The problem has several remedies which depend on the context heavily (using virtual base classes, just refine the aforementioned cast, etc.)
More info here, especially here.
One famous example of ambiguity in multiple inheritance is the so-called Diamond Problem.
Summary:
"In object-oriented programming languages with multiple inheritance and knowledge organization, the diamond problem is an ambiguity that arises when two classes B and C inherit from A, and class D inherits from both B and C. If a method in D calls a method defined in A (and does not override the method), and B and C have overridden that method differently, then from which class does it inherit: B, or C?"
You can find details here: Wikipedia: Diamond Problem
struct Base{
void foo(){
}
};
struct Derived1 : public Base{
};
struct Derived2 : public Base{
};
struct Final : public Derived1, public Derived2{
};
int main(){
Final f;
f.foo();
}
See on Ideone. To fix, simply use virtual inheritance:
struct Derived1 : virtual public Base{
};
struct Derived2 : virtual public Base{
};
Another possibility for ambigouty is the following:
struct Base1{
void foo(){
}
};
struct Base2{
void foo(){
}
};
struct Final : public Base1, public Base2{
};
int main(){
Final f;
f.foo();
}
Again, on Ideone. To fix, simple make do the following in Final:
struct Final : public Base1, public Base2{
using Base1::foo;
// or
// using Base2::foo;
};
When it makes names used unclear
class baseX
{
private:
void* callA();//will never be ambiguous.
protected:
void* callB();
public:
void* callC();
}
class baseY
{
private:
void* callA();//will never be ambiguous.
protected:
void* callB();
public:
void* callC();
}
class derived: public baseX, public baseY
{
void someMethod()
{
void* x = baseX::callB();//not ambiguous
void* y = baseY::callB();//not ambiguous
void* z = callB();//ambiguose
}
}
void someFunction(derived& d)
{
void* x = d.CallC();//ambiguous
}
Ambiguity can also happen when the same class is the base through more than one route:
class Base
{
public void call();
}
class DerivedX : public Base
{
}
class DerivedY : public Base
{
}
class GrandChild : public DerivedX, public DerivedY //What does call() do?
{
}
This can be solved with virtual bases:
class Base
{
public void call();
}
class DerivedX : public virtual Base
{
}
class DerivedY : public virtual Base
{
}
class GrandChild : public DerivedX, public DerivedY //only one "Base" class in inheritance, shared between DerivedX and DerivedY
{
}