template class inheritance syntax - c++

My intention is to have some base class CBaseClass that, amongst other things, serves as a container to some members of type CBaseMember; then to derive a CDerivedClass : public CBaseClass that holds CDerivedMember : public CBaseMember.
I can't use a pointer to CBaseMember and initialize it with a CDerivedMember object in CDerivedClass because it's a multiple inheritance situation, CDerivedMember has an additional interface (a pure abstract base class) that is irrelevant to CBaseClass implementation but needs to be visible to CDerivedClass. Lots of dirty casting is something that I would very much like to avoid.
My solution to this problem was to make CBaseClass a template, like this:
//declaration
template <class Member>
CBaseClass
{
protected:
virtual void GenericMethod();
virtual void VirtualMethod() = 0;
Member* member;
};
//definition
template <class Member>
void CBaseClass<Member>::GenericMethod()
{
member->SomeMemberMethod();
}
and then to inherit CDerivedClass from it, like this:
//declaration
CDerivedClass : public CBaseClass<CDerivedMember>
{
protected:
virtual void VirtualMethod();
};
//definition
void CDerivedClass::VirtualMethod()
{
member->SomeDerivedMethod();
}
Predictably, this doesn't work (CBaseClass<CDerivedMember>::GenericMethod() is unresolved, for obivious reasons), but unfortunatly I don't know how to change my code to mean what I intend for it to mean.
Can anyone please explain how those things are done properly - or suggest another solution for my problem?
Thanks!

Well, you could keep the dirty typecasts at one place, encapsulated in your class. Therefore, it's not really dirty anymore.
class CBaseMember {
public:
virtual void SomeMemberMethod(){}
};
class CDerivedMember : public CBaseMember {
public:
virtual void SomeMemberMethod() { /* do other stuff */ }
virtual void SomeDerivedMethod() {}
};
//declaration
class CBaseClass
{
protected:
virtual void GenericMethod();
virtual void VirtualMethod() = 0;
CBaseMember* member;
virtual CBaseMember * getMember() {
return member;
}
};
//definition
void CBaseClass::GenericMethod()
{
getMember()->SomeMemberMethod();
}
//declaration
class CDerivedClass : public CBaseClass
{
protected:
virtual void VirtualMethod();
virtual CDerivedMember * getMember() {return static_cast<CDerivedMember *>(member);}
};
//definition
void CDerivedClass::VirtualMethod()
{
getMember()->SomeDerivedMethod();
}
In summary, you do the dirty typecasting inside the getMember() method of the derived class. At that point you should be sure that the type of the member is CDerivedMember anyway. So, as long as you know that the pointer you have is of type CDerivedClass you will have access to its CDerivedMember without typecasting. If you have to fall back to a CBaseClass pointer, you'll naturally fall back to the CBaseMember while accessing its member.

I suspect that you want to get rid of the templates, because the snippet you provided would work (if you added the class keyword to the declaration of your types).
If you want to avoid downcasts from CBaseMember* to CDerivedMember*, you can approach the situation with dynamic binding and covariance:
class CBaseClass {
private:
CBaseMember* const baseMember;
protected:
virtual CBaseMember* member() const {
// ^^^^^^^^^^^
return baseMember;
}
/* everything else you need here. Just never ever access `baseMember` directly */
};
class CDerivedClass : public CBaseClass {
private:
CDerivedMember* const derivedMember;
protected:
virtual CDerivedMember* member() const {
// ^^^^^^^^^^^^^^
return derivedMember;
}
/* everything else you need here. Just never ever access `derivedMember` directly */
};
However, this only works if you will never change the member to point somewhere else, because you cannot pull this trick with a setter: virtual void CBaseClass::member(CBaseMember*) cannot be overridden with virtual void CDerivedClass::member(CDerivedMember*).
Note that you will still be carrying the baseMember pointer in your CDerivedClass around, although it is never ever used. So if memory is important to you, this might not be viable.

Related

How to call private virtual base class implementation when overriding in child class

