Interface to base class method - c++

For code below, are there any other ways to access a method in base through interface?
struct Base {
void funct_base() {
printf("Common function for class Foo and class Bar\n");
}
};
struct IFoo {
virtual ~IFoo() {}
virtual void funct_a() = 0;
// would like to access Base::bunct_base() from here
};
struct Foo : public Base, public IFoo {
virtual void funct_a() {
printf("I am Foo:: funct A\n");
}
};
class IBar {
virtual ~IBar() {}
virtual void funct_a() = 0;
// would like to access Base::bunct_base() from here
};
class Bar : public Base, public IBar {
virtual void funct_a() {
printf("I am Bar:: funct A\n");
}
};
I know this can be done, but I just do not like the wrapper, it does not seem clean:
struct IBar {
virtual ~IBar() {}
virtual void funct_a() = 0;
virtual void funct_base() = 0;
};
struct Bar : public Base {
virtual void funct_a() {
printf("I am Bar:: funct A\n");
}
virtual void funct_base() {
Base::funct_base();
}
};
EDIT:
The question is, there is one base class, and two different derived classes that inherit from the same base class. Is there a way to access a base class method through derived class interface without adding a base class method wrapper?

Use a abstract base class IBase with a Abstract method funct_base and make the interface class a Virtual base classes of the classes Base, IFoo and IBar:
struct IBase {
virtual void funct_base() = 0;
};
struct Base : public virtual IBase {
virtual void funct_base() override { printf("Common function for class Foo and class Bar\n"); }
};
struct IFoo : public virtual IBase {
virtual void funct_a() = 0;
};
struct Foo : public IFoo, public Base {
virtual void funct_a() override { printf("I am Foo:: funct A\n"); }
};
class IBar : public virtual IBase {
virtual void funct_a() = 0;
};
class Bar : public IBar, public Base {
virtual void funct_a() override { printf("I am Bar:: funct A\n"); }
};

Related

Avoiding C++ virtual inheritance

I'm trying to inherit from a hierarchy of abstract base classes, using an equivalent hierarchies of implementation classes. The only way I've figured out how to do it is using virtual inheritance.
/* Foo Interface */
class IFoo
{
public:
virtual void foo() = 0;
virtual ~IFoo() = default;
};
/* Bar Interface */
class IBar : virtual public IFoo
{
public:
virtual void bar() = 0;
virtual ~IBar() = default;
};
/* A specialized Foo */
class SpecificFoo : virtual public IFoo
{
public:
void foo() override { std::cout << "Foo!\n"; }
};
/* A specialized Bar */
class SpecificBar : virtual public IBar, virtual public SpecificFoo
{
public:
void bar() override { std::cout << "Bar!\n"; }
};
int main()
{
SpecificBar b;
b.bar();
return 0;
}
Although I'm not entirely opposed to using virtual inheritance, I'm not sure that it's the correct approach. Having to use dynamic_cast seems like something to avoid if possible. Is there a better way to do this?
I've tried something with an adapter pattern, but copy/pasting wrapper methods is getting out of hand.
I don't see the benefit of making IBar a sub-type of IFoo from the posted code.
IMO, it will be better to remove that inheritance.
/* Foo Interface */
class IFoo
{
public:
virtual void foo() = 0;
virtual ~IFoo() = default;
};
/* Bar Interface */
class IBar
{
public:
virtual void bar() = 0;
virtual ~IBar() = default;
};
/* A specialized Foo */
class SpecificFoo : public IFoo
{
public:
void foo() override { std::cout << "Foo!\n"; }
};
/* A specialized Bar */
class SpecificBar : public IBar
{
public:
void bar() override { std::cout << "Bar!\n"; }
};
/* A specialized Foo and Bar */
class SpecificFooAndBar : public IFoo, public IBar
{
public:
void foo() override { std::cout << "Foo!\n"; }
void bar() override { std::cout << "Bar!\n"; }
};
I came up with a solution that avoids virtual inheritance, but also gets rid of code duplication. I used a template parameter to specify the base class.
/* Foo Interface */
class IFoo
{
public:
virtual void foo() = 0;
virtual ~IFoo() = default;
};
/* Bar Interface */
class IBar : public IFoo
{
public:
virtual void bar() = 0;
virtual ~IBar() = default;
};
/* A specialized Foo */
template <typename _BaseClass>
class SpecificFooTpl : public _BaseClass
{
public:
void foo() override { std::cout << "Foo!\n"; }
};
using SpecificFoo = SpecificFooTpl<IFoo>;
/* A specialized Bar */
class SpecificBar : public SpecificFooTpl<IBar>
{
public:
void bar() override { std::cout << "Bar!\n"; }
};
int main()
{
SpecificFoo f;
SpecificBar b;
f.foo();
b.bar();
return 0;
}

