Means of copying derived class attributes without dynamic casting - c++

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 */ }
};

Related

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.

Base class of non polymorphic derived classes

I have the following class definitions:
class BaseHandle { /* Lots of things */ };
class VertexHandle : public BaseHandle {
/* Only static members and non-virtual functions, default dtor */ };
class EdgeHandle : public BaseHandle { /* Dito */ };
class FaceHandle : public BaseHandle { /* Dito */ };
All classes have no virtual functions or bases.
The derived classes only derive from BaseHandle and do not add any non-static members, nor non-default dtors.
I want to save Vertex-, Edge- and FaceHandles in the same vector:
std::vector<BaseHandle*> handles;
But it doesn't work, if I retrieve the BaseHandle object and want to dynamic_cast them to the derived object it fails, because the classes are not polymorphic (that's my explanation perhaps I'm wrong).
How could I achieve a common vector of BaseHandles? I should mention, that I can't change the class defintions because they are part of a third party library.
You need to have a virtual destructor in your parent class for it to be used polymorphically
class BaseHandle
{
public:
virtual ~BaseHandle();
...
};
That's because dynamic_cast works with the RTTI (RunTime Type Information) which is only available if your class has at least one virtual member function
And this will also prevent resource leaks, otherwise only the parent class part of your instance would be destroyed
Workaround
You can use an std::vector of std::shared_ptr, not only will you avoid memory leaks by not having to call new and delete by hand but that smart pointer also has a magic property (it stores the deleter to call on destruction based on the way it was constructed) that solves your problem:
int main()
{
std::vector<std::shared_ptr<BaseHandle>> shared_vec;
shared_vec.push_back(std::make_shared<VertexHandle>());
} // At the end of scope all destructors are called correctly
If you don't have access to c++11 you could use boost::shared_ptr
You could store
struct thing
{
enum Type { vertex, edge, face };
Type type;
union
{
VertexHandle * vh;
EdgeHandle * eh;
FaceHandle * fh;
};
};
but it's basically a mess ... are you sure you want to do this? It looks like you are storing multiple types in a single array despite the fact that there is no way to use them polymorphically, so is there actually a good reason to have only one array, and not three?
Following on from a comment by Kerrek. You could "create your own, parallel class hierarchy and add each of those types as a member". For example:
class MyBaseHandle {
public:
virtual ~MyBaseHandle(){}
virtual Box getBoundingBox() const = 0;
};
class MyEdgeHandle : public MyBaseHandle {
std::unique_ptr<EdgeHandle> handle_;
public:
MyHandle(std::unique_ptr<EdgeHandle> handle) : handle_(std::move(handle)) {}
Box getBoundingBox() const override;
};
Then you can dynamic_cast if you want to. But I would try and avoid using dynamic_cast at all. Add virtual methods in your parallel class hierarchy that do what you need. For example I've added a virtual getBoundingBox function to the base class that you can then specialize for your particular kinds of handle:
Box MyEdgeHandle::getBoundingBox() const {
// Get data from EdgeHandle
auto v1 = handle_->getVertex1();
auto v2 = handle_->getVertex2();
// create box from edge data...
return box;
}
Live demo
If all classes derived from BaseHandle only use single-inheritance from BaseHandle (plus maybe inheritance from empty classes with trivial dtor, which are subject to empty-baseclass-optimization) and don't add anything but non-virtual functions and static members, and all derived classes use the default dtor or equivalent, you can just static_cast to the target.
Though be aware that there is no way to know which of the derived classes, if any, it actually was.

Is there a way to infer the type of an object?

