Shared template member function of multiple classes - c++

I have multiple classes that are quite different in their behavior, but at the same time, share common functions that have to access the member variables.
So what I want to do, is to create a templated member function to avoid extra copy-paste code duplication.
The final result should be like:
ClassA::CallFoo()
ClassB::CallFoo()
ClassC::CallFoo()
where CallFoo() is defined in a shared file like [weirdo hypothetical syntax]
<template this* T>::CallFoo(){T->memberX->DoStuff();}
Is something like that possible with C++? I cant seem to find anything concerning code reuse and multiple classes.
EDIT:
I have multiple classes, ClassA, ClassB, ClassC, ... ClassX, all of which have a member variable memberX. In order to use that member variable inside the member functions of the classes, I have to do some setup and preprocessing on that variable, which is equal for all of the classes. So ClassA can have a method DoCoolStuff1() which has to call [shared code] to get the updated shared variable, ClassB can have a method DoBoringStuff1() which also calls [shared code].
Unfortunately, memberX is not in my source code, but in library headers ClassA : public LibClass, so I cannot override it there.

If what you are saying is that all of these classes inherit from LibClass, which contains memberX, then just add one more layer of inheritance:
class myLibClass : public LibClass
{
void CallFoo() { // do stuff with memberX }
};
class classA : public myLibClass {};
class classB : public myLibClass {};
etc...

Related

Is there an efficient way to provide an alias for a class member in C++?

Here is a base class:
class Base
{
public:
int foo;
// ...
};
This class is declared in a header file that I cannot change because I don't have the rights to do so.
Here is a derived class:
class Derived : public Base
{
public:
// provide alias to Base::foo
// ...
};
Is there a way I can provide an alternate name that refers to Base::foo inside class Derived without using pointers or references?
In other words, is there any way to provide an alias without adding any extra class members to Derived?
Also, if conditional compilation directives can be avoided, that would be ideal.
No, there is no renaming feature (though there was some work done on such a feature in the early days but it was dropped).
There's no way to do what you want other than adding the desired name as a member to Derived, and forwarding it to the base class function. Note however that this can be inline and should be absorbed by the compiler so it won't hurt performance.

Does this example warrant the use of public inheritance

I'm trying to implement a library where Class1 provides about five public methods Method1 to Method5. Class2 provides two methods - Methods6 and Method7. And Class3 provides one method - Method8. Now, for the end user, I want to expose methods from combination of these classes. E.g. If the end user instantiates a class called Class1Class2, they should have access to Method1 to Method7, if they instantiate a class called Class1Class3, they should have access to Method1 to Method5 and Method8.
There are 3 different approaches I could think of (please suggest any others as well):
Multiple inheritance: Keep each of Class1, Class2 and Class3 as it is. Then, create a new class Class1Class2 that publicly multiple inherits from Class1 and Class2. Similarly I can create a class Class1Class3 that publicly multiple inherits from Class1 and Class3.
Multi-level inheritance: I could derive Class2 from Class1, and call that Class1Class2. And Class3 from Class1 and call that Class1Class3. And if we need Class1Class2Class3, we inherit that class from Class2 and Class3, which have both derived from Class1. Here, we would use virtual inheritance to resolve the diamond problem. I don't expect to use Class2Class3, so that shouldn't be a problem here.
Composition: Keep each of Class1, Class2 and Class3 as it is. Create Class1Class2 that implements each of the methods Method1 to Method7 and internally delegate them to the objects of Class1 and Class2 accordingly. Similarly, a Class1Class3 would compose objects of Class1 and Class3. With this approach we need to provide implementations for all the methods and delegate them to the composed objects.
While "Composition over inheritance" guideline is generally great for loose coupling of classes, etc., in the above case, where we have to do code reuse from separate concrete implementations, Approach 1 or 2 seem like better options.
You are only talking about code reuse here. I would think that's because you don't actually need nor want actual polymorphism. If this is indeed the case, then consider private inheritance and using to expose the parent methods.
For example:
class Class1Class2 : Class1, Class2 {
public:
using Class1::Method1;
// ...
using Class2::Method6;
// ...
};
Private inheritance, while technically being called inheritance, is very different from public inheritance, which itself is conceptually different from subtyping.
In C++ (and a lot of other languages that support OOP), public inheritance usually provides both subtyping and code reuse. However, it is entirely possible to derive a class with incorrect behavior in places that expect the parent class. This potentially undermines subtyping. It is also entirely possible to derive a class that does not reuse any of the implementation of the parent class. This potentially undermines code reuse.
Conceptually, subtyping is expressed by interface inheritance, while implementation inheritance is only one way to reuse code. The "composition over inheritance" saying, as far as I understand it, is about using other tools to reuse code because implementation inheritance often leads to bad code. However, there isn't really another way to achieve true subtyping than inheritance, so it may still be useful there1.
On the other hand, private inheritance is just an odd form of composition. It simply replaces the member with a private base class. An advantage of this is the ability to use using to easily expose the parts of that "member" you want to expose.
1 I personally don't like either forms of (public) inheritance, prefering static polymorphism and compile-time duck typing. However, I can happily work with interface inheritance, whereas I usually stay far away from implementation inheritance.
As you want easy combination, you might use template as variant of your first proposal:
template <typename ... Bases>
struct Derived : Bases...
{
};
using Class1Class2 = Derived<Class1, Class2>;
using Class1Class2Class3 = Derived<Class1, Class2, Class3>;
To make things more interesting you may employ CRTP. Here is an example:
template<typename Base>
class ClassA {
public:
void MethodA1() {static_cast<Base*>(this)->MethodA1_Impl();}
void MethodA2() {static_cast<Base*>(this)->MethodA2_Impl();}
};
template<typename Base>
class ClassB {
public:
void MethodB1() {static_cast<Base*>(this)->MethodB1_Impl();}
void MethodB2() {static_cast<Base*>(this)->MethodB2_Impl();}
};
template<typename Base>
class ClassC {
public:
void MethodC1() {static_cast<Base*>(this)->MethodC1_Impl();}
void MethodC2() {static_cast<Base*>(this)->MethodC2_Impl();}
};
class ClassABC: public ClassA<ClassABC>, public ClassB<ClassABC>, public ClassC<ClassABC> {
public:
//void MethodA1_Impl();
//void MethodA2_Impl();
//void MethodB1_Impl();
//void MethodB2_Impl();
//void MethodC1_Impl();
//void MethodC2_Impl();
};
You may uncomment and implement ANY subset of MethodXY_Impl(), and that would compile. The client code may call any method from MethodXY(). If there is no corresponding implementation - the compiler would produce an error.

Storing different objects as one object type (c++)

I searched for this, but I feel I'm not finding the answer I'm after. So, simple version and hopefully someone can just say "here's how" and I'll be on my way :)
Essentially I want this:
class BaseObject
{
public:
BaseObject();
~BaseObject();
virtual bool FunctionX() =0;
virtual bool FunctionY() =0;
};
class ObjectA : BaseObject
{
public:
ObjectA();
~ObjectA();
bool FunctionX();
bool FunctionY();
bool FunctionZ();
};
.. same for ObjectB as above ..
...
vector<BaseObject*> myList;
ObjectA a;
ObjectB b;
myList.push_back((BaseObject*)&a);
myList.push_back((BaseObject*)&b);
myList.back()->FunctionX();
I know the code above is wrong, I'm just trying to get the overall concept over.
What I need:
A base class that defines functions that MUST be present in classes that inherit from it.
The ability to store the classes that inherit from it all in the same vector (cast as the base class).
The vector to know it can call the base classes defined functions.
The classes to be able to have their own, additional functions that the vector/base class do not need to be aware of.
I just noticed, you're deriving privately. BaseObject is a private base class of ObjectA. When you omit the inheritance specifier, you get private inheritance by default. Change the ObjectA declaration to
class ObjectA : public BaseObject...
Otherwise, code outside of the ObjectA scope is not allowed to know that ObjectA is-a BaseObject.
Your code is almost right. It misses the virtual for BaseObject's destructor, however, which will invoke undefined behaviour (e.g. crashes) in any typical usage scenario. This is the correct declaration:
virtual ~BaseObject();
Another thing you should consider is making your public functions non-virtual and your virtual functions private, with the public functions delegating to the private ones (called Non-Virtual Interface Idiom by Herb Sutter).
A few more things:
A base class that defines functions that MUST be present in classes
that inherit from it.
You won't be able to achieve this, at least in the literal sense, by any normal means. A class can derive from your abstract class but remain itself abstract by not defining your pure virtual functions.
The ability to store the classes that inherit from it all in the same
vector
Mind the difference between "class" and "object". A vector doesn't store classes but objects. In C++, classes cannot be used as objects (which is different in Java, for example). To "store classes" implies something like type lists in advanced template metaprogramming, a technique not related at all to your problem.
(cast as the base class).
You do not need to cast from subclass to base class.

Multiple Interfaces to a Class in C++

I have three classes that interact as follows. Class A contains a private member of type Class B. It also contains a method to which an object of type ClassC is passed. This method then calls a method on ClassC, passing to it a particular interface (ClassBInterface1) of its member of type ClassB:
ClassA
{
void Foo(ClassC ObjectC)
{
ObjectC.Bar((ClassBInterface1) ObjectB);
}
ClassB ObjectB;
}
My question is: ClassA does not need to access the methods of ClassB defined in Interface1. Therefore, in my view, it would be more elegant if the member of ClassA was of type ClassBInterface2, rather than ClassB. Is it possible to do this, while still passing B to C under Interface1?
The only way I can think of is to typecast ClassBInterface2 to ClassB and back to ClassBInterface1 in the Bar method in ClassA.
Is this the best way to do it? Or should I just leave it as it is?
Thanks a lot for any help.
If you define ObjectB as a ClassBInterface2 it won't be possible to convert it to ClassBInterface1 at runtime because it's internal structure won't be known.
Your way is the best one to do it but you can do a little modification. You don't need to do a explicit cast from ClassB to ClassBInterface1 while calling ObjectC.Bar because the compiler will do it for you.
If class B is defined as follows:
ClassB : public ClassBInterface1, ClassBInterface2
{
/*Class methods and attributes*/
}
you can just do the following while calling the Bar function on the ObjectC (assuming objectB is defined as ClassB)
ObjectC.Bar(ObjectB);
C++ has a great feature for this called "forward declarations". Basically, for any parts of your code that don't need to know the details of a class, you can simply pass around a reference. Only when you want to call member methods (including constructors and destructors) do you need to have the full class definition.
#include "ClassC.h"
class ClassB;
class ClassA
{
public:
void foo(ClassC& objectC)
{
objectC.bar(_objectB);
}
protected:
ClassB& _objectB;
};
Note that we include a header for ClassC because we need to call one of his methods.
Note that we forward declare ClassB and only hold a reference because we don't really care what he is.
Note finally that ClassA can't be instantiated currently, because somehow the reference to _objectB has to be set to something. For example, a constructor:
public ClassA(ClassB& objectB)
: _objectB(objectB)
{}
ClassA now only holds on to whatever reference was given to him on construction.
Based on your use of the term "interface" in your question, I assume you may have a class hierarchy. This answer can easily be extended to such a hierarchy. But the important point here is that concrete types always require a class definition, while simple reference object only require a forward declaration.

Is it necessary the scope resolution in this case?

Do we need to include the scope
baseClass::statmember.methodmember();
in a call to a static member of the base class that has been inherited when we call it from inside a method of the derived class?
I see it in a code programed by other person, I try to modify it and it compiles as well without including the scope
derivedclass::methodDerived() {
statmember.methodmember();
};
Why the programmer has included in all the calls to the member the scope:: if its unnecessary? Is it a reminder of the unicity of the static member in all the objects?
Or I am wrong and the code may give different results?
I'm guessing it's because the following is allowed:
class Base
{
public:
static void foo(){}
};
class Derived:public Base
{
public:
static void foo(){}
};
Either that, or for readability. Sometimes, just because it isn't necessary doesn't mean it has no use (even if that use is readability, which is a biggie).
It would be necessary only if the base class and the derived class have a function with the same name, and you want to distinguish between them.
Otherwise it's not necessary.