Inheriting both abstract base interface and its implementation gives C2259

I have the following condition:
An absract base class with many pure virtual functions:
interface IBase
{
virtual void foo1() = 0;
virtual void foo2() = 0;
virtual void foo3() = 0;
virtual void foo4() = 0;
virtual void foo5() = 0;
// ...
virtual void fooN() = 0;
};
Two small interfaces that inherit it:
Version-A:
interface IBaseExt_A :
public IBase
{
virtual void foo_A() = 0;
};
Version-B:
interface IBaseExt_B :
public IBase
{
virtual void foo_B() = 0;
};
I create base class that implements all of the IBase interface functions:
class CBase :
public IBase
{
public:
virtual void foo1() { /* Do something... */}
virtual void foo2() { /* Do something... */}
virtual void foo3() { /* Do something... */}
virtual void foo4() { /* Do something... */}
virtual void foo5() { /* Do something... */}
// ...
virtual void fooN() { /* Do something... */}
};
Now, I want to implement both derived versions with minimal code.
I was hoping to do something like:
class CBaseExt_A :
public IBaseExt_A,
public CBase
{
public:
virtual void foo_A() { /* Do something... */}
};
Apparently this gives error:
C2259: 'CBaseExt_A': cannot instantiate abstract class...These errors refer to all IBase interface functions.
I know I can solve it the long way by delegating all IBase functions to CBase implementation:
class CBaseExt_A :
public IBaseExt_A,
public CBase
{
// IBase implementation:
public:
virtual void foo1() { CBase::foo1();}
virtual void foo2() { CBase::foo2();}
virtual void foo3() { CBase::foo3();}
virtual void foo4() { CBase::foo4();}
virtual void foo5() { CBase::foo5();}
// ...
virtual void fooN() { CBase::fooN();}
// IBaseExt_A implementation:
public:
virtual void foo_A() { /* At last - do what we came here for...*}
};
But this makes my small class CBaseExt_A become big and complex.
Is there a way how to avoid all this manual delegation coding?
Many thanks, PazO
You should use the following code:
interface IBase
{
virtual void foo() = 0;
......
};
class CBase : virtual public IBase
{
void foo() { }
......
};
interface IBaseExt_A : virtual public IBase
{
virtual void foo_A() = 0;
};
struct CBaseExt_A : public IBaseExt_A, public CBase
{
virtual void foo_A() { /* Do something... */ }
};
Note that both places where the IBase class is inherited should be marked as virtual.
I think you should specify one of the two inheritance to be virtual.
That is a diamond inheritance where
IBase is the top level
IBaseExt_A and CBase are the middle level
CBaseExt_A is the bottom level
so in CBaseExt_A you want to specify from which path implement the top level, I would say that you may want to specify CBase inheritance in IBaseExt_A to be public virtual instead of just public.
class CBaseExt_A :
public IBaseExt_A,
public virtual CBase
{
public:
virtual void foo_A() { /* Do something... */}
};

C++ virtual method with class specific parameter

Hi I have such an idea in my mind, but I don't know how to implement it. In my program I already have Base class, and few derived classes.
base.hpp
BaseClass {
public:
BaseClass();
virtual int getSomething(int param);
}
base.cpp
BaseClass::BaseClass(){};
int BaseClass::getSomething(int param)
{
return param * 5;
}
derived1.hpp
DerivedClass1 : public BaseClass {
public:
DerivedClass1();
}
derived2.hpp
DerivedClass2 : public BaseClass {
public:
DerivedClass1();
}
Now I use Derived or Base classes as needed.
BaseClass *c = (BaseClass *) new DerivedClass1;
cout << c->getSomething(5);
What I want is to have some type of class specific parameter in base class, which would be different for DerivedClass1 and DerivedClass2. Here is an example, how it could look like.
base.hpp
BaseClass {
public:
BaseClass();
virtual int getSomething(int param);
}
base.cpp
BaseClass::BaseClass(){};
int BaseClass::getSomething(int param)
{
return param * CLASS_SPECIFIC_PARAM;
}
Then for DerivedClass1 this CLASS_SPECIFIC_PARAM would be 5, for DerivedClass2 would be 6 or whatever.
Is this even possible to do ? What is the best approach to do this ?
You just add a parameter to your base class which children will reset on their own values:
base.hpp
BaseClass {
public:
BaseClass() : m_param(0) {};
virtual int getSomething(int param);
protected:
int m_param;
}
derived1.hpp
DerivedClass1 : public BaseClass {
public:
DerivedClass1() : m_param(5) {};
}
derived2.hpp
DerivedClass2 : public BaseClass {
public:
DerivedClass1() : m_param(6) {};
}
PS: And add a virtual destructor to your BaseClass
An alternative would be a virtual (or pure virtual function) instead of a protected member.
BaseClass {
public:
BaseClass();
virtual int getSomething(int param);
protected:
virtual int getClassSpecific() const =0;
}
//...
BaseClass::BaseClass(){};
int BaseClass::getSomething(int param)
{
return param * getClassSpecific();
}
//...
DerivedClass1 : public BaseClass {
//...
virtual int getClassSpecific() const { return 5;}
}
//.....
DerivedClass2 : public BaseClass {
//...
virtual int getClassSpecific() const { return 6;}
}

