Specifying void* parameter in derived function - c++

I would like to do something that probably is not possible in Cpp, but I could not find a post about this specifically.
I want to have a derived class specify the type of a void* parameter on a virtual function.
I have a base class called interface with a send function.
// pure virtual
class Interface{
virtual bool Send(const void*)=0;
};
struct Packet{
DataType data;
};
class SpecificInterface{
bool Send(const DataType*);
}
Is there a way to make something like this work? The intent is that SpecificInterface::Send implements Interface::Send. Allowing SpecificInterface to not be a pure virtual while restricting the void* to a specific packet type.
Otherwise I know I could take a void* parameter and static_cast it into the Packet* type; however, I do not want others to send a pointer type that cannot be cast to Packet*.
Let me know if this is not clear

When you want to override a virtual function, the number of arguments and the types of the arguments must exactly match the declaration in the base class. You'll have to use:
class SpecificInterface{
bool Send(const void* ptr)
{
cont DataType* dataTypePtr = static_cast<const DataType*>(ptr);
// Now use dataTypePtr any way you wish
}
};
Please note that use of such code is dangerous. If ptr does not really point to a DataType object, your program will have undefined behavior.

#RSahu is correct, of course. You could still use a virtual method to do about the same thing:
class Interface {
virtual bool send(const void*) = 0;
};
struct Packet {
DataType data;
};
class SpecificInterface {
bool send(cont void*) override {
send(static_cast<DataType*>(data));
}
bool send(cont DataType*); // code which actually does something
};
However - I recommend against your whole approach to begin with - it is massively unsafe, since the validity of the type is never checked! It's a source of many potential bugs. More often than not, you can avoid doing this. Here are a few things you might try instead:
std::any - a class which doesn't offer you compile-time type safety, but at least checks types at run-time. You would have a send(const std::any& data) virtual function, and inside it you would call std::any_cast<DataType>(data) to get a DataType or std::any_cast<DataType>(&data) to get a DataType *.
Probably even better - the Curiously-recurring template pattern (CRTP):
template <typename T>
class Interface {
virtual bool send(T*) = 0;
};
class SpecificInterface : Interface<DataType> {
bool send(cont DataType*) override;
}

Related

C++ templates: Calling member function of derived template class from base class