This may be a stupid question, I suspect I know the answer (no) because I seem to be hitting a wall here.
Given I have a collection of objects derived from certain class:
class BaseClass;
class DerivedA: public BaseClass;
class DerivedB: public BaseClass;
class DerivedC: public BaseClass;
std::vector<BaseClass> myCollection;
I want to call a method depending on the types of the specific class:
class Processor {
void doSomething(DerivedA a, DerivedB b);
void doSomething(DerivedA a, DerivedC c);
}
The problem is, if I access the individual items on the collection and try to call the 'doSomething' method in the 'Processor', it will not be able do decide which method to use (afaik). So my question is: Is there any way to fetch the items in the collection with the right derived-type?
If you are going to keep the doSomething method as it is, this is what is called multiple dispatch and is NOT currently supported by C++.
If it were a virtual member function of BaseClass then yes it would be the run of the mill C++ polymorphism on the object it is being invoked on, but it would still NOT automatically infer the type of the arguement.
To get around this you can do something like what is suggested in the earlier link
void collideWith(Thing& other) {
// dynamic_cast to a pointer type returns NULL if the cast fails
// (dynamic_cast to a reference type would throw an exception on failure)
if (Asteroid* asteroid = dynamic_cast<Asteroid*>(&other)) {
// handle Asteroid-Asteroid collision
} else if (Spaceship* spaceship = dynamic_cast<Spaceship*>(&other)) {
// handle Asteroid-Spaceship collision
} else {
// default collision handling here
}
}
Basically keep casting to various possible Derived classes until one works and call one of the methods appropriately(no special effort since the compiler knows what type you are trying to cast to).
IMPORTANT: as #WhozCraig points out, your vector needs to hold pointers to avoid Object-Slicing and render this whole question moot.
Ok, yes you should use polymorphism as the above stated. If your function needs to handle 2 objects though it gets extremely complicated.
If the derivations form a limited set and know each other you can use double-dispatch. It's not perfect but it solves this particular case.
class DerivedA;
class DerivedB;
class DerivedC;
class BaseClass
{
public:
virtual ~BaseClass();
virtual void doSomethingWithBase( BaseClass & b2 ) = 0;
virtual void doSomethingWithDerivedA( DerivedA & da ) = 0;
virtual void doSomethingWithDerivedB( DerivedB & db ) = 0;
virtual void doSomethingWithDerivedC( DerivedC & dc ) = 0;
};
class DerivedA : public BaseClass
{
public:
void doSomethingWithBase( BaseClass & b2 )
{
b2.doSomethingWithDerivedA( *this );
}
void doSomethingWithDerivedA( DerivedA & da )
{
// implement for two DerivedA objects
}
void doSomethingWithDerivedB( DerivedB & db )
{
// implement for an A and B
}
void doSomethingWithDerivedC( DerivedC & dc )
{
// implement for an A and C
}
};
// implement DerivedB to call doSomethingWithDerivedB on its parameter
// implement DerivedC to call doSomethingWithDerivedC on its parameter.
You get the idea. From where you call you don't need to know which two types you have and you never need to actually look this up. But if you ever add more implementations you have a lot of code to edit and may consider some kind of lookup table.
If you need a class to define itself you can use some kind of virtual id.
class BaseClass
{
public:
virtual int id() const = 0;
};
and then you get the classes to reveal their ids and find the handler in the table based on these ids that wil handle the two objects. The ids don't have to be ints, they can be strings which makes it easier to avoid naming clashes, and this has the advantage over the double-dispatch method of the base class not knowing its derived classes or them knowing each other, and being extensible. You also don't have to handle every pair.

C++ Variable Type Selection at Runtime

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

Polymorphism and checking if an object has a certain member method

I'm developing a GUI library with a friend and we faced the problem of how to determine whether a certain element should be clickable or not (Or movable, or etc.).
We decided to just check if a function exists for a specific object, all gui elements are stored in a vector with pointers to the base class.
So for example if I have
class Base {};
class Derived : public Base
{
void example() {}
}
vector<Base*> objects;
How would I check if a member of objects has a function named example.
If this isn't possible than what would be a different way to implement optional behaviour like clicking and alike.
You could just have a virtual IsClickable() method in your base class:
class Widget {
public:
virtual bool IsClickable(void) { return false; }
};
class ClickableWidget : public Widget
{
public:
virtual bool IsClickable(void) { return true; }
}
class SometimesClickableWidget : public Widget
{
public:
virtual bool IsClickable(void);
// More complex logic punted to .cc file.
}
vector<Base*> objects;
This way, objects default to not being clickable. A clickable object either overrides IsClickable() or subclasses ClickableWidget instead of Widget. No fancy metaprogramming needed.
EDIT: To determine if something is clickable:
if(object->IsClickable()) {
// Hey, it's clickable!
}
The best way to do this is to use mixin multiple inheritance, a.k.a. interfaces.
class HasExample // note no superclass here!
{
virtual void example() = 0;
};
class Derived : public Base, public HasExample
{
void example()
{
printf("example!\n");
}
}
vector<Base*> objects;
objects.push_back(new Derived());
Base* p = objects[0];
HasExample* he = dynamic_cast<HasExample*>(p);
if (he)
he->example();
dynamic_class<>() does a test at runtime whether a given object implements HasExample, and returns either a HasExample* or NULL. However, if you find yourself using HasExample* it's usually a sign you need to rethink your design.
Beware! When using multiple inheritance like this, then (HasExample*)ptr != ptr. Casting a pointer to one of its parents might cause the value of the pointer to change. This is perfectly normal, and inside the method this will be what you expect, but it can cause problems if you're not aware of it.
Edit: Added example of dynamic_cast<>(), because the syntax is weird.
If you're willing to use RTTI . . .
Instead of checking class names, you should create Clickable, Movable, etc classes. Then you can use a dynamic_cast to see if the various elements implement the interface that you are interested in.
IBM has a brief example program illustrating dynamic_cast here.
I would create an interface, make the method(s) part of the interface, and then implement that Interface on any class that should have the functionality.
That would make the most sense when trying to determine if an Object implements some set of functionality (rather than checking for the method name):
class IMoveable
{
public:
virtual ~IMoveable() {}
virtual void Move() = 0;
};
class Base {};
class Derived : public Base, public IMoveable
{
public:
virtual void Move()
{
// Implementation
}
}
Now you're no longer checking for method names, but casting to the IMoveable type and calling Move().
I'm not sure it is easy or good to do this by reflection. I think a better way would be to have an interface (somethign like GUIElement) that has a isClickable function. Make your elements implement the interface, and then the ones that are clickable will return true in their implementation of the function. All others will of course return false. When you want to know if something's clickable, just call it's isClickable function. This way you can at runtime change elements from being clickable to non-clickable - if that makes sense in your context.