multi class inheritance setup issues

I have 3 interface (pure virtual) classes like this
class A {
virtual void M1() = 0;
virtual void M2() = 0;
};
class B : public A {
virtual void M3() = 0;
};
class C : public A {
virtual void M4() = 0;
};
I have the implementers like this
class Aimpl : A {
void M1 () override {};
void M2 () override {};
}
class Bimpl: public Aimpl, public B{
void M3() override {};
}
class Cimpl: public Aimpl, public C{
void M4() override {};
}
and
Bimpl b = Bimpl();
b.M2() // Error. M2 is ambigous. Can be from Aimpl or A
what's a simple way to fix this? I want to be able to pass around B or C in functions rather than Bimpl
Essentially, you have two different M2 methods in Bimpl: Aimpl::M2 and B::M2. You have run into the diamond-inheritance problem.
To fix it, you should use virtual inheritance. This question provides a very good overview. Essentially, you should use something like this:
class A {
virtual void M1() = 0;
virtual void M2() = 0;
};
class B : public virtual A {
virtual void M3() = 0;
};
class C : public virtual A {
virtual void M4() = 0;
};
class Aimpl : public virtual A {
void M1 () override {};
void M2 () override {};
};
class Bimpl: public virtual Aimpl, public virtual B {
void M3() override {};
};
class Cimpl: public virtual Aimpl, public virtual C {
void M4() override {};
};
Note that I'm not super super familiar with virtual inheritance, so this may or may not be the best way to apply virtual inheritance.

Using C++, how to call a base class method from a derived class method and apply this to an object passed as an argument?

I can't figure out how to call a base class method from a derived class method but concurrently applying this method call at an object passed as argument.
What I mean is this:
class Animal
{
virtual void eat(Animal& to_be_eaten) = 0;
};
class Carnivores: public Animal
{
virtual void eat(Animal& to_be_eaten) { /*implementation here*/}
};
class Wolf : public Carnivores
{
virtual void eat(Animal& to_be_eaten)
{ /*call eat method(of Base class) of Base to_be_eaten here*/ }
}
I thought of something like this
dynamic_cast<Carnivores&>(to_be_eaten).eat(*this) //and got a segmentation fault
Is there any way for this to be done?
Thank you!
New edit::
Updated the code
As simple as:
class Derived : public Base {
virtual void eat(Animal& to_be_eaten) {
Base::eat(to_be_eaten);
// do anything you want with to_be_eaten here.
}
};
EDIT: This works for me:
class Animal
{
virtual void eat(Animal& to_be_eaten) = 0;
};
class Carnivores: public Animal
{
virtual void eat(Animal& to_be_eaten) { /*implementation here*/}
};
class Wolf : public Carnivores
{
virtual void eat(Animal& to_be_eaten)
{
Carnivores *c = dynamic_cast<Carnivores*>(&to_be_eaten);
if(c)
c->Carnivores::eat(*this);
}
}
Note that i had to make Base::eat public in order to call it from Derived.
If I understand correctly, what you want is not to use a virtual call on the parameter object (to_be_eaten). I think only an object can do that for himself. I don't think there's a way for other objects to do it for him.
class Base
{
public:
virtual eat(Base& to_be_eaten);
protected:
virtual callEatNonVirtual(Base& other) = 0;
};
class Derived1 : public Base
{
public:
virtual eat(Base& to_be_eaten)
{
to_be_eaten.callEatNonVirtual(*this);
}
protected:
virtual callEatNonVirtual(Base& other)
{
Base::eat(other);
}
};
class Derived2 : public Base
{
public:
virtual eat(Base& to_be_eaten)
{
to_be_eaten.callEatNonVirtual(*this);
}
protected:
virtual callEatNonVirtual(Base& other)
{
Base::eat(other);
}
};