I have a class hierarchy like this:
class Base
{
public:
void start() { init(); }
private:
virtual void init() = 0;
};
class Default : public Base
{
private:
virtual void init() override {/*default implementation*/};
};
class Special : public Default
{
private:
virtual void init() override final {/*specialized implementation*/};
}
Which works alright if I call start() on an object of type Special;
Now I have a case where in the implementation in the Special class I want to call the implementation of the Default class.
Normally that would work with Default::init();, but will fail here due to the Defaults declaration of this is private.
Obviously one solution is to change this from private to protected, but I'd like to ask if there is another way? Rather than allowing any child to call this function directly, I'd like to limit this to calls that are initiated via virtual functions already defined in the Base or Default class.
Is there some option or modifier that would allow member function calls to be only allowed from child classes if they are within (the same) overriding virtual member functions?
C++ doesn't provide means to achieve this directly, so you'd have to work around, e. g. in piece of code below.
Well, if you absolutely want to. I personally would rather just fall back to making the functions protected, document what they are intended for and when to be called, and then just trust the deriving classes to do the stuff right. That in the end keeps the interfaces cleaner and doesn't rely on a rather unusual (and perhaps ugly) pattern (actually passing this twice).
class Base
{
public:
virtual ~Base() { }
void start()
{
InitProxy p(*this);
init(p);
}
protected:
class InitProxy
{
public:
InitProxy(InitProxy const&) = delete;
void init()
{
m_base.Base::init(*this);
}
private:
friend class Base;
Base& m_base;
InitProxy(Base& base)
: m_base(base)
{ }
};
private:
virtual void init(InitProxy& proxy) { }
};
class Derived : public Base
{
void init(InitProxy& proxy) override
{
proxy.init();
}
};
You could let the proxy accept a member function pointer, if you want to apply this constraint to more than one function, so you wouldn't have to re-write the proxy for every function separately. Possibly you'd need to make a template from then, if function parameters differ.
Forward declare Special, and make it a friend of Default:
class Base
{
public:
void start() { init(); }
private:
virtual void init() = 0;
};
class Special; // Forward declaration
class Default : public Base
{
private:
virtual void init() override {/*default implementation*/}
friend class Special; // Friend declaration
};
class Special : public Default
{
private:
virtual void init() override final {
Default::init();
/*Other implementation*/
}
};

Implementing compositional behaviour for virtual methods

Suppose that I have a heirarchy of several classes:
class A {
public:
virtual void DoStuff() = 0;
};
class B : public A {
public:
// Does some work
void DoStuff() override;
};
class C : public B {
public:
// Calls B::DoStuff and does other work
void DoStuff() override;
};
It can naively be implemented:
void Derived::DoStuff() {
Base::DoStuff();
...
}
This implementation has a serious problem, I believe: one always has to remember to call base implementation when overrides.
Alternative:
class A {
public:
void DoStuff() {
for (auto& func: callbacks_) {
func(this);
}
}
virtual ~A() = default;
protected:
template <class T>
void AddDoStuff(T&& func) {
callbacks_.emplace_back(std::forward<T>(func));
}
private:
template <class... Args>
using CallbackHolder = std::vector<std::function<void(Args...)>>;
CallbackHolder<A*> callbacks_;
};
Usage:
class Derived : public Base {
public:
Derived() {
AddDoStuff([](A* this_ptr){
static_cast<Derived*>(this_ptr)->DoStuffImpl();
});
}
private:
void DoStuffImpl();
};
However, I believe that it has a good amount of overhead when actually calling DoStuff(), as compared to the first implementation. In the use cases which I saw, possibly long costruction of objects is not a problem (one might also try to implement something like "short vector optimization" if he wants).
Also, I believe that 3 definitions for each DoStuff method is a little too much boilerplate.
I know that it can be very effectively solved by using inheritance pattern simular to CRTP, and one can hide the template-based solution behind interface class (A in the example), but I keep wondering -- shouldn't there be an easier solution?
I'm interested in a good implementation of call DERIVED implementation FROM BASE, if and only if derived class exists and it has an overriding method for long inheritance chains (or something equivalent).
Thanks!
Edit:
I am aware of an idea described in #Jarod42's answer, and I don't find it appropriate because I believe that it is ugly for long inheritance chains -- one has to use a different method name for each level of hierarchy.
You might change your class B to something like:
class A {
public:
virtual ~A() = default;
virtual void DoStuff() = 0;
};
class B : public A {
public:
void DoStuff() final { /*..*/ DoExtraStuff(); }
virtual void DoExtraStuff() {}
};
class C : public B {
public:
void DoExtraStuff() override;
};
I am not sure if I understood correctly but this seems to be addressed pretty good by the "Make public interface non-virtual, virtualize private functions instead" advice.
I think it's orignated in the Open-Closed principle. The technique is as-follows:
#include <iostream>
class B {
public:
void f() {
before_f();
f_();
};
private:
void before_f() {
std::cout << "will always be before f";
}
virtual void f_() = 0;
};
class D : public B{
private:
void f_() override {
std::cout << "derived stuff\n";
}
};
int main() {
D d;
d.f();
return 0;
}
You essentially deprive descendant class of overriding public interface, only customize exposed parts. The base class B strictly enforces that required method is called before actual implementation in derived might want to do. As a bonus you don't have to remember to call base class.
Of course you could make f virtual as well and let D decide.

