C++ Variable Type Selection at Runtime - c++

I am upgrading an old application which was written for a specific hardware interface. I now need to add support for a modern hardware to the existing application.
To do this, I would like to create a class for each hardware type, and assign a variable to one type or the other whenever the user selects which hardware is in their system.
For example:
Class HardwareType1 and Class HardwareType2 both exist having the same member functions.
object HW;
if (userHwType = 1)
// initialize HW as a HardwareType1 class
}
else{
// initialize HW as a HardwareType2 class
}
Now I can use HW.doSomething() throughout my code without a conditional for hardware type every time I interact with the hardware.
I'm sure this is pretty basic but to be honest I don't even know what this is called or what terms to search on for this one.
Thanks!

Create an an abstract base class, and derive two concrete classes from it: one implementing type1 and the other implementing type2:
class Hardware
{
public:
virtual ~Hardware() {};
virtual void doSomething() = 0;
};
class Hardware1: public Hardware
{
public:
void doSomething() { // hardware type1 stuff. }
};
class Hardware2: public Hardware
{
public:
void doSomething() { // hardware type2 stuff. }
};
Then create the necessary instance:
std::unique_ptr<Hardware> hardware(1 == userHwType ? new Hardware1() :
new Hardware2());
hardware->doSomething();
If you compiler does not support C++11 then std::unique_ptr will not be available to you. An alternative smart pointer would boost::scoped_ptr (or boost::shared_ptr).

Use polymorphism with a common abstract base class, like this:
class HardwareBase
{
public:
virtual void Open() = 0;
virtual void Close() = 0;
virtual ~HardwareBase() {};
};
Then derive your concrete hardware types:
class HardwareType1 : public HardwareBase
{
public:
virtual void Open() {...}
virtual void Close() {...}
};
And select the required hardware instance:
std::unique_ptr<HardwareBase> hw;
if (userHwType == 1)
hw.reset(new HardwareType1());
else
hw.reset(new HardwareType2());
// And use it like this:
hw->Open();
Note that you now need a pointer to the selected object instance.
Use a unique_ptr to automatically delete it on exit.

The term to search for is polymorphism; that's the general term for interacting with different types through a common interface.
In C++, if you need to select behaviour at runtime, the usual approach is to define an abstract interface, which acts as a base class for your concrete types, using virtual functions - the function to call is chosen at runtime depending on the true type of the object.
// Abstract interface
class Hardware {
public:
virtual ~Hardware() {} // needed to safely delete objects
virtual void doSomething() = 0; // must be implemented by each concrete type
};
// One concrete type
class HardwareType1 : public Hardware
{
HardwareType1() { /* initialise */ }
void doSomething() { /* implementation for this type of hardware */ }
};
// Another concrete type
class HardwareType2 : public Hardware
{
HardwareType2() { /* initialise */ }
void doSomething() { /* implementation for this type of hardware */ }
};
Now you can choose which to create, and then interact using the abstract interface:
// Create the correct type, depending on user input
std::unique_ptr<Hardware> hw
((userHwType == 1) ? new HardwareType1 : new HardwareType2);
// Do the right thing depending on the type
hw->doSomething();

You could search for factory method. That is the name of the pattern you are trying to implement

Related

Use derived class operations in function accepting pointer to abstract base class

Let's say I have an abstract base class that has two derived classes. Each of those derived classes has some new functionality not present in the abstract base class, but both derived classes have the same function. For example:
class MyBase:
public:
/* ... */
virtual void DoSomething() = 0;
/* ... */
class MyAlpha : public MyBase
public:
/* ... */
void DoSomething() { /* does sometihng */ }
/* Function not present in abstract base class */
void DoSomethingNew() { /* does something new */ }
/* ... */
class MyBeta : public MyBase
public:
/* ... */
void DoSomething() { /* does sometihng */ }
/* Function not present in abstract base class */
void DoSomethingNew() { /* does something new */ }
/* ... */
Now I have a templated function somewhere that accepts a pointer (in my case a std::unique_ptr) to the base class, and I want to be able to call the DoSomethingNew() function (the function that is present in both derived classes but not the base class. For example:
template <typename Base_t> void MyOperation(std::unique_ptr<Base_t> &base_object) {
/* some ops */
base_object->DoSomethingNew();
}
How do I go about doing this? I feel like template specialization might be the way to go here but I'm not quite sure. I am working on extending an open source library with a new feature, so I have limitation on what existing code I can/should modify to make my feature work. The base class in my actual use case is code that I'd like to avoid modifying, but for general use in this library, my function signature needs to accept a pointer to the base class.
As the base class is virtual, the actual usage is something like:
std::unique_ptr<MyBase> object = std::unique_ptr<MyAlpha>(new MyAlpha);
MyOperation(object);
How do I go about this using derived class functionality in the MyOperation() function? If it makes a difference, I have to stay C++11 compatible.
Each of those derived classes has some new functionality not present in the abstract base class, but both derived classes have the same function.
Then capture that in a possibly abstract intermediate class:
class MyMiddle : public MyBase {
public:
virtual void DoSomethingNew() = 0;
};
class MyAlpha : public MyMiddle {
public:
void DoSomething() override;
void DoSomethingNew() override;
};
class MyBeta : public MyMiddle {
public:
void DoSomething() override;
void DoSomethingNew() override;
};
This way you can implement the common functionality around DoSomethingNew by referencing MyMiddle, avoiding a lot of code duplication you might otherwise get.
Now I have a templated function somewhere that accepts a pointer (in my case a std::unique_ptr) to the base class, and I want to be able to call the DoSomethingNew() function.
Since you only have a pointer to the base class, the compiler will not out of the box allow you to call methods of a derived class on that. However, if you expect the implementation to actually be an instance of a derived class, you can cast to that.
Use a dynamic_cast to check whether the derived class is of the expected type and use it as that type if it is. Use a static_cast if you are 100% totally absolutely sure that the argument will always be of the derived class, now and forever in the future. In other words, don't. Go for dynamic_cast.
Note that dynamic_cast is available for raw pointers but not for unique_ptr. So you have two options: either keep the unique pointer to base and use a raw pointer to derived for access. Or cast the pointer in an elaborate multi-step procedure. The latter only makes sense if you want to hold on to the pointer for longer in a context where it needs to be of the derived type. The simple case goes like this:
void SomethingSimple(std::unique_ptr<MyBase> base) {
MyMiddle* derived = dynamic_cast<MyMiddle>(base.get());
if (derived == nullptr) {
// derived wasn't of the correct type, recover in a reasonable way.
return;
}
derived->DoSomethingNew();
}
The more complex pointer cast goes like this instead:
void SomethingComplicated(std::unique_ptr<MyBase> base) {
MyMiddle* derived = dynamic_cast<MyMiddle>(base.get());
if (derived == nullptr) {
// derived wasn't of the correct type, recover in a reasonable way.
return;
}
std::unique_ptr<MyMiddle> middle(derived);
// Here two unique_ptr own the same object, make sure not to throw exceptions!
base.release(); // Complete transfer of ownership.
SomethingThatNeedsTheNewFunction(middle); // Pass ownership of middle type.
}
Of course, std::unique_ptr does allow for custom deleters, which makes this whole setup way more fun. I recommend you read this answer for code that is propagating the deleter while constructing a unique pointer to a derived class. This only becomes necessary if your function signature allows for a non-standard deleter in its pointer argument.
You could do the above without the MyMiddle class, using two separate calls to dynamic_cast to try converting to each of your derived classes in turn. But as long as the middle class and the shared functionality makes sense conceptually I'd go for that. If you did two separate casts, then you could call a template function for both cases, and that template function could assume existence of that function even though it would be operating on different argument types. Doesn't feel like a great solution to me, though.
I feel like template specialization might be the way to go here but I'm not quite sure.
That would work if the caller would call the function with the actual derived type as the static type of the argument. So you could do
template <typename Base_t> void MyOperation(std::unique_ptr<Base_t> &base_object) {
// Handle the case where DoSomethingNew is not an option.
}
template <> void MyOperation(std::unique_ptr<MyAlpha> &alpha_object) {
alpha_object->DoSomethingNew();
}
template <> void MyOperation(std::unique_ptr<MyBeta> &beta_object) {
beta_object->DoSomethingNew();
}
But the following would still not call the specialized function:
std::unique_ptr<MyBase> object(new MyAlpha());
MyOperation(object);
Even though object dynamically contains a MyAlpha its static type is a unique pointer to MyBase, and that's what drives the template parameters. So I can't see a way where such a specialization would be useful to you.
dynamic_cast<> exists for when you need to either down cast or cross cast from your pointer-to-base into a derived class. In your example it would look something like this:
std::unique_ptr<MyBase> object = std::unique_ptr<MyAlpha>(new MyAlpha);
// ...
dynamic_cast<MyAlpha*>(object.get())->DoSomethingNew();
You can read more about it here, but as I mentioned in my comment, too many of these is an indicator you have a design problem. Especially here when you have that functionality in both derived classes, it could easily be moved into the base class.
As an alternative to dynamic_cast<> since you are unable to modify the base class, you could create your own base class where you inherit from the unmodifiable base class and customize the interface to something you will actually use.
class NewBase : public MyBase
{
public:
void DoSomething() = 0;
void DoSomethingNew() = 0;
};
std::unique_ptr<NewBase> object = std::unique_ptr<MyAlpha>(new MyAlpha);
// ...
object->DoSomethingNew();

design pattern to avoid unnecessary addition of abstract functions to accommodate new functionality

In below code I have abstract class TestAlgModule which I will be exposing to library users and there are several functionalities they can use such as VOLUME, MIXER and so on. However, suppose users need a new function which is added only in MixerManager then I need to add that in TestAlgModule abstract class and now suddenly all the derived class needs to add that without any benefit.
How do I avoid this?
#include <iostream>
using namespace std;
enum {VOLUME, MIXER, UNKNONWN};
class TestAlgModule {
public:
virtual void open(int type) = 0;
virtual void close(int type) = 0;
};
class volumeManager : public TestAlgModule
{
public:
void open(int type) {}
void close(int type) {}
};
class mixerManager : public TestAlgModule
{
public:
void open(int type) {}
void close(int type) {}
void differentFunction() {};
};
/* users calls this to get algModule and then call functions to get the job done */
TestAlgModule *getTestAlgModule(int type) {
switch(type) {
case VOLUME:
return new volumeManager();
case MIXER:
return new mixerManager();
default:
break;
}
return nullptr;
}
int main() {
TestAlgModule * test = getTestAlgModule(MIXER);
test->open();
//test->differentFunction(); this can't be called as it is not part of abstract class and users are exposed only abstract class
return 0;
}
If something is not clear please let me know and I will do my best to answer it. I am looking for a better way to do this i.e. change in VolumeManager should be independent of MixerManager.
If you want to use an abstract factory, like you did in above code, then you need to return a pointer to the base class. That is correct. And then you need to invoke all functions through the base pointer.
By the way, please do not use raw pointers. Please use std::unique pointers instead.
There are 2 possible solutions.
Add the interface functions as a none pure, but still virtual function to your base class, with a default behaviour.
virtual void differentFunction() {}
Because of the other pure functions, the base class is still abstract. This may lead to a fat interface. But in many cases it is an acceptable solution.
The second possibility is to downcast the base class pointer to your needed pointer, using dynamic_cast and checking the return value of the dynamic cast.
if(mixerManager* mm = dynamic_cast<mixerManager*>(test)) {
mm->differentFunction();
}
All this depends of course on the overall design and what you want to achieve. But the above 2 are the standard patterns.
There are also other design patterns that may fit your needs, like builder or prototype. Please check.

C++ plugin system where the plugins inherit from base class

I am trying to add a plugin capability to my C++ codebase. The difficulty arises because the plugins need to contain plumbing the plugin writer shouldn't be aware of (thus keeping the include file simple).
So, this is the setup:
"PluginBase.h". This is the class the plugin would inherit from.
class PluginBase {
virtual void PluginProcess() = 0; // the plugin-specific capability
};
"PluginPlumbing.h". The class that contains the plumbing.
class PluginPlumbing : public PluginBase {
void PlumbingFunction() {
// Some stuff
PluginProcess();
// Some more stuff
}
};
The outer framework code would (by loading the DLL/so of the plugin) acquire a pointer to a PluginPlumbing class instance, and then call PlumbingFunction() on it.
However, the conundrum I have is, I can't just upcast a PluginBase pointer I get from the DLL/so to a PluginPlumbing pointer as it clearly doesn't actually inherit from PluginPlumbing. And I can't have the plugin inherit from PluginPlumbing, because then I'm back at square one of exposing the plumbing to the plugin writer.
The only solution I can imagine is that instead of nicely inheriting, the PluginBase and the PluginPlumbing are entirely separate classes. The PluginBase would be instantiated by the DLL/so, and the PluginPlumbing instance would be instantiated by the framework, and handed that PluginBase pointer so it can make the plumbing calls. Is that the only solution to go about it?
If you want to expose some functionality from your plugins to external software you definitely have to provide some interface for that.
In your example you provided PluginBase interface with PluginProcess() function, so, any other user of your PluginBase interface can call it without having to care about its implementation.
If you need another interface with another method - do it the same way.
class PluginPlumbing {
public:
virtual void PlumbingFunction() = 0;
};
And hide the implementation in your DLL implementation:
class PluginPlumbingImpl : public PluginPlumbing {
public:
void PlumbingFunction() override {
// do the stuff
}
}
If it needs additional parameters - also pass it as abstract interface classes or POD structures. You should also have some declaration for your plugin function which will create exact instances for your interface implementations (which should be accessible by users of your plugins).
To summarize this, you should have something like that:
// myplugininterface.h
// this header will be exposed to plugin implementors and
// plugin consumers
class IMyPluginClass1 {
public:
virtual void func1() = 0;
virtual void func2() = 0;
}
// another interface, ties together other functionality
class IMyPluginClass2 {
public:
virtual void func1() = 0;
// you can even pass around your interface classes
virtual void doSomethingWithAnotherObject(IMyPluginClass1 *obj) = 0;
// or use "factory" methods to create objects
virtual IMyPluginClass1 *createObject() = 0;
}
// this is functions implemented by a plugins, they should create
// instances for your plugin objects
// you could do them as a static methods of your classes if you don't
// plan to expose that as C compatible plugins
IMyPluginClass1 *createObject1();
IMyPluginClass2 *createObject2();
// mycoolplugin.cpp
// specific implementation of your plugin, you or someone else
// compile this to plugin DLL
#include "myplugininterface.h"
class IMyPluginClass1Impl : public IMyPluginClass1 {
public:
IMyPluginClass1Impl() :
myMyValue(100500)
{}
void func1() override {
// implement
}
void func2() override {
// implement
}
private:
// you can have any private or even public members in your implementation
int mMyValue;
};
class IMyPluginClass2Impl : public IMyPluginClass2 {
public:
void func1() override {
// implement
}
void doSomethingWithAnotherObject(IMyPluginClass1 *obj) override {
// implement
// but don't assume you can cast IMyPluginClass1 to
// something specific, because it might be not yours implementation
// it depends on how carefully you design your interfaces and
// explain to plugin writers what is allowed and what is not
}
IMyPluginClass1 *createObject() {
// be careful with that, in that case you MUST declare
// virtual destructor as a part of your interface class
return new IMyPluginClass1Impl();
}
};
IMyPluginClass1 *createObject1() {
return new IMyPluginClass1Impl();
}
IMyPluginClass2 *createObject2() {
return new IMyPluginClass2Impl();
}
And users of your plugin can use it only by including myplugininterface.h and
obtaining addresses of create functions (this is platform dependent).
Keep in mind, that if you return instances created by new and allow
users of your plugins to delete objects created like that - you must
declare virtual destructor for your interface classes.
This is a general approach. It has some pitfalls when you have hierarchy for
your plugin objects, you cant share common implementation for your abstract
classes without putting some additional effort (assuming you don't want to have copypasta)

Associating children via parents in parallel inheritence hierarchies

I need to develop a C++ solution to represent an object with features, where the objects and features are represented by different objects, but the actual implementation of the association is implemented in a derived class which exists to encapsulate an external implementation. I know that this kind of thing is typical of inheritance-related problems, so I want opinions on the correct solution. The implementation part should be seen as a sort of API boundary -- the user code should not see it, or see it only once in order to select the implementation.
Here's an example:
#include <cstdio>
// External implementation 1
class SomeShape {};
class SomeBody { public: SomeShape *shape; };
// External implementation 2
class OtherShape {};
class OtherBody { public: OtherShape *shape; };
//////////////
class Shape
{
public:
virtual const char *name() { return "Shape"; }
};
class Body
{
public:
virtual void setShape(Shape *s) = 0;
};
class Factory
{
public:
virtual Shape *makeShape() = 0;
virtual Body *makeBody() = 0;
};
//////////////
class AShape : public Shape
{
public:
SomeShape *someShape;
virtual const char *name() { return "AShape"; }
};
class ABody : public Body
{
protected:
SomeBody *someBody;
AShape *shape;
public:
ABody() { someBody = new SomeBody; }
virtual void setShape(Shape *s)
{
shape = static_cast<AShape*>(s);
printf("Setting shape: %s\n", s->name());
someBody->shape = shape->someShape;
}
};
class AFactory : public Factory
{
public:
virtual Shape *makeShape()
{ return new AShape(); }
virtual Body *makeBody()
{ return new ABody(); }
};
//////////////
class BShape : public Shape
{
public:
OtherShape *otherShape;
virtual const char *name() { return "BShape"; }
};
class BBody : public Body
{
protected:
OtherBody *otherBody;
BShape *shape;
public:
BBody() { otherBody = new OtherBody; }
virtual void setShape(Shape *s)
{
shape = static_cast<BShape*>(s);
printf("Setting shape: %s\n", s->name());
otherBody->shape = shape->otherShape;
}
};
class BFactory : public Factory
{
public:
virtual Shape *makeShape()
{ return new BShape(); }
virtual Body *makeBody()
{ return new BBody(); }
};
Thus, the role of the above is to allow the user to instantiate Body and Shape objects, which exist to manage associating underlying implementations SomeShape/SomeBody or OtherShape/OtherBody.
Then, a main function exercising both implementations could be,
int main()
{
// Of course in a real program we would return
// a particular Factory from some selection function,
// this should ideally be the only place the user is
// exposed to the implementation selection.
AFactory f1;
BFactory f2;
// Associate a shape and body in implementation 1
Shape *s1 = f1.makeShape();
Body *b1 = f1.makeBody();
b1->setShape(s1);
// Associate a shape and body in implementation 2
Shape *s2 = f2.makeShape();
Body *b2 = f2.makeBody();
b2->setShape(s2);
// This should not be possible, compiler error ideally
b2->setShape(s1);
return 0;
}
So, the parts that I am not happy about here are the static_cast<> calls in setShape(), because they build in an assumption that the correct object type has been passed in, without any compile-time type checking. Meanwhile, setShape() can accept any Shape, when in reality only a derived class should be accepted here.
However, I don't see how compile-time type checking could be possible if I want the user code to operate on the Body/Shape level and not the ABody/AShape or BBody/BShape level. However, switching the code so that ABody::setShape() accepts only an AShape* would make the whole factory pattern useless, for one thing, and would force the user code to be aware of which implementation is in use.
In addition it seems like the A/B classes are an extra level of abstraction over Some/Other, which exist only to support them at compile time, yet these are not intended to be exposed to the API, so what's the point... they serve only as a kind of impedance-matching layer, forcing both SomeShape and OtherShape into the Shape mold.
But what are my alternative choices? Some run-time type checking could be used, such as dynamic_cast<> or an enum, but I'm looking for something a little more elegant, if possible.
How would you do this in another language?
Analysis of your design issue
Your solution implements the abstract factory design pattern, with:
AFactory and BFactory are concrete factories of the abstract Factory
ABody and AShape on one hand and BBody and BShape on the other hand are concrete products of abstract products Body and Shape.
The Axxx classes form a familiy of related classes. So do the Bxxx classes.
The issue you worry about is that an the method Body::setShape() depends on an abstract shape argument, whereas the concrete implementation expects in reality a concrete shape.
As you've rightly pointed out, the downcast to the concrete Shape suggests a potential design flaw. And it will not be possible to catch the errors at compile-time, because the whole pattern is designed to be dynamic and flexible at run time, and the virtual function can't be templatized.
Alternative 1: make your current design a little bit safer
Use the dynamic_cast<> to check at runtime if the downcast is valid. Consequence:
the ugly casting is very well isolated in a single function.
the runtime check is only done when necessary, i.e. the only time you set the shape.
Alternative 2: adopt a design with strong isolation
A better design, would be to isolate the different products. So one product class would only use the abstract interface of the other classes of the same family and ignore their concrete specificity.
Consequences:
very robust design enforcing superior separation of concerns
you could factorize the Shape* member at the level of the abstract class, and perhaps even de-virtualize setShape().
but this comes at expense fo rigidity: you couldn't make use of family specific interface. This could be very embarassing, if for example the goal is that the family represents a native UI, knowing that products are highly interdependent and need to use native API (that's the typical example in the book of the Gang of 4).
Alternative 3: templatize dependent types
Opt for a template based implementation of your abstract factory. The general idea, is that you define the internal dependencies between products, using a template implementation.
So in your example Shape, AShape and BShape are unchanged as there is no dependency to other produts. But Body depends on a Shape, ad you want to have ABody depending on AShape, whereas BBody should depend on BShape.
The trick is then to use a template instead of an abstract class:
template<class Shape>
class Body
{
Shape *shape;
public:
void setShape(Shape *s) {
shape=s;
printf("Setting shape: %s\n", s->name());
}
};
Then you would define ABody by deriving it from Body<AShape>:
class ABody : public Body<AShape>
{
protected:
SomeBody *someBody;
public:
ABody() { someBody = new SomeBody; }
};
This is all very nice, but how shall this work with the abstract factory ? Well same principle: templatize instead of virtualize.
template <class Shape, class Body>
class Factory
{
public:
Shape *makeShape()
{ return new Shape(); }
Body *makeBody()
{ return new Body(); }
};
// and now the concrete factories
using BFactory = Factory<BShape, BBody>;
using AFactory = Factory<AShape, ABody>;
The consequence is that you have to know at compile time which concrete factory and concrete products you intend to use. THis can be done using C++11 auto :
AFactory f1; // as before
auto *s1 = f1.makeShape(); // type is deduced from the concrete factory
auto *b1 = f1.makeBody();
b1->setShape(s1);
With this approach you will no longuer be able to mixup products of different families. The following statement will cause an error:
b2->setShape(s1); // error: no way to convert an AShape* to a BShape*
And here an online demo

Means of copying derived class attributes without dynamic casting

I am trying to find an efficient way (using polymorphism) to copy specific attributes between two derived classes externally. I have a set of data classes that derive from a base class DataClassA. I want to operate on these data classes in a separate filter class that takes DataClassA references as input and output parameters. The filter will perform the necessary operations common to DataClassA, but I also want to propagate class-specific attributes from my input to output class. Consider:
class DataClassA
{
public:
virtual void copyAttributes( DataClassA& copyFrom );
}
class DataClassB : public DataClassA
{
public:
virtual void copyAttributes( DataClassA& copyFrom );
};
class DataFilter
{
void run( DataClassA& input, DataClassB& output )
{
//do some calculations here
...
//then copy over attributes
output.copyAttributes( input );
}
};
My problem is obviously that the copyAttributes() depends on needing to know the types of both the input and output derived classes (which need not necessarily be the same). However, the filter will only handle references to the base class DataClassA. My reflex is to simply institute a dynamic_cast, though I risk getting my hand slapped (and other possible negative consequences). If I did this, I would simply create a copyAttributes method for each derived class that called the copyAttributes of the parent class, and then use dynamic_cast to see if the copyFrom object is of the same type:
void DataClassB::copyAttributes( DataClassA& copyFrom )
{
//copy attributes from parent class
DataClassA::copyAttributes( copyFrom );
//test if the class being copied from is of type DataClassB
DataClassB* copyPtr = dynamic_cast<DataClassB*>&copyFrom;
if( copyPtr != NULL )
{
//copy DataClassB-specific attributes from copyFrom to this
...
}
}
The most similar post I could find on the problem was here Virtual functions and polymorphism. My primary questions are: 1) is my proposed use of dynamic_cast inappropriate?; and 2) if so, how might I implement this copyAttributes another way? There were references to using a visitor design pattern though I'm not sure how that would look.
This is kind of a simpler version of what the Visualization Toolkit (VTK) does in the sense that I'm using classes of filters that operate on a number of different data classes. Interestingly, they handle RTTI by including macros that include the string name of classes and parent classes that can be compared directly for correct downcasting of datatypes.
It seems you want multi-dispatch (as that I have done here: https://ideone.com/8VxALs)
That require that the visitor knows each derived types.
An other approach is to use a dynamic_cast each time.
A simple double dispatch can be done as follow:
class DataClassA
{
public:
virtual ~A() {}
virtual void copyAttributes(DataClassA& copyFrom) { copyFrom.copyAttributesToA(*this); }
virtual void copyAttributesToA(DataClassA& copyTo) { /* Implementation to copy A -> A */ }
virtual void copyAttributesToB(DataClassB& copyTo) { /* Implementation to copy A -> B */ }
};
class DataClassB : public DataClassA
{
public:
void copyAttributes(DataClassA& copyFrom) override { copyFrom.copyAttributesToB(*this); }
void copyAttributesToA(DataClassA& copyTo) override { /* Implementation to copy B -> A */ }
void copyAttributesToB(DataClassB& copyTo) override { /* Implementation to copy B -> B */ }
};