I'm currently working on a spreadsheet application, but I'm having problems with templates.
Every cell of the template can contain a variable which can be any of the standard types.
The relevant class is SpreadSheet, whose most important member variable is SheetCells, which has
type vector< vector<CellBase*> >. The CellBase class is an abstract class from which CellField<T> is
derived, the latter being the template class storing one piece of data corresponding to exactly one cell
of the spreadsheet.
I have another class, SheetView, that eventually has to display the spreadsheet. (To keep things simple,
assume that this class has full access to every other class.) This class doesn't really care what type
the value of every cell is, as it will convert everything to a string anyway. However, my problem is writing
a member function of SpreadSheet that returns a string, containing the data. My first idea was to write a function
std::string SpreadSheet::getDataFromSheet(int row, int column) that SheetView would call, and then that function would do
return (std::to_string(SheetCells[row][column] -> getData())), where getData() is a member function of CellField<T>, returing
something of type T.
However, since SheetCells contains pointers to CellBase classes, I must make getData a member of CellBase,
but this is not possible, since I want getData() to return a variable of type T, the same type as the template class
CellField.
The relevant parts of all class definitions are found below.
//SpreadSheet
class Spreadsheet
{
private:
int _height, _width;
public:
Spreadsheet(int newHeight, int newWidth);
~Spreadsheet();
string getData(int row, int column);
vector< vector<CellBase*> > SheetCells;
};
//CellBase
class CellBase
{
public:
CellBase();
virtual ~CellBase();
};
//CellField
template<typename T>
class CellField : public CellBase
{
public:
CellField(T newValue);
virtual ~CellField();
T getData();
T _value;
};
So in short, I want to be able to call getData() from SpreadSheet, but the member variables of the latter
only contain pointers to CellBase classes (but the classes are actually of type CellField<T>).
I've looked at similar questions, but none of them seem to address the issue of a base class member function calling a template class<T> function where the latter and the former need to return a variable of type T. Maybe void* pointers will work?
As C++ is a strongly typed language, you can't call them directly this way, since the compiler would not be able to figure out what the return value of the function is.
What you need to do is, map it all to a common interface. The question you should ask is: what are the information i realy need from the CelField? Maybe all you need is the string-representation of the value, then you could do something like this:
class CellBase
{
virtual std::string getData()=0;
};
template<typename T>
class CellField : public CellBase
{
std::string getData(){//some implementation}
};
Another option is the use of boost::any, which is able to contain any type you like. This is especially useful if you don't need to actually interfere with the returned value other than passing it to some other function taking "an arbitrary parameter". However in order to really use the value, you still have to cast it to a specific type using boost::any_cast<T>() and therefore need to know which type you expect and do a proper error-handling if the type is wrong.
A possible solution is employ a visitor, along these line:
Class Visitor
{
virtual ~Visitor(void) {}
virtual void visit(CellBase<int> *cell) {}
virtual void visit(CellBase<float> *cell) {}
...
} ;
class CellBase
{
public:
CellBase();
virtual ~CellBase();
virtual void accept(Visitor *v) { v->visit(this) ;}
};
class DataGetterVisitor : public Visitor
{
public:
virtual void visit(CellBase<int> *cell)
{
// here I know how to make the transformation
}
virtual void visit(CellBase<float> *cell) {}
string text ;
} ;
string dataGetter(CellBase *cell)
{
DataGetterVisitor visitor ;
cell->accept(visitor);
return visitor.text ;
}

Pure virtual member function has to process a templated buffer - how to?

I have a base class PixelBuffer which has a virtual function to copy the content of the PixelBuffer to a templated Buffer object. PixelBuffer may have several inherited implementations like OpenGLPixelBuffer/DXPixelBuffer which implement a pure virtual copyToBuffer function (pseudo code):
class PixelBuffer
{
public:
virtual void copyToBuffer(? buffer) = 0; // how to declare this?
};
The PixelBuffer has an internal data type which can be of different base types (int, uint, float, char, ...).
More important is the data type of the Buffer I want to copy to.
The buffer class (may) look something like this:
template <typename T>
class Buffer
{
public:
Buffer() : m_data(), m_size(0) {}
Buffer(std::size_t buffsize) : m_data(new std::vector<T>(buffsize)), m_size(buffsize) { }
std::shared_ptr<std::vector<T>> data() { return m_data; }
std::size_t size() { return m_size; }
void allocate(std::size_t buffsize) {
m_data = std::shared_ptr<std::vector<T>>(new std::vector<T>(buffsize));
m_size = buffsize;
}
private:
std::shared_ptr<std::vector<T>> m_data;
std::size_t m_size;
};
typedef Buffer<float> FloatBuffer;
typedef Buffer<char> ByteBuffer;
I am searching for a way to do something like this:
PixelBuffer* pbObj = ...;
FloatBuffer dest;
pbObj->copyToBuffer(dest); // does allocation and copying
Since it is not possible to template the PixelBuffer member functions, I don't know how to solve this right now. I know I need many implementations for copying the different buffer data types, but I don't know where to implement them and how this could be done without adding a bunch of functions to PixelBuffer (for each type of Buffer).
Maybe this could be done using the visitor pattern or with policies?
Edit:
To answer a comment: Yes, it should be possible to copy from any PixelBuffer type to any Buffer type. However, only those types for which the copying is implemented should be supported!
I'm still not exactly certain what you require, but if you want to be able to pass various specializations of Buffer then you need unique methods rather than a single virtual method:
virtual void copyToBuffer(Buffer<char> & buffer) = 0;
virtual void copyToBuffer(Buffer<float> & buffer) = 0;
You would probably then override these in the subclass, and probably throw an exception for any cases where the copy operation wasn't supported. Your question suggests you don't want to do this, although I feel it's the best solution if you have a limited set of buffer specialisations that you need to deal with.
If you want only a single method, you need to abstract out functionality common to each specialization of Buffer into a class which each specialisation extends, and take a reference to that instead:
virtual void copyToBuffer(BufferBase & buffer) = 0;
template <typename T>
class Buffer : public BufferBase
{
// ...
The implementations of the copyToBuffer method are then going to be limited to the functionality provided in BufferBase, in this case, so I doubt this solution would prove workable for you.
On the other hand, if you want to only have a single method which accepts a specific type of buffer and the type differs from subclass to subclass, then the method shouldn't be declared in the base class at all - you should simply declare the method with the appropriate argument type in each of the subclasses. Probably the cleanest solution in this case is to parameterize the PixelBuffer class according to the element type of the buffer it supports:
template <typename E>
class PixelBuffer : public PixelBufferBase
{
public:
virtual void copyToBuffer(Buffer<E> &) = 0;
}
Your example then becomes:
PixelBufferBase* pbObj = ...;
PixelBuffer<float> *fpbObj = dynamic_cast<PixelBuffer<float> *>(pbObj);
FloatBuffer dest;
fpbObj->copyToBuffer(dest); // does allocation and copying
(You can probably use a static_cast instead for performance, at the cost of certain safety).
You don't actually need a policy-based design; you would get a benefit from policies only if the copyToBuffer implementation could be shared between different PixelBuffer subclasses (which sounds unlikely) and in any case you'd still need to parameterise the PixelBuffer type.
I also don't believe the visitor patterns helps you with this problem - it requires multiple functions to deal with multiple PixelBuffer/Buffer types; you might move the overloaded method around to a different class, but you don't avoid the need for it.
I have met the same problem. I used a void * as the type and convert the pointer to the correct Buffer in the implements.
It's not beautiful, but It works and has no penalty on the performance.
But if your PixelBuffer will copy to more than one type of Buffer with only one copyToBuffer function. You will have to add another argument to distinct different type of buffers:
enum class BufferType
{
INT,
CHAR,
FLOAT,
//...
};
class PixelBuffer
{
public:
//....
virtual void copyToBuffer(void* buffer, BufferType buffertype) = 0;
}
virtual void DXPixelBuffer::copyToBuffer(void* buffer, BufferType buffertype)
{
switch(buffertype){
case BufferType::FLOAT:
Buffer<float>* pbuffer = static_cast<Buffer<float>*>(buffer);
//...
break;
//...
And you can use a traits class and a wrap function to make the call to copyToBuffer more safe.
template<typename T> struct BufferTraits;
template<> struct BufferTraits<float>{
static constexpr BufferType Type = BufferType::FLOAT;
};
template<> struct BufferTraits<char> {
static constexpr BufferType Type = BufferType::CHAR;
};
class PixelBuffer
{
public:
template<typename T> void PixelBuffer::copyToBuffer(Buffer<T>& buffer){this->copyToBuffer(reinterpret_cast<void *>(&buffer), BufferTraits<T>::Type);}
//...
}
Your example will remain the same:)
PixelBuffer* pbObj = ...;
FloatBuffer dest;
pbObj->copyToBuffer(dest);

Why does C++ prefer this template method to a method overload?

Assuming I had two classes, the first one for writing primitive types (bool, int, float, etc.) and the second one extending the first to also write complex types:
struct Writer {
virtual void Write(int value) = 0;
};
struct ComplexWriter : public Writer {
template <typename TValue> void Write(const TValue &value) {
boost::any any(value);
Write(any);
}
//virtual void Write(int value) = 0; // see question below
virtual void Write(const boost::any &any) = 0;
};
The idea is that if someone calls myWriter.Write(someIntValue);, the int overload will receive priority over the templated method.
Instead, my compiler (Visual C++ 11.0 RC) always picks the template method. The following code snippet, for example, will print Wrote any to the console:
struct ComplexWriterImpl : public ComplexWriter {
virtual void Write(int value) { std::cout << "Wrote an int"; }
virtual void Write(const boost::any &any) { std::cout << "Wrote any"; }
};
void TestWriter(ComplexWriter &writer) {
int x = 0;
writer.Write(x);
}
int main() {
ComplexWriterImpl writer;
TestWriter(writer);
}
The behavior suddenly changes when I declare the Write(int) method in the ComplexWriter class as well (see commented out line in the first snippet). It then prints Wrote an int to the console.
Is this how my compiler ought to behave? Does the C++ standard explicitly say that only overloads defined in the same class (and not a base class) shall be prioritized over a templated method?
The problem is that at the point you're calling writer.Write(x) the compiler sees a ComplexWriter not a ComplexWriterImpl, so it is only aware of the functions defined in ComplexWriter - the template function and the boost::any function.
ComplexWriter does not contain any virtual functions that accept an int, so it has no way to call through to the int overload defined in ComplexWriterImpl
When you add in the virtual overload to the ComplexWriter class, then the compiler becomes aware that there is an integer overload in the ComplexWriter class and therefore calls through to it's implementation in ComplexWriterImpl
EDIT: Now that you've edited in the inheritance between ComplexWriter & Writer, I've got a more complete explanation for you:
When you create a subclass and define a function in it then all of the functions of that name in the base class will be hidden, regardless of their argument types.
You can get around this with the using keyword I believe:
struct ComplexWriter : public Writer {
template <typename TValue> void Write(const TValue &value) {
boost::any any(value);
Write(any);
}
using Writer::Write;
virtual void Write(const boost::any &any) = 0;
};
For more details see this FAQ entry: http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.9
EDIT 2: Just to confirm that this does indeed solve your problem: http://ideone.com/LRb5a
When you access the object via the ComplexWriter "interface", the compiler will try to resolve the function call to Write(int) using the definitions in that class. If it does not able to do so, it will consider base classes.
In this case, you have two candidates: Write(any) and the templated version. Since there is no explicit Write(int) available at this point, it will have to choose between these two options. Write(any) requires an implicit conversion, while the templated version does not, so the templated version is called (which in turn calls Write(any)).
To make the Write(int) from Writer available, import the Writer::Write functions:
class ComplexWriter : public Writer
{
using Writer::Write;
// rest is as before
};

What is an appropriate interface for dealing with meta-aspects of classes?

I'm looking for some advice of what would be an appropriate interface for dealing with aspects about classes (that deal with classes), but which are not part of the actual class they are dealing with (meta-aspects). This needs some explanation...
In my specific example I need to implement a custom RTTI system that is a bit more complex than the one offered by C++ (I won't go into why I need that). My base object is FooBase and each child class of this base is associated a FooTypeInfo object.
// Given a base pointer that holds a derived type,
// I need to be able to find the actual type of the
// derived object I'm holding.
FooBase* base = new FooDerived;
// The obvious approach is to use virtual functions...
const FooTypeInfo& info = base->typeinfo();
Using virtual functions to deal with the run-time type of the object doesn't feel right to me. I tend to think of the run-time type of an object as something that goes beyond the scope of the class, and as such it should not be part of its explicit interface. The following interface makes me feel a lot more comfortable...
FooBase* base = new FooDerived;
const FooTypeInfo& info = foo::typeinfo(base);
However, even though the interface is not part of the class, the implementation would still have to use virtual functions, in order for this to work:
class FooBase
{
protected:
virtual const FooTypeInfo& typeinfo() const = 0;
friend const FooTypeInfo& ::foo::typeinfo(const FooBase*);
};
namespace foo
{
const FooTypeInfo& typeinfo(const FooBase* ptr) {
return ptr->typeinfo();
}
}
Do you think I should use this second interface (that feels more appropriate to me) and deal with the slightly more complex implementation, or shoud I just go with the first interface?
#Seth Carnegie
This is a difficult problem if you don't even want derived classes to know about being part of the RTTI ... because you can't really do anything in the FooBase constructor that depends on the runtime type of the class being instantiated (for the same reason you can't call virtual methods in a ctor or dtor).
FooBase is the common base of the hierarchy. I also have a separate CppFoo<> class template that reduces the amount of boilerplate and makes the definition of types easier. There's another PythonFoo class that work with Python derived objects.
template<typename FooClass>
class CppFoo : public FooBase
{
private:
const FooTypeInfo& typeinfo() const {
return ::foo::typeinfo<FooClass>();
}
};
class SpecificFoo : public CppFoo<SpecificFoo>
{
// The class can now be implemented agnostic of the
// RTTI system that works behind the scenes.
};
A few more details about how the system works can be found here:
► https://stackoverflow.com/a/8979111/627005
You can tie dynamic type with static type via typeid keyword and use returned std::type_info objects as means of identification. Furthermore, if you apply typeid on a separate class created specially for the purpose, it will be totally non-intrusive for the classes you are interesed in, althought their names still have to be known in advance. It is important that typeid is applied on a type which supports dynamic polymorphism - it has to have some virtual function.
Here is example:
#include <typeinfo>
#include <cstdio>
class Base;
class Derived;
template <typename T> class sensor { virtual ~sensor(); };
extern const std::type_info& base = typeid(sensor<Base>);
extern const std::type_info& derived = typeid(sensor<Derived>);
template <const std::type_info* Type> struct type
{
static const char* name;
static void stuff();
};
template <const std::type_info* Type> const char* type<Type>::name = Type->name();
template<> void type<&base>::stuff()
{
std::puts("I know about Base");
}
template<> void type<&derived>::stuff()
{
std::puts("I know about Derived");
}
int main()
{
std::puts(type<&base>::name);
type<&base>::stuff();
std::puts(type<&derived>::name);
type<&derived>::stuff();
}
Needless to say, since std::type_info are proper objects and they are unique and ordered, you can manage them in a collection and thus erase type queried from the interface:
template <typename T> struct sensor {virtual ~sensor() {}};
struct type
{
const std::type_info& info;
template <typename T>
explicit type(sensor<T> t) : info(typeid(t))
{};
};
bool operator<(const type& lh, const type& rh)
{
return lh.info.before(rh.info);
}
int main()
{
std::set<type> t;
t.insert(type(sensor<Base>()));
t.insert(type(sensor<Derived>()));
for (std::set<type>::iterator i = t.begin(); i != t.end(); ++i)
std::puts(i->info.name());
}
Of course you can mix and match both, as you see fit.
Two limitations:
there is no actual introspection here . You can add it to template struct sensor via clever metaprogramming, it's very wide subject (and mind bending, sometimes).
names of all types you want to support have to be known in advance.
One possible variation is adding RTTI "framework hook" such as static const sensor<Myclass> rtti_MyClass; to implementation files where class names are already known and let the constructor do the work. They would also have to be complete types at this point to enable introspection in sensor.

C++ Functor Callback Setup

Im following Lars Haendel's Functor tutorial on newty.de to setup a callback system. I am a bit confused however and I am hoping someone can assist me.
Here is my Functor template
#include <igameevents.h>
// Abstract Base Class (Functor)
class TBaseCallback
{
public:
// two possible functions to call member function. virtual cause derived
// classes will use a pointer to an object and a pointer to a member function
// to make the function call
virtual void operator()(IGameEvent *pEvent){}; // call using operator
virtual void Call(IGameEvent *pEvent) {}; // call using function
};
// Derived Template Class
template <class TClass> class TEventCallback : public TBaseCallback
{
private:
void (TClass::*funcPtr)(IGameEvent*); // pointer to member function
TClass* thisPtr; // pointer to object
public:
// constructor - takes pointer to an object and pointer to a member and stores them in two private variables
TEventCallback(TClass* _thisPtr, void(TClass::*_funcPtr)(const char*))
{ thisPtr = _thisPtr; funcPtr=_funcPtr; };
// override operator "()"
virtual void operator()(IGameEvent *pEvent)
{ (*thisPtr.*funcPtr)(pEvent); }; // execute member function
// override function "Call"
virtual void Call(IGameEvent *pEvent)
{ (*thisPtr.*funcPtr)(pEvent); }; // execute member function
};
What I want to do is basically allow other .dlls to use my HookGameEvent() function, and when a Game Event is called, I can run through a vector||list of my hooks, check if the event name matches, then execute the callbacks as needed. What is confusing me though is how I can store the callback in my HookEvent struct which looks like this.
std::vector<EventHook*> m_EventHooks;
struct EventHook
{
char *name;
EventHookMode mode;
//TEventCallback<IGameEvent*> pEventCallback;
};
I have it commented out for now, but im sure its obvious what im confused on and where I am screwing up. If anyone can provide any assistance it would be much appreciated.
Most people don't understand inheritance. Generally, derived classes are implementation details. The only time you utter their names are to construct them. Furthermore, virtual functions in a base should be private and pure, and should be completely inaccessible in derived classes, it's a design bug in C++ that this isn't enforced.
struct TBaseCallback
void operator()(IGameEvent *pEvent) { _Call(pEvent); };
void Exec(IGameEvent *pEvent) { _Call(PEvent); }
private:
virtual void _Call(IGameEvent *pEvent)=0;
};
struct EventHook
{
char *name;
EventHookMode mode;
TBaseCallback *p;
void dispatch(char *msg; IGameEvent *e) const {
if(strcmp(msg,name)==0) p->Exec(e);
}
};
With this design, it doesn't make any difference what is in classes derived from TBaseCallback, and nor should it. Only the abstraction should ever be publically visible. In normal code this is hard to enforce .. when you're using DLLs to get the derived classes it is absolutely mandatory because the set of derived classes is open/arbitrary/infinite/indeterminate (take your pick).
BTW: when you push this to more complex abstractions you will soon discover why Object Orientation is a broken concept. With DLL loaded derived classes, you simply cannot cheat with dynamic_cast switches (because they're closed/specific/finite/determinate).
The class that is going to do the callbacks should hold a list of Functor objects to be called. These would be your
std::vector<EventHook*> m_EventHooks;
Now the EventHook should have a virtual function:
struct EventHook
{
...
virtual void notifyMe();
}
Then everyone that is interested in getting notified will create his own implementation of the hook:
struct MyEventHook : public EventHook
{
virtual void notifyMe() { ... whatever I want to do in that case ... }
}
Through the wonders of polymorphism, when you then iterate over all elements of your m_EventHooks container and call notifyMe() for those, the correct class' version will be called.
The problem I see (and there could very well be others) is that in pEventCallback's type, the template parameter should be a class type but is actually a pointer type. One fix (without limiting what types the callback wraps) is to use the base type:
struct EventHook
{
char *name;
EventHookMode mode;
TBaseCallback* pCallback;
};
If there's more to TEventCallback's API, and it needs to be accessible through an EventHook, you should move the code in TEventCallback that deals with an object and its method into a separate subclass.
// Example EventCallback that takes other args
class EventCallback : public TBaseCallback {
public:
EventCallback();
EventCallback(const EventArgs& evtArgs);
// EventCallback specific methods ...
virtual EventArgs& args();
virtual const EventArgs& args() const;
}
/* TReturn allows for calling methods with a non-void return. Return value is ignored.
*/
template <class TClass, typename TReturn = void>
class TMethodCallback : public EventCallback
{
private:
typedef TReturn (TClass::*TMeth)(IGameEvent*);
TMeth funcPtr; // pointer to member function
TClass* thisPtr; // pointer to object
public:
// constructor - takes pointer to an object and pointer to a member and stores them in two private variables
TMethodCallback(TClass* _thisPtr, TMeth _funcPtr)
{ thisPtr = _thisPtr; funcPtr=_funcPtr; };
// override operator "()"
virtual void operator()(IGameEvent *pEvent)
{ (*thisPtr.*funcPtr)(pEvent); }; // execute member function
// override function "Call"
virtual void Call(IGameEvent *pEvent)
{ (*thisPtr.*funcPtr)(pEvent); }; // execute member function
};
Off-Topic
You might as well make the default implementation of TBaseCallback::Call call TBaseCallback::operator().
void TBaseCallback::Call(IGameEvent *pEvent) { this->operator()(pEvent); };
I think you will be getting a complicated compiler error because you are using T* instead of T in your template instantiation.
Try this:
struct EventHook
{
char *name;
EventHookMode mode;
TEventCallback<IGameEvent> pEventCallback;
};
should compile, if that what you want.