C++ add virtual method in polymorphic subclass

I have cumbersome class and I want to refactor it to replace type code with subclasses. At some point during such process I have following hierarchy:
// interface
ISomeClass(){
public:
virtual foo() = 0;
virtual ~ISomeClass();
}
// this class is cumbersome one with huge amount of conditional logic based on type
BaseSomeClass : public ISomeClass(){
public:
virtual foo(){
if(TYPE_0 == getType()){ // finally I want to move such conditional logic in subclass
doSmth();
} else if (TYPE_1 == getType()){
doAnother();
}
}
protected:
virtual int getType(){ // I temporary need it for refactoring issue
return type_; // to replace type_ with subclasses
}
private:
int type_;
};
// this classes is almost empty now, but I want to move there all conditional logic in future
class Implementation1 : public BaseSomeClass {
virtual int getType(){ // I temporary need it for refactoring issue
return TYPE_0; // to replace type_ with subclasses
}
};
class Implementation2 : public BaseSomeClass {
virtual int getType(){ // I temporary need it for refactoring issue
return TYPE_1; // to replace type_ with subclasses
}
};
In BaseSomeClassdefined additional virtual method getType(). Would this method behavior be polymorphic if I handle all the instances using some kind of interface ISomeClass pointer? Assuming the interface itself doesn't provide such virtual method. Please notice this code is a first step in refactoring, not final one. Also this is a simplified example and real code has tens of such methods, I need to do refactoring step by step. And the question is about C++ dynamic polymorphism.
You asked:
Would this method behavior be polymorphic if I handle all the instances using some kind of interface ISomeClass pointer? Assuming the interface itself doesn't provide such virtual method.
If the interface does not provide such a virtual method, you can't expect polymorphic behavior.
It'll be better to implement foo in Implementation1 and Implementation2.
class BaseSomeClass : public ISomeClass()
{
};
class Implementation1 : public BaseSomeClass
{
virtual void foo()
{
doSmth();
}
};
class Implementation2 : public BaseSomeClass
{
virtual void foo()
{
doAnother();
}
};
If you must use getType(), you can resort to template based polymorphic behavior.
template <typename D>
class BaseSomeClass : public ISomeClass()
{
public:
virtual foo()
{
int type = D::getType();
if(TYPE_0 == type)
{
doSmth();
}
else if (TYPE_1 == type)
{
doAnother();
}
}
};
Here, you are expecting D to provide the interface getType(). You might as well expect D to provide the interface foo.
template <typename D>
class BaseSomeClass : public ISomeClass()
{
public:
virtual void foo()
{
D::foo():
}
};

