I usually try to find answers here before I post anything, but I'm not even sure how to formulate my question.
So here's what I want to do... I want to define a Base Interface, and a Derived Interface. Then, I want to implement the Base Interface, with extra variables and methods. Finally, I want to implemented a Derived class, from the implemented Base Interface BUT ALSO from the Derived Interface. I don't know about you, but my head hurts.
If I do something like below, I get Ambiguous definitions under the DerivedFloat code since that code "sees" both the GetBaseValue method from the IBase, inherited through IDerivedFloat, as well as the GetBaseValue inherited from Base.
Surely, there must be a way to derive a class which uses the expanded features of the Base Implementation, as well as making sure it implements the required IDerivedFloat methods.
Now... This is a dummy example to show what I'm conceptually trying to achieve. It's not a real life example.
template <typename VALUE_TYPE>
class IBase
{
public:
virtual VALUE_TYPE GetBaseValue() const = 0;
};
class IDerivedFloat : public IBase<FLOAT>
{
public:
virtual void SetBaseValue(const FLOAT & value) = 0;
};
// Implementation of Base
template <typename VALUE_TYPE>
class Base : public IBase<VALUE_TYPE>
{
public:
VALUE_TYPE GetBaseValue() const { return m_BaseValue; }
protected:
VALUE_TYPE m_BaseValue;
}
// Uses expanded Base AND implements IDerivedFloat
class DerivedFloat : public Base<FLOAT>, public IDerivedFloat
{
public:
void SetBaseValue(const FLOAT & value) { m_BaseValue = value };
}
You can use virtual inheritance to work around this problem:
class IDerivedFloat : virtual IBase<FLOAT>
{
public:
virtual void SetBaseValue(const FLOAT & value) = 0;
};
template <typename VALUE_TYPE>
class Base : virtual IBase<VALUE_TYPE>
{
public:
VALUE_TYPE GetBaseValue() const { return m_BaseValue; }
protected:
VALUE_TYPE m_BaseValue;
}
Using virtual inheritance gives the derive class one instance of the base class members, instead of one from each time it exists in the class hierarchy.
Multiple inheritance is an issue precisely because of the ambiguity issue you ran into, but there are ways to get around it. You have to explicitly tell the compiler which super you are calling the ambiguous functions from, by leading the function call with the super's name and a double colon.
Example:
- C inherits from A and B.
- A and B both have add() function.
- In C, you have to say A::add() or B::add() to tell the compiler which one to use.
Link for details and more complete implementation: http://www.cprogramming.com/tutorial/multiple_inheritance.html
Related
I'm not exactly sure what to call this inheritance scheme, but I'm trying to use a cloneable interface with a default implementation. I'm having some issues getting the correct scheme though.
I'm basing this somewhat on the cloneable interface defined in C#.
First I have my interface and default implementations:
template<class BaseType>
class ICloneable
{
public:
virtual std::shared_ptr<BaseType> Clone() const = 0;
};
template<class BaseType, class DerivedType>
class Cloneable : public ICloneable<BaseType>
{
public:
virtual std::shared_ptr<BaseType> Clone() const
{
return std::shared_ptr<BaseType>(new DerivedType(*(DerivedType*)this));
}
};
My desire is to have the following scheme.
// A pure virtual base interface
class Base : public ICloneable<Base>
{
public:
virtual void SomeFunc() = 0;
}
// Another implementation
class Imp1 : public Base, Cloneable<Base, Imp1>
{
public:
virtual void SomeFunc() {}
}
// An implementation
class Imp2 : public Cloneable<Base, Imp2>
{
public:
virtual void SomeFunc() {}
}
If I have a list of `std::shared_ptr' objects, I can invoke the Clone function when I want to make a deep copy without having to manually write the function in every one of the implementations.
Right now I get that Imp is an abstract class, which doesn't surprise me. Anyone know how I can get this default implementation idea to work? The point is to not have to manually write the clone function for every one of the implementations. It might not be doable but I'm out of ideas to try.
You could do the following:
#include <memory>
template<typename InterfaceType_>
struct ICloneable
{
using InterfaceType = InterfaceType_;
virtual ~ICloneable() = default;
virtual std::shared_ptr<InterfaceType> clone() const = 0;
};
template<typename T, typename Base = ICloneable<T>>
struct CloneableMixin : public Base
{
using InterfaceType = typename Base::InterfaceType;
// With the following line uncommented, code does not compile in MSVC
//using typename Base::InterfaceType;
std::shared_ptr<InterfaceType> clone() const override
{ return std::make_shared<T>(*static_cast<const T*>(this)); }
};
Now, this can be used as follows:
struct SomeBaseClass : public CloneableMixin<SomeBaseClass> { /*...*/ };
struct SomeDerivedClass : public CloneableMixin<SomeDerivedClass, SomeBaseClass> { /*...*/ };
Two notes:
In order to be able to access InterfaceType_ template parameter of ICloneable, you need to make it a template alias, and then use using typename Base::InterfaceType (as it is template parameter dependent type).
I've provided default type for Base template parameter of CloneableMixin - this allows to use it for base classes, for which you want to have clone implemented.
Moreover, two unrelated comments:
You don't need to type virtual - it's implied. It's a good idea to add override at the end (this makes sure that the method actually overrides something, otherwise a compiler will report an error).
You might consider using std::make_shared instead of new.
I am playing around with the Visitor pattern, and I have the following bit of code which compiles:
class DerivedVisitee;
class Visitor
{
public:
void visit(DerivedVisitee &v);
};
class Visitee
{
public:
virtual void accept(Visitor &v) = 0;
};
class DerivedVisitee : public Visitee
{
public:
void accept(Visitor &v) { v.visit(*this); }
};
I would like to provide a default visit method for all descendants of Visitee. As such, I tried to do the following:
class DerivedVisitee;
class Visitor
{
public:
void visit(DerivedVisitee &v);
};
class Visitee
{
public:
virtual void accept(Visitor &v) { v.visit(*this); } // added implementation here
};
class DerivedVisitee : public Visitee
{
// removed overridden method
};
But compilation fails with 'void Visitor::visit(DerivedVisitee &)' : cannot convert argument 1 from 'Visitee' to 'DerivedVisitee &' (MSVC). Can you explain why this happens, and what is a correct method for doing what I'm trying to do?
EDIT: Visitor::visit needs to work on DerivedVisitee objects only; to put it another way, I intend to use multiple overloaded Visitor::visit methods with different implementations, for different descendants of Visitee.
The basic answer is: you cannot in pure object oriented code.
By nature the Visitor pattern is about passing to visit the derived type, and in Visitee said type is unknown (it's a runtime property).
In C++, there exists a pattern called CRTP:
template <typename Derived, typename Base>
class VisiteeHelper: public Base {
public:
virtual void accept(Visitor& v) override {
Derived& d = static_cast<Derived&>(*this);
v.visit(d);
}; // class VisiteeHelper
and then you can derive from this:
// And there we see the "Curiously Recurring" part:
class DerivedVisitee: public VisiteeHelper<DerivedVisitee, Visitee> {
}; // class DerivedVisitee
class MoreDerivedVisitee: public VisiteeHelper<MoreDerivedVisitee, DerivedVisitee> {
}; // MoreDerivedVisitee
It's up to you to decide whether you prefer the dead-simple boilerplate or the smart (but potentially confusing) CRTP solution.
Personally, unless you have multiple overloads of accept (up to 4 per type by overloading on const-ness), I would not bother. It's about as much work to write the accept by hand, and it's dead simple, and immediately understandable.
You should pass Visitee& instead of DerivedVisitee& as argument of visit method. This is the whole point of using public inheritance and Polymorphism. Any derived object can be used where a base object is expected. At runtime, the actual type will be deducted and appropriate method will be called on that object.
I have searched stack overflow but haven't found something that exactly answers my question. I have an interface class which contains only pure virtual functions which I would like to be implemented by classes which derive from this class.
I have an interface that I will call BaseInterface which defines functions that I would like to be overridden in all classes which derive from this interface. In this example, say there is only one pure virtual function called toImplement. I create a class called Base which inherits from BaseInterface and adds some functionality to the inherited pure virtual functions. Base is still an abstract class since it does not implement the functions in BaseInterface.
I have several classes which derive from Base which all benefit from the common functionality of Base but specify what happens when toImplement is run on their instances. These classes should all be concrete and satisfy all the requirements set by BaseInterface. Below I define one of these classes called Derived.
All of this works fine when BaseInterface and Base are not templated. The code compiles and runs fine without defining (1.) or implementing (2.) toImplement in Base.
However I would like toImplement to work with different types. From what I understand it is fine to have pure virtual functions in a templated class. I template BaseInterface and Base on some type T. When I don't define toImplement in Base (1.), I cannot compile since Base doesn't know which toImplement to use in tryUsingImplemented. If I now add the definition to Base, the code pre-compiles but the linker cannot find the implementation of Base::toImplement. Finally, if I both define and implement toImplement in Base (1. and 2.), the code compiles.
I don't like this because I have a dummy implementation of toImplement in Base and I never want this implementation to be run. Additionally, because Base implements toImplement, Derived is no longer required to implement it. This makes BaseInterface useless in my eyes.
Can sombody enlighten me on how to enforce the implementation of toImplement in Derived, without having to implement it in Base first if that is at all possible?
template <typename T>
class BaseInterface {
virtual void toImplement(T & t) = 0;
};
template <typename T>
class Base : public BaseInterface<T> {
bool m_useImplemented;
public:
explicit Base(bool useImplemented) : m_usedImplemented(useImplemented) {}
void tryUsingImplemented(T & t) {
if (m_useImplemented)
toImplement(t);
}
protected:
// 1: Defining toImplement pure virtual function in Base
virtual void toImplement(T & t);
};
// 2. Implementing a version of toImplement in Base which does nothing
template <typename T>
inline void Base<T>::toImplement(T & t) {
// do nothing
}
class Derived : public Base<int> {
public:
explicit Derived(bool useImplemented) : Base<int>(useImplemented) {}
protected:
// 3. implementing toImplement in Derived
void toImplement(T & t) {
std::cout << "Doing stuff for Derived" << std::endl;
}
};
For future reference, it would be helpful if you provided the compiler error message.
However, in this case I know. There are two errors in your code:
toImplement is private in BaseInterface.
The lookup in tryUsingImplemented will not look in the base class. You're facing the lookup in dependent bases problem. To fix it, write this->toImplement(t).
You need to declare toImplement as protected in BaseInterface if you intend to call it from a derived class. I have removed all the overriding methods from the derived classes and replaced the parameter type of Derived::toImplement with int, and it compiles fine. The latter is necessary because Derived is not a template, so you need to use the template parameter passed to Base.
#include <iostream>
template <typename T>
class BaseInterface {
protected:
virtual void toImplement(T & t) = 0;
};
template <typename T>
class Base : public BaseInterface<T> {
bool m_useImplemented;
public:
explicit Base(bool useImplemented) : m_useImplemented(useImplemented) {}
void tryUsingImplemented(T & t) {
if (m_useImplemented)
toImplement(t);
}
};
class Derived : public Base<int> {
public:
explicit Derived(bool useImplemented) : Base<int>(useImplemented) {}
protected:
// 3. implementing toImplement in Derived
void toImplement(int & t) {
std::cout << "Doing stuff for Derived" << std::endl;
}
};
In Java, there is a detailed generic class hierarchy for containers. Java defines interfaces like ICollection<T> which is inherited by ISet<T> which is inherited by IList<T> and implemented by ArrayList<T>. I would like to create a similar hierarchy in a C++ library I am creating.
Using C++ templates however, makes this very cumbersome. For example, say I define an ISet<T>:
template<typename T>
class ISet
{
public:
virtual ~ISet() = 0;
virtual void add(T e) = 0;
virtual size_t size() = 0;
virtual bool isEmpty()
{
return size() == 0;
}
};
Then, if I wanted to make a List<T> which implements ISet<T>, I would have to list in the class definition every method that I wanted to inherit but not override, in order to let me later call it without something messy like alist::ISet<T>->isEmpty():
template<typename T>
class List : public ISet<T>
{
public:
...
void add(T e)
{
...
}
virtual sz size()
{
...
}
using ISet<T>::isEmpty; //well this is annoying
};
I understand the reason for this, and "why doesn't this work the way I expect it to?" has been answered in these qeustions: here and here.
My question is, is there a clean (or even any!) way to achieve this without having to explicitly list every inherited but not overridden method in the base class?
What I would really like would be something I could put in List<T> like:
using ISet<T>::*;
which would make all of the methods in ISet<T> dependent in the class definition of List<T>, and would alias them to List<T>::functionName.
Please tell me there is SOME way to achieve this without having to update every inheriting class's list of using directives each time I change one of my templated interfaces!
Do I have to resort to a preprocessor define of using directives defined along with the interface? Arrrrgghhhh!
This statement is incorrect:
... would have to list in the class definition every method that I
wanted to inherit but not override, in order to let me later call it
without something messy like alist::ISet->isEmpty():
Try to compile following code:
template<class T>
class Base {
public:
virtual void f1();
virtual void f2();
};
template<class T>
class Derived : public Base<T> {
public:
virtual void f1();
};
void foobar()
{
Derived<int> d;
d.f1();
d.f2();
}
If you mean that you want to access base class methods or members on derived class, you can simply do that more explicit way:
template<class T>
class Derived : public Base<T> {
public:
virtual void f1() { this->f2(); }
};
That is not messy and works as you asked, just little bit more explicit (some says it is good idea to always use this-> explicitly).
I have the following structure
class Base
{
public:
Base(Type);
virtual render
}
class A
{
public:
Base(Type == A);
void render()
}
class B
{
public:
Base(Type == B);
void render()
}
void client_function()
{
Base baseObject(A);
//Base is an instance of class A
baseObject.render()//runs class A render
}
There are things in the above code that are not c++ as far as I am aware, they are closely related to pattern matching found in Haskell for example, but this is the best way I could find to illustrate my question without already knowing the answer ;)
In writing I want the client to be able to create a base object and pass the type of object as an argument, the correct specification of the object is returned and the client need not care less about it, just knows that running render will run the correct specific render.
Please feel free to ask questions if I have been unclear :)
I think you need to read about virtual functions and inheritance:
http://www.parashift.com/c++-faq-lite/virtual-functions.html
http://www.parashift.com/c++-faq-lite/proper-inheritance.html
http://www.parashift.com/c++-faq-lite/abcs.html
You need run-time polymorphism. There is not much important part of constructor. You have to inherit the Base into A and B. For example:
class Base
{
public:
virtual void render (); // <--- declare 'virtual'
virtual ~Base(); // <--- very much needed to avoid undefined behavior
};
class A : public Base //<---- inheritance
{
public:
void render(); // <--- this also becomes 'virtual'
};
...
Now you can use as per your requirement.
Base *baseObject = new A(); // <----- need to use pointer (or reference)
(*baseObject).render(); // <--- other way to write: baseObject->render();
delete baseObject;
I'm not sure I understood your question. In C++ you cannot choose your base class at runtime, but you certainly can have your base class depend from the derived class. This is done by using templates and what is known as the Curiously Recurring Template Pattern:
template <typename T> class Base {
public:
virtual void render(T *) {}
};
class A : public Base<A>
{
public:
void render(A * t) {}
};
class B : public Base<B>
{
public:
void render(B * t) {}
};
void client_function() {
A a1;
A a2;
a1.render(&a2); // calls A::render
a1.Base<A>::render(&a2); // calls Base<A>::render
Base<A> * ba = &a1;
ba->render(&a2); // calls A::render
}
Hope this answers your question.
What you ask for is exactly what inheritance is for: creating object from a class hierarchy that specializes a functionality.
In your example, apart from syntax problems, things will work as you expect, i.e. method A::render will be called, even if you don't know at compile time that object, declared as a Base, is indeed a A. That's virtual inheritance magicness.