I have encountered a virtual method in a nested class.
##classone.h
class ClassOne: {
public:
class InnerClass{
public:
virtual void method1();
...
##classone.cpp
void ClassOne::InnerClass::method1()
{
...
}
I am subclassing ClassOne and need to extend method1(). What need's to be done with the nested class in that situation?
What I tried
##subclassone.h
class SubClassOne: public ClassOne{
public:
virtual void method1();
##subclassone.cpp
void SubClassOne::InnerClass::method1()
{
##New implementation
}
But that gives a multiple definition of ClassOne::InnerClass::method1()
method1 belongs to ClassOne::InnerClass, not ClassOne. When you inherit from ClassOne, the nested class from base class becomes a member of the derived class, too, and you can reach it by qualifying with either ClassOne:: or SubClassOne::. Hence the double definition error regarding method1.
You'll need to sub-class InnerClass, too. If you still wish to derive from ClassOne, it would look like this:
class ClassOne {
public:
class InnerClass {
public:
virtual void method1();
};
};
void ClassOne::InnerClass::method1()
{
}
class SubClassOne : public ClassOne {
class DerivedInnerClass : InnerClass { //
virtual void method1();
};
};
void SubClassOne::DerivedInnerClass::method1()
{
}
Related
How does one go about overriding such a function in the example below?
It's clearly not working the way I wrote it, but is it possible to implement something similar?
class Foo
{
public:
class Kid
{
public:
virtual void DoSomething();
};
};
class FirstBar : public Foo
{
public:
void Foo::Kid::DoSomething() override;
};
class SecondBar : public Foo
{
public:
void Foo::Kid::DoSomething() override;
};
My take on it - your bars want to have Kids of their own, properly inheriting:
#include<iostream>
class Foo
{
public:
class Kid
{
public:
virtual void DoSomething() {std::cout<<"Kid!\n";}
};
};
class FirstBar : public Foo
{
public:
class Kid : Foo::Kid {
public:
void DoSomething() override {std::cout<<"Kid Bar 1!\n";}
};
};
class SecondBar : public Foo
{
public:
class Kid : Foo::Kid {
public:
void DoSomething() override {std::cout<<"Kid Bar 2!\n";}
};
};
int main() {
Foo::Kid().DoSomething();
FirstBar::Kid().DoSomething();
SecondBar::Kid().DoSomething();
return 0;
}
Note inheriting from Foo is unnecessary unless Kid is defined as protected, but I left the inheritance in case it makes sense for other reasons.
One way to solve it is to inherit Foo::Kid
Live sample
class FirstBar : public Foo::Kid
You can inherit both Foo and Foo::Kid if you need to:
class FirstBar : public Foo::Kid, public Foo
Override is quite informative keyword. However, one can use it in class declaration only. Is there any reason to forbid its use in definitions? Example:
class Base
{
public:
virtual void Method() = 0;
};
class Child : public Base
{
public:
void Method() override;
};
// source.cpp
void Child::Method() override // oops
{
...
}
I need help for an implementation that uses multiple inheritance of Interfaces...
There is an existing code whith an interface which has a lot of functions. The instances are created using a factory.
class IBig
{
// Lot of pure virtual functions
};
And his inplementation:
class CBig: public IBig
{
// Implementation
}
I Want to split the interface in multiple smaller interfaces, but it should stay compatible to the existing code for some time.
Here is a sample of what I tried to do:
class IBaseA
{
public:
virtual void DoA() = 0;
};
class IBaseB
{
public:
virtual void DoB() = 0;
};
// The same interface, now based on multiple smaller interfaces
class IBig : public IBaseA, public IBaseB
{
};
class CBaseA: public IBaseA
{
public:
virtual void DoA()
{
printf("DoA\n");
}
};
class CBaseB: public IBaseB
{
public:
virtual void DoB()
{
printf("DoB\n");
}
};
// Inherit from base classes where the implementation is, and from IBig as
// the instance of CBig is returned as IBig.
class CBig: public CBaseA, public CBaseB, public IBig
{
};
The problem here is that the class CBig cannot be instanciated. The compiler says the functions DoA and DoB are pure virtual, even if they are inplemented in CBaseA and CBaseB. What should I do if i don't want to implement again the functions, just to call the function of the base class ?
NB: I know the design is ugly, but this is only temporary until the big interface can be replaced, and.... I want to understand ! ;-)
Thanks in advance !
Here we should use virtual inheritance. This feature assures that there is only one instance of your virtually-inherited base class when you instantiate a subclass. For your example, this would look like:
#include <cstdio>
class IBaseA
{
public:
virtual void DoA() = 0;
};
class IBaseB
{
public:
virtual void DoB() = 0;
};
// The same interface, now based on multiple smaller interfaces
class IBig : virtual public IBaseA, virtual public IBaseB
// ^ ^
{
};
class CBaseA: virtual public IBaseA
// ^
{
public:
virtual void DoA()
{
printf("DoA\n");
}
};
class CBaseB: virtual public IBaseB
// ^
{
public:
virtual void DoB()
{
printf("DoB\n");
}
};
// Inherit from base classes where the implementation is, and from IBig as
// the instance of CBig is returned as IBig.
class CBig: public CBaseA, public CBaseB, public IBig
{
};
int main()
{
CBig cb;
}
The above changes ensure that there are not extra declarations of DoA and DoB created when you inherit from IBaseA and IBaseB multiple times.
Please refer the following example.
using namespace std;
//Base interface
class IBase
{
public:
virtual void BaseMethod1() = 0;
virtual void BaseMethod2() = 0;
};
class IEntity1 : public IBase
{
public:
virtual void Entity1Method1() = 0;
virtual void Entity1Method2() = 0;
};
class Entity1 : public IEntity1
{
public:
Entity();
//IBaseMethods
void BaseMethod1();
void BaseMethod2();
//IEntityMethods
void Entity1Method1();
void Entity1Method2();
//EntityMethods
void Method1();
void Method2();
};
In the above example, for all other entities deriving from IBase needs to implement BaseMethod1() and BaseMethod2().Because of which lots of code duplication is happening? Is there anyway where we can avoid redundant implementation of IBase methods in entities deriving from it?
You can use virtual inheritance in combination with a default base implementation class to encapsulate your default base behavior, and have it be only inherited by the concrete classes you want, like follows:
using namespace std;
//Base interface
class IBase
{
public:
virtual void BaseMethod1() = 0;
virtual void BaseMethod2() = 0;
};
class IEntity1 : virtual public IBase
{
public:
virtual void Entity1Method1() = 0;
virtual void Entity1Method2() = 0;
};
class BaseImpl : virtual public IBase
{
public:
virtual void BaseMethod1()
{
...
}
virtual void BaseMethod2()
{
...
}
}
class Entity1 : public IEntity1, public BaseImpl
{
public:
Entity1();
//IEntityMethods
void Entity1Method1();
void Entity1Method2();
//EntityMethods
void Method1();
void Method2();
};
There is, however, a runtime cost associated with virtual inheritance. Multiple inheritance also comes with some structural issues, e.g. base class construction.
You can even have some fun with template classes to make your class composition more modular:
template<typename TEntity, typename TBaseImpl>
class ConcreteEntity: public TEntity, public TBaseImpl
{
public:
ConcreteEntity() {}
};
class ConreteEntity1 : public ConcreteEntity<IEntity1, BaseImpl>
{
public:
ConreteEntity1();
//IEntityMethods
void Entity1Method1();
void Entity1Method2();
//ConreteEntity1 Methods
void Method1();
void Method2();
};
You could make a function that is called in BaseMethod1() implementations that are the same.
Something like this:
void BaseMethod1_common();
class Entity1 : public IEntity1
{
public:
Entity();
//IBaseMethods
void BaseMethod1() { BaseMethod1_common(); }
void BaseMethod2();
//IEntityMethods
void Entity1Method1();
void Entity1Method2();
//EntityMethods
void Method1();
void Method2();
};
First of all IBase deserves a virtual destructor.
Declare it pure virtual and define IBase:BaseMethod1() and
IBase::BaseMethod1().
If your intention is to hide implementation, then the only option would be to release the code as a library and then share only the header file among the other developers.
Implementing a global function, or using multiple inheritance as suggested still mean that your implementation is exposed.
However, if the intent is to reduce coupling among the various classes, there's another option :
Create a class that has the actual shared implementation, and then another class which will be an interface to it.
This interface class will then be the base class for other derived entities.
Example code is shown below :
//First Header and Cpp file
class Base_private
{
public:
BaseImpl(arguments);
~BaseImpl();
void BaseMethod1() {
//Implementation
}
void BaseMethod2() {
//Implementation
}
};
//Second Header and Cpp file
class BaseInterface
{
public:
BaseInterface(arguments);
~BaseInterface();
void BaseMethod1() {
m_pBase->BaseMethod1();
}
void BaseMethod2() {
m_pBase->BaseMethod2();
}
private:
Base_private* m_pBase;
};
class Entity : public BaseInterface
{
public:
Entity(arguments);
~Entity();
void Method1();
void Method2();
};
I have the following problem. I have a base class and several classes inheriting from it. All those classes are sharing a very similar interface and will most probably not be required to overload most of the shared methods.
However, all of them are using different member objects that are derived from each other and share a very similar interface too.
class BaseClass
{
protected:
Com* com;
public:
void setReady()
{
com->setReady();
}
}
class DerivedClass : BaseClass
{
protected:
DerivedCom* com;
}
class Derived2Class : BaseClass
{
protected:
Derived2Com* com;
}
How can I enable DerivedClass to have setReady() run its version of com instead of the one inherited from BaseClass?
Construct your instances with different implementations of Com. (Assuming DerivedCom implements Com)
class BaseClass
{
protected:
Com* com;
public:
BaseClass(Com* c = new Com) : com(c)
{}
void setReady()
{
com->setReady();
}
}
class DerivedClass : BaseClass
{
public:
DerivedClass() : BaseClass(new DerivedCom)
{}
}
class Derived2Class : BaseClass
{
public:
Derived2Class() : BaseClass(new Derived2Com)
{}
}
A simple solution is to introduce a getCom() protected virtual function, that returns a Com* or Com&:
virtual Com* getCom()
{ return this->com; }
The child classes can override it and return their own Com-derived instance. Your setReady() function can then be implemented as:
void setReady()
{
getCom()->setReady();
}
Your com member can then be made private, btw.
The drawback with this solution is that you'll have multiple Com-derived instances in the child classes.
Maybe a class template might help you:
class BaseClass
{
protected:
Com* com;
public:
virtual void setReady()
{
com->setReady();
}
};
template<typename T>
class ComDerived : public BaseClass {
protected:
T* com;
public:
void setReady()
{
com->setReady();
}
};
class DerivedClass : public ComDerived<DerivedCom>
{
};
class Derived2Class : public ComDerived<Derived2Com>
{
};
Why not templated mother class?
template <typename T>
class BaseClass
{
protected:
T* com;
public:
void setReady()
{
com->setReady();
}
};
class DerivedClass : BaseClass<DerivedCom>
{
};
class Derived2Class : BaseClass<Derived2Com>
{
};
To build on d909b's answer, I'd do something like:
class BaseClass {
private:
virtual Com * alloc_com() {
return new Com;
}
Com * com;
public:
BaseClass() : com(alloc_com()) {}
void setReady() {
com->setReady();
}
};
class DerivedClass {
private:
virtual Com * alloc_com() override {
return new DerivedCom;
}
};
class Derived2Class {
private:
virtual Com * alloc_com() override {
return new Derived2Com;
}
};
This works as long as DerivedCom publicly inherits from Com AND when Com has a virtual destructor. If Com does not have a virtual destructor, you also need to have a virtual dealloc_com function. Otherwise, you need to use a template or CRTP pattern, and then you're limited to cases where you are able to deduce the type of the object at compile time. If you know these are your only cases though, using templates will allow you to use the interface without adding virtual function call overhead.