wrapper to template class inherited by another class

template <class CollectionItem>
class Collection
{
void A();
// Many other utility functions
}
class ICollection
{
virtual void B() = 0;
}
class Base : public Collection<BaseItem>, public IBase
{
virtual void B();
}
Is there any way of offering Collection functions via ICollection interface without wrapping all the functions in Base class? ICollection : public Collection<CollectionItem> is not an option.
Bounty Update:
OK, so the original idea was to have Interface to all Collection classes. Before we continue, every CollectionItem also has Interface, let's call it ICollectionItem and ICollection only knows about ICollectionItem.
So what I did was create another template class as Interface to Collection template class - ICollection (pure virtual) accepting ICollectionItem(s). Collection class inherits this interface.
Every Collection class (inheriting Collection<CollectionItem> class) would also inherit it's Interface Collection class. That Interface then virtual inherits ICollection<ICollectionItem>. I'll just post the code :)
Here is the code:
template <class ICollectionItem>
class ICollection
{
public:
virtual const ICollectionItem* At(const int idx) = 0;
};
template <class CollectionItem, class ICollectionItem>
class Collection
: public ICollection,
public virtual ICollection<ICollectionItem> // Weak point
{
private:
List<CollectionItem*> fContainer;
public:
Collection(void) {}
virtual ~Collection() {}
virtual const ICollectionItem* At(const int idx); // Casting GetAt result
virtual const TCollectionItem& GetAt(const int idx) const
virtual ListIterator<TCollectionItem> >* GetIterator(void) const;
virtual ListIterator<ICollectionItem> >* Iterator(void) const; // Weak point
}
Example usage:
class IBaseItem
{
public:
virtual int Number() = 0;
{
class BaseItem
: public IBaseItem
{
public:
virtual int Number();
void SetNumber(int value);
}
class IBase
: public virtual ICollection<IBaseItem>
{
public:
virtual IBaseItem* ItemByName(String name) = 0;
virtual ~IBase() {}
}
class Base
: public Collection<BaseItem, IBaseItem>,
public IBase
{
public:
BaseItem* GetItemByName(String name);
virtual IBaseItem* ItemByName(String name);
}
Weak points:
First is at using virtual inheritance ... lots written about it, not much to talk about, or is it?
Unable to access Iterator using ICollection interface. See ListIterator function, only first one can be implemented, the second one would require some kind of new List of IBaseItem. I decided to live with that and just use for loop.
Even tho I somehow managed to get what I wanted (With wrapping and casting), I would still like to hear an second opinion. I don't like using virtual inheritance, specially in such delicate situations - using Collections for application Base creation.
I can not see any other solution than calling some Collection method in Base implementation of IBase virtual methods.
class Base : public Collection<BaseItem>, public IBase
{
virtual void B()
{
A();
}
}
You say, and I quote:
I want to call Collection functions using IBase pointer
I really don't see what is to be done here besides dynamic_cast. It does exactly what you want it to do.
void fun(IBase * base) {
auto * coll = dynamic_cast<Collection<BaseItem>*>(base);
if (coll) {
coll->A();
}
}
Your Collection class must have a virtual destructor.
You can, of course, offer a templated version, if you'd need different baseitems in different, scenarios for some reasons. This has bad code smell and I think your architecture is bad at this point, but oh well.
template <typename T> void fun(IBase * base) {
auto * coll = dynamic_cast<Collection<T>*>(base);
if (coll) {
coll->A();
}
}
void test(IBase * p) {
fun<BaseItem5>(p);
}
If you have some other specific scenario in mind, please edit your question to say what you mean.
Hmm...So you wanna to reuse the Collection class's utility functions, and you want to design a class which will implement an interface defined by IBase. As you mentioned above,"wrapping all the functions in Base class" is a way to offer Collection functions.
(1) Via inheritance,derived class has a good knowledge of Collection
class Derived:public Collection<DerivedType>,public IBase{};
or
template <typename T>
class Derived:public Collection<T>,public IBase{};
(2) Via inheritance,derived class knows little about Collection,but through IBase
class IBase : public Collection<BaseItem>{};
class Derived:public IBase{};
By (1),If you want to call Collection functions using IBase pointer,you have to wrap the functions.
By (2), any Derived instance is " a kind of " IBase which is "a kind of " Collection. So you can use IBase pointer to call Collection functions.
So,the key point is that the objects pointed by the IBase pointer should have the method you want to call.Wrap it or inherit it. I can not see any other solution than these two ways.
Edit: the idea is refined based on your example:
Here is an idea:
//generic interface can be kept as it is
template <class ICollectionItem>
class ICollection
{
public:
virtual const ICollectionItem* At(const int idx) = 0;
};
class Empty
{
};
template <class CollectionItem , class BaseClass = Empty>
class GenericCollection
: public BaseClass
{
public:
const CollectionItem* At(const int idx);
// At and ItemByName are standard functions for a collection
CollectionItem* ItemByName(String name);
//note that here nothing has to be declared as virtual
};
//example usage:
class IBase
: public virtual ICollection<IBaseItem>
{
public:
virtual IBaseItem* ItemByName(String name) = 0;
virtual ~IBase() {}
};
class Base
: public GenericCollection<BaseItem, IBase >
{
public:
//nothing to be implemented here, all functions are implemented in GenericCollection and defined as virtual in IBase
//The definition of the functions has to be the same:
};
In collection you can implement whatever and in the interface you can define what ever you want to be virtual from your collection. The only thing is that you need to have some standard in naming convention for functions.
Hope this helps,
Raxvan.
From your comments in another answer, it seems you want a collection of interfaces, and an implementation of this interface. The simplest I can advise you is the following:
template<typename T>
class ICollection
{
public:
virtual iterator<T>* begin() const = 0;
};
template<typename T, typename TBase>
class Collection : public ICollection<TBase>
{
public:
iterator_impl<T>* begin() const { return whatever; }
};
Example:
class IItem {};
class Item : public IItem {};
class Base : public Collection<Item, IItem> {};
old answer:
Is there any way of offering Collection functions via IBase interface without wrapping all the functions in Base class ?
If I understood your problem, you want to use it like this:
void myfunc()
{
// ...
IBase* obj = ...;
obj->A();
obj->B();
}
I think here is a misunderstanding here: if you want A() to be callable from an IBase, then you have to add it to Ibase declaration.
If you want to use the Collection functions on an object, then you should cast this object to a Collection, via dynamic_cast for example.
Furthermore, if you have such a funcion:
void fun(IBase* base) { /* ... */ }
you cannot cast to a Collection*, since there are no relationship between these two classes, unless you have another way to be sure base is a Collection:
void fun(IBase* base)
{
if(base && base->isABaseItemCollection())
{
// Valid, since the real type was checked before
Collection* collection = (Collection*)base;
// ...
}
}
On a side note: you can generate bases almost automatically:
template
class Base : public Collection, public U {};
typedef Base BaseCollection;
According to comment/chat:
You have something like:
class IAnimal { /*...*/ };
class Cat : public IAnimal { /*...*/ };
class Dog : public IAnimal { /*...*/ };
class Cats
{
std::vector<Cat*> cats;
public:
Cat* at(size_t index) { return cats[index]; }
/*...*/
};
class Dogs
{
std::vector<Dog*> dogs;
public:
Dog* at(size_t index) { return dogs[index]; }
/*...*/
};
And you want to factorize some code using something like
class IAnimals
{
public:
std::vector<IAnimals*> animals; // or getter/setter which works with IAnimals.
/* some common factorized code */
};
// And so
class Cats : public IAnimals { /**/ };
class Dogs : public IAnimals { /**/ };
I propose, instead of creating class IAnimals, to use template functions as:
template <typename TAnimals>
void foo(TAnimals& animals)
{
Ianimals* animal = animals.at(42);
// ...
animal->eat(food);
// ...
}
You have to give compatible "interface" (names) to the type used in template.
Maybe you could have an operator() in IBase that would be delegated to Base?
class CollectionBase {};
template <class Item> class Collection: public CollectionBase {};
class IBase
{
public:
virtual CollectionBase* operator()() = 0;
};
class Base : public Collection<BaseItem>, public IBase
{
public:
virtual Collection<BaseItem>* operator()() { return this; }
};

C++ Inheritance with pure virtual functions

I'm trying to create a class that serves as a base object, which will then be sub-classed (=implemented) to serve various purposes.
I want to define one or more pure virtual functions, so that however subclasses the base class, is required and does not forget to implement them.
There is one caveat, the pure virtual function's signature includes the type of the base object. Once sub-classed, the function definition doesn't match the base classes definition anymore of course. E.g.:
class BaseItem
{
public:
virtual std::string getDifferences(const BaseItem& item) = 0;
}
So, in the derived class I'd like to do:
class DerivedClass : public BaseItem
{
public:
virtual std::string getDifferences(const DerivedClass& item) = 0;
private:
std::string derivedItemCustomObject;
}
which of course the compiler won't accept. I could make it a BaseItem of course, but then I can't utilize any objects in the derived class.
Do I have to use casting to accomplish this?
Please let me know if my intent/question is not clear.
There is NO need to change the function signature. Look at following:
class BaseItem
{public:
virtual std::string getDifferences(const BaseItem& item) = 0;
};
class DerivedClass : public BaseItem
{public:
virtual std::string getDifferences(const BaseItem& item) // keep it as it's
{
const DerivedClass& derivedItem = static_cast<const DerivedClass&>(item);
}
};
Can use static_cast<> without any fear because, DerivedClass::getDifferences() is called only for DerivedClass object. To illustrate,
BaseItem *p = new DerivedClass;
DerivedClass obj;
p->getDifferences(obj); // this always invoke DerivedClass::getDifferences
If you worry that sometime you might end up passing any other derived class object as an argument to the method, then use dynamic_cast<> instead and throw exception if that casting fails.
It's unclear what you're trying to achieve. Suppose that the compiler allowed you to do this (or you do this by the means of a cast), then it would open the following hole in the type system:
class BaseItem
{
public:
virtual std::string getDifferences(const BaseItem& item) = 0;
};
class DerivedClass : public BaseItem
{
public:
virtual std::string getDifferences(const DerivedClass& item)
{
item.f();
// ...
}
void f() const {}
};
class DerivedClass2 : public BaseItem
{
public:
virtual std::string getDifferences(const DerivedClass2& item) { ... }
};
void g()
{
BaseItem* x = new DerivedClass;
// oops, calls DerivedClass::f on an instance of DerivedClass2
x->getDifferences(DerivedClass2());
}
Your design is probably wrong.
I assume that the compiler accept but DerivedClass::getDifferences doesn't override BaseItem::getDifferences. Here is a way to achieve what you apparently want
template <typename T>
class DerivedHelper: public BaseItem {
public:
virtual std::string getDifferences(const BaseItem& item) {
getDifferences(dynamic_cast<const T&>(item));
}
virtual std::string getDifferences(const T& item) = 0;
};
class DerivedClass : public DerivedHelper<DerivedClass>
{
public:
// not more needed but providing it will hide getDifferences(const BaseItem& item)
// helping to statically catch some cases where a bad argument type is used.
virtual std::string getDifferences(const DerivedClass& item) = 0;
private:
std::string derivedItemCustomObject;
};
but be aware that there is a runtime check which will throw exceptions if the argument isn't of the correct class.
One way to accomplish this is to use a template and have the parameter be the type of the derived type
template <typename T>
class BaseItem {
public:
virtual std::string getDifferences(const T& item) = 0;
};
class DerivedClass : public BaseItem<DerivedClass> {
public:
virtual std::string getDifferences(const DerivedClass& item) {
// Implement it here
}
};
You should use cast from BaseItem to DerivedClass + runtime check if given BaseItem is a DerivedClass instance.