Workaround for virtual static function functionality - c++

Let's say I have a class:
class StateVector {
protected:
float* _v;
public:
StateVector():_v(new float[size()]) {}
virtual ~StateVector() { delete [] _v; }
virtual size_t size() = 0;
// ...
};
class PositionState : public StateVector {
public:
size_t size() { return 3; }
float* x() { return _v; }
};
class MovingState : public PositionState {
public:
size_t size() { return PositionState::size() + 3; }
float* v() { return _v + PositionState::size(); }
};
The intent here is to allow derived classes to specify the size of the state vector by overriding size(). (This information needs to be available to the constructor of StateVector, the base class which owns the underlying array).
However, this is less than ideal for a few reasons:
First, in this implementation, size() must/will be the same for all instances of a class. But in this factoring, there is nothing that prevents different instances of the same class from having different opinions about size().
Second, other classes need to generate an instance in order to query the appropriate size:
template <typename State>
class StateTransition {
Matrix<float> _m;
// constructor for Matrix takes #rows, #cols
StateTransition():_m(State().size(), State().size()) {}
// ...
};
This is silly, because for all States, size() will be the same. In this case, size() might be quite large, and in the constructor for StateTransition will (by constructing two States) allocate two arrays of that size and then immediately throw them away!
Finally, it is expected that each derived class will carry a superset of its base's state, so size() should never be smaller for base classes than for derived classes– but since we can't traverse the inheritance tree, I don't know of a way to enforce this programmatically. This is a secondary concern, but it would be nice if there were a clean way to handle it.
It would make the most sense to be able to write:
class StateVector {
float* _v;
StateVector:_v(new float[size()]) {}
virtual static size_t size() = 0;
};
class PositionState {
static size_t size() { return 3; }
// ...
};
// etc.
template <typename State>
class StateTransition {
Matrix<float> _m;
StateTransition():_m(State::size(), State::size()) {}
};
However, other answers here (and elsewhere) indicate that virtual static functions are not allowed (and some of them unhelpfully suggest that it "doesn't make sense" or "wouldn't be useful").
What is an idiomatic way to solve this problem, that makes it easy as possible for derived classes to follow the rules?

Although I'm not sure why you insist on using virtual functions and not numeric arguments passed to the constructor of the base class, there is a solution that involves virtual functions, but of a different class:
class StateVectorInfo {
public:
virtual int size() const = 0;
protected:
~StateVectorInfo () = default;
};
class PositionStateInfo : public StateVectorInfo {
PositionStateInfo (); // don't create other instances
public:
virtual int size() const;
static PositionStateInfo info; // single instance
};
PositionStateInfo PositionStateInfo::info; // a definition is needed
class StateVector {
float* _v;
public:
StateVector (const StateVectorInfo& info):
_v(new float[info.size()]) {
}
};

Related

Implementing a ReaderWriter class based upon separate stateful Reader and Writer bases

Suppose I have two classes...
We can call the first FooReader and it looks something like this:
class FooReader {
public:
FooReader(const Foo* const foo)
: m_foo(foo) {
}
FooData readFooDataAndAdvance() {
// the point here is that the algorithm is stateful
// and relies upon the m_offset member
return m_foo[m_offset++];
}
private:
const Foo* const m_foo;
size_t m_offset = 0; // used in readFooDataAndAdvance
};
We can call the second FooWriter and it looks something like this:
class FooWriter {
public:
FooWriter(Foo* const foo)
: m_foo(foo) {
}
void writeFooDataAndAdvance(const FooData& foodata) {
// the point here is that the algorithm is stateful
// and relies upon the m_offset member
m_foo[m_offset++] = foodata;
}
private:
Foo* const m_foo;
size_t m_offset = 0;
};
These both work wonderfully and do their job as intended. Now suppose I want to create a FooReaderWriter class. Note that the
I naturally want to say that this new class "is a" FooReader and "is a" FooWriter; the interface is simply the amalgamation of the two classes and the semantics remain the same. I don't want to reimplement perfectly good member functions.
One could model this relationship using inheritance like so:
class FooReaderWriter : public FooReader, public FooWriter { };
This is nice because I get the shared interface, I get the implementation and I nicely model the relationship between the classes. However there are problems:
The Foo* member is duplicated in the base classes. This is a waste of memory.
The m_offset member is separate for each base type, but they need to share it (i.e. calling either readFooDataAndAdvance and writeFooDataAndAdvance should advance the same m_offset member).
I can't use the PIMPL pattern and store m_foo and m_offset in there, because I'd lose the const-ness of the m_foo pointer in the base FooReader class.
Is there anything else I can do to resolve these issues, without reimplementing the functionality contained within those classes?
This seems ready made for the mixin pattern. We have our most base class which just declares the members:
template <class T>
class members {
public:
members(T* f) : m_foo(f) { }
protected:
T* const m_foo;
size_t m_offset = 0;
};
and then we write some wrappers around it to add reading:
template <class T>
struct reader : T {
using T::T;
Foo readAndAdvance() {
return this->m_foo[this->m_offset++];
};
};
and writing:
template <class T>
struct writer : T {
using T::T;
void writeAndAdvance(Foo const& f) {
this->m_foo[this->m_offset++] = f;
}
};
and then you just use those as appropriate:
using FooReader = reader<members<Foo const>>;
using FooWriter = writer<members<Foo>>;
using FooReaderWriter = writer<reader<members<Foo>>>;
CRTP.
template<class Storage>
class FooReaderImpl {
public:
FooData readFooDataAndAdvance() {
// the point here is that the algorithm is stateful
// and relies upon the m_offset member
return get_storage()->m_foo[get_storage()->m_offset++];
}
private:
Storage const* get_storage() const { return static_cast<Storage const*>(this); }
Storage * get_storage() { return static_cast<Storage*>(this); }
};
template<class Storage>
class FooWriterImpl {
public:
void writeFooDataAndAdvance(const FooData& foodata) {
// the point here is that the algorithm is stateful
// and relies upon the m_offset member
get_storage()->m_foo[get_storage()->m_offset++] = foodata;
}
private:
Storage const* get_storage() const { return static_cast<Storage const*>(this); }
Storage * get_storage() { return static_cast<Storage*>(this); }
};
template<class T>
struct storage_with_offset {
T* m_foo = nullptr;
std::size_t m_offset = 0;
};
struct FooReader:
FooReaderImpl<FooReader>,
storage_with_offset<const Foo>
{
FooReader(Foo const* p):
storage_with_offset<const Foo>{p}
{}
};
struct FooWriter:
FooWriterImpl<FooWriter>,
storage_with_offset<Foo>
{
FooWriter(Foo* p):
storage_with_offset<Foo>{p}
{}
};
struct FooReaderWriter:
FooWriterImpl<FooReaderWriter>,
FooReaderImpl<FooReaderWriter>,
storage_with_offset<Foo>
{
FooReaderWriter(Foo const* p):
storage_with_offset<Foo>{p}
{}
};
If you need an abstract interface for runtime polymorphism, inherit FooReaderImpl and FooWriterImpl from them.
Now, FooReaderWriter obeys the ducktype contract of FooReader and FooWriter. So if you use type erasure instead of inheritance, it will qualify for either (at point of use).
I'd be tempted to change them to
using FooReader = std::function<FooData()>;
using FooWriter = std::function<void(FooData const&)>;
and then implement a multi-signature std::function for FooReaderWriter. But I'm strange and a bit unhinged that way.

C++ Specify variable type a posteriori in derived class

I have two databases of different types of objects with some common functions so I thought to create a parent class with the definitions of the common functions. The idea is that these functions have to do the same operations even though the type of objects is different. A silly example:
class Database
{
public:
// retrieve size of the dataset
int Size() const {return list_.size();}
};
class DerivedDatabase : public Database
{
private:
// list of dataset objects
std::vector<Object1> list_;
};
class DerivedDatabase2: public Database
{
private:
// list of dataset objects
std::vector<Object2> list_;
};
One solution is to define the function as virtual Size() const =0 and then have the derived classes override it. However the idea is to have it already implemented for when I have to create new types of DataBases. Is there a way to specify a posteriori the variable type in the derived classes? The two derived databases are inherently different and they behave completely differently except for some functions, which are common. Thus they have to be separate objects
You may use CRTP to factorize code, something like:
template <typename T> class Database
{
// T should have a container named list_
public:
// retrieve size of the dataset
int Size() const { return AsDerived().list_.size(); }
private:
const T& AsDerived() const { return static_cast<const T&>(*this); }
T& AsDerived() { return static_cast<T&>(*this); }
};
And then
class DerivedDatabase : public Database<DerivedDatabase>
{
friend class Database<DerivedDatabase>;
private:
std::vector<Object1> list_;
};
class DerivedDatabase2 : public Database<DerivedDatabase2>
{
friend class Database<DerivedDatabase2>;
private:
std::vector<Object2> list_;
};
Note that DerivedDatabase and DerivedDatabase2 doesn't share a common base type here
Live example
Sure, that what templates are for:
class Database {
virtual int size() = 0;
public:
// retrieve size of the dataset
int Size() const {return size();}
}
template<typename T>
class DerivedDatabase: public Database {
std::vector<T> list_;
int size() const {return list_.size();}
}

How to make a member function in an inheritance hierarchy return always the same value?

I have an inheritance hierarchy and I want to make each class in this hierarchy have a set of attributes which are particular for that class and which do not change during the run of the program. For example:
class Base
{
public:
const std::string getName() const;
bool getAttribute1() const;
int getAttribute2() const;
};
Now I want these functions to return the same result all the time. Furthermore, when another class inherits Base this class should have its own set of attributes and any instance of this derived class should have the same attributes. Also the name should be unique for each class.
I want to know a way to make this as transparent and elegant as possible. Sofar I have considered 2 ideas that I can use:
Make some lock system.
That is provide setters for these attributes, but make them throw a runtime exception when they are called more than once.
Make the getters pure virtual.
In this case, the result of the functions would not be stored inside the object itself. This would make it vaguely clear that the result depends on the dynamic type.
Both ideas sound incredibly lousy, so I need your help.
I am new to C++, but I know there are a lot of idioms and patterns to solve general problems like this one. Do you know any?
I have an inheritance hierarchy and I want to make each class in this hierarchy have a set of attributes which are particular for that class and which do not change during the run of the program
Well, then just provide the corresponding values as arguments to a class constructor, and do not expose any setter method on the public interface. This will make sure the values remain constant throughout the life-time of the object.
To protect against possible errors that would alter the value of those data members from member functions of your class (which of course can access the private data), make those data members const. Notice, that this will force you to initialize those members in the constructor's initializer list.
class Base
{
public:
// Forwarding constructor (requires C++11)
Base() : Base("base", true, 42) { }
const std::string getName() const { return _s; }
bool getAttribute1() const { return _a1; }
int getAttribute2() const { return _a2; }
protected:
// Constructor that can be called by derived classes
Base(std::string s, bool a1, int a2)
: _s(s), _a1(a1), _a2(a2) { }
private:
const std::string _s;
const bool _a1;
const bool _a2;
};
Derived classes would then just construct the base subobject with the appropriate arguments:
class Derived : public Base
{
public:
// Provide the values for the constant data members to the base constructor
Derived() : Base("derived", false, 1729) { }
};
This way you would not incur in the overhead of a virtual function call, and you won't have to rewrite similar virtual functions for each of these members in derived classes.
Make them virtual and hard-code the result which the functions should return:
class Base
{
public:
virtual const std::string getName() const { return "BaseName"; }
virtual bool getAttribute1() const { return whatEverAttributeValueYouWant; }
virtual int getAttribute2() const { return attributeValueHere; }
};
class Derived : public Base {
public:
virtual const std::string getName() const { return "DerivedName"; }
virtual bool getAttribute1() const { return whatEverOtherAttributeValueYouWant; }
virtual int getAttribute2() const { return otherAttributeValueHere; }
};
If you want to describe classes rather than objects, use (kind-of) traits:
template<class T> struct AttributeValues;
template<> struct AttributeValues<Base> {
static const std::string name () { return "BaseName"; }
};
template<> struct AttributeValues<Derived> {
static const std::string name () { return "DerivedName"; }
};
//...
auto nameBase = AttributeValues<Base>::name ();
auto nameDerived = AttributeValues<Derived>::name ();

Is it possible to store polymorphic class in shared memory?

Suppose I have class Base and Derived : public Base.
I have constructed a shared memory segment using boost::interprocess library. Is it possible to have code similar to this:
Base* b = new Derived();
write(b); //one app writes
Base* b2 = read(b); //second app reads
//b equals b2 (bitwise, not the ptr location)
The problems I see here is for instance that the required space for a derived class of Base is unknown (so how much shmem to allocate?)
Q: how to pass objects via pointers between applications?
Just read its documentation
In particular:
Virtuality forbidden
The virtual table pointer and the virtual table are in the address
space of the process that constructs the object, so if we place a
class with a virtual function or virtual base class, the virtual
pointer placed in shared memory will be invalid for other processes
and they will crash.
This problem is very difficult to solve, since each process needs a
different virtual table pointer and the object that contains that
pointer is shared across many processes. Even if we map the mapped
region in the same address in every process, the virtual table can be
in a different address in every process. To enable virtual functions
for objects shared between processes, deep compiler changes are needed
and virtual functions would suffer a performance hit. That's why
Boost.Interprocess does not have any plan to support virtual function
and virtual inheritance in mapped regions shared between processes.
Shared memory originally only allows POD structures (at heart, they may have constructors/copy/etc...).
Boost.Interprocess raises the bar by emulating pointers semantics on top of offsets into the shared memory segment.
However, a virtual pointer is not a pointer to pure data, it's a pointer to code sections, and that is where things get complicated because code sections are not necessarily mapped to the same address from one process to another (even if they were launched from the same binary).
So... no, virtual pointers-polymorphic objects cannot be stored in shared memory.
However, just because many C++ implementations chose to use a virtual-pointer mechanism does not mean that this is the only way to have polymorphic behavior. For example, in LLVM and Clang they build on their closed hierarchies to get polymorphism without virtual pointers (and RTTI) so as to lower memory requirements. Those objects could, effectively, be stored in shared memory.
So, how to get polymorphism compatible with shared memory: we need not to store pointers to tables/functions, however we can store indexes.
Example of the idea, but could probably be refined.
/// In header
#include <cassert>
#include <vector>
template <class, size_t> class BaseT;
class Base {
template <class, size_t> friend class BaseT;
public:
int get() const; // -> Implement: 'int getImpl() const' in Derived
void set(int i); // = 0 -> Implement: 'void setImpl(int i)' in Derived
private:
struct VTable {
typedef int (*Getter)(void const*);
typedef void (*Setter)(void*, int);
VTable(): _get(0), _set(0) {}
Getter _get;
Setter _set;
};
static std::vector<VTable>& VT(); // defined in .cpp
explicit Base(size_t v): _v(v) {}
size_t _v;
}; // class Base
template <class Derived, size_t Index>
class BaseT: public Base {
public:
BaseT(): Base(Index) {
static bool const _ = Register();
(void)_;
}
// Provide default implementation of getImpl
int getImpl() const { return 0; }
// No default implementation setImpl
private:
static int Get(void const* b) {
Derived const* d = static_cast<Derived const*>(b);
return d->getImpl();
}
static void Set(void* b, int i) {
Derived* d = static_cast<Derived*>(b);
d->setImpl(i);
}
static bool Register() {
typedef Base::VTable VTable;
std::vector<VTable>& vt = Base::VT();
if (vt.size() <= Index) {
vt.insert(vt.end(), Index - vt.size() + 1, VTable());
} else {
assert(vt[Index]._get == 0 && "Already registered VTable!");
}
vt[Index]._get = &Get;
vt[Index]._set = &Set;
}
}; // class BaseT
/// In source
std::vector<VTable>& Base::VT() {
static std::vector<VTable> V;
return V;
} // Base::VT
int Base::get() const {
return VT()[_v]._get(this);
} // Base::get
void Base::set(int i) {
return VT()[_v]._set(this, i);
} // Base::set
Okay... I guess that now you appreciate the compiler's magic...
Regarding the usage, it's fortunately much simpler:
/// Another header
#include <Base.h>
// 4 must be unique within the hierarchy
class Derived: public BaseT<Derived, 4> {
template <class, size_t> friend class BaseT;
public:
Derived(): _i(0) {}
private:
int getImpl() const { return _i; }
void setImpl(int i) { _i = i; }
int _i;
}; // class Derived
In action at ideone.
I believe you are looking at serialization of objects. Have a look at http://www.boost.org/doc/libs/1_51_0/libs/serialization/doc/index.html
A few ways you can do is:
1. serialize your C++ class
2. send data to another app
3. deserialize into C++ class.
//From the example above , I have removed VTable
// I also removed static variables as per boost::interprocess
// static variable don't work with shared memory, and also I did not see
// any advantage in actually builting a VTable for all derived classes
#include <vector>
#include <boost/bind.hpp>
#include <boost/function.hpp>
template <class> class BaseT;
class Base {
template <class> friend class BaseT;
boost::function< int (void) > _get;
boost::function< void (int) > _set;
public:
int get() {
return _get();
} // -> Implement: 'int get() ' in Derived
void set(int i) {
_set(i);
} // = 0 -> Implement: 'void set(int i)' in Derived
}; // class Base
template <class Derived>
class BaseT : public Base {
public:
BaseT() : Base(), impl(static_cast<Derived *> (this)) {
Base::_get = boost::bind(&BaseT<Derived>::get, this);
Base::_set = boost::bind(&BaseT<Derived>::set, this, _1);
}
int get() {
return impl->get();
}
void set(int i) {
impl->set(i);
}
private:
Derived * impl;
};
//some A implementation of Base
struct A : BaseT<A> {
int get() {
return 101; //testing implementation
}
void set(int i) {
; //implementation goes here
}
};
//some B implementation of Base
struct B : BaseT<B> {
int get() {
return 102; //testing implementation
}
void set(int i) {
; //implementation goes here
}
};
int main() {
BaseT<A> objectA;
BaseT<B> objectB;
Base *a = &objectA;
Base *b = &objectB;
std::cout << a->get() << " returned from A class , "
<< b->get() << " returned from B class " << std::endl;
return 0;
}
//While redefining I changed semantics of constnance in getter,
//and had non- const Derived pointer used for both getter and setter.
//But original simantics can be preserved as following:
int get() const {
//return impl->get();
//this enforces that get has to be const
static_cast<const Derived *> (this)->get() ;
}

Avoiding dynamic_cast in implementation of virtual functions in derived class

Here is some sample code explaining what I am trying to achieve.
Basically, I have an algorithm that depends on some basic operations available in a class. I have defined those operations in a pure abstract base class. I want to apply that algorithm to a variety of objects that provide those operations by deriving classes for the specific objects.
However, the different derived objects are incompatible with one another as far those operations are concerned. My question is whether I can avoid using RTTI to ensure that for example, bool derived2::identical(const base* other2), asserts(or other exit mechanism) where other2 is not of type derived2.
One alternative would be to template the function algorithm on the specific derived object, but that would mean that it's implementation would have to live in a header file which I don't want to do since 1) Changing the algorithm code for test purposes can cause recompilation of large portions of the code 2) The algorithm's implementation would be exposed in the header instead of living nicely in a source file hidden from the end-user.
Header file
#include <list>
class base
{
public:
virtual float difference(const base*) const = 0;
virtual bool identical(const base*) const = 0;
};
class derived1 : public base
{
public:
float difference(const base* other1) const
{
// other1 has to be of type derived1
if(typeid(other1) == typeid(this))
{
// process ...
}
else
{
assert(0);
}
return 1;
}
bool identical(const base* other1) const
{
// other1 has to be of type derived1
if(typeid(other1) == typeid(this))
{
// compare...
}
else
{
assert(0);
}
return true;
}
};
class derived2 : public base
{
public:
float difference(const base* other2) const
{
// process ...
// other2 has to be of type derived2
return 2;
}
bool identical(const base* other2) const
{
// do comparison
// derived1 and derived2 cannot be compared
return true;
}
};
// Declaration
int algorithm(std::list<base*>& members);
Implementation of algorithm Source file
#include "header_file_containing_base"
int algorithm(std::list<base*>& members)
{
// This function only relies on the interface defined in base
// process members;
return 1;
}
Main program
int main()
{
// Create lists of derived1 and derived2
// Run algorithm on these lists
}
You could use double dispatch (http://en.wikipedia.org/wiki/Double_dispatch)
Well, there is one simple thing: store the real type as a member.
An enum, grouping all the types. It'll become cumbersome if you have a lot of them.
A Factory to generate ids (using templates to only generate one id per item)
...
I'll illustrate the factory id:
class IdFactory
{
public:
template <class T>
static size_t GetId(T const&) // argument deduction
{
static size_t const Id = GetIdImpl();
return Id;
}
private:
static size_t GetIdImpl()
{
static size_t Id = 0;
return ++Id;
}
}; // class IdFactory
And you can use it like such:
class Base
{
public:
explicit Base(size_t id): mId(id) {}
size_t const mId; // meaningless to change it afterward...
private:
};
class Derived: public Base
{
public:
explicit Derived(): Base(IdFactory::GetId(*this)) {}
};
Then you can use the mId member for testing. Note that since it's const it can be exposed... otherwise you can create an inline const getter...
float Derived::difference(const Base& rhs)
{
assert( IdFactory::GetId(*this) == rhs.mId );
// ...
}
The cost here is negligible:
GetId is inlined, thus no function call
GetId is lazily initialized, apart for the initialization it amounts to checking that the static member has been initialized: it's typically implemented as a if statement which condition always evaluate to true (apart from the first time).
== is normally fast ;)
The only downside is that you actually need to make sure that you correctly initialize the ids.
There is also a no-storing solution, which involves a virtual function call:
class Other: public Base
{
public:
virtual size_t id() const { return IdFactory::GetId(*this); }
};
It's easier to put in practice because not storing a const member means that you don't have to write the assignment yourself.
You could use a templated function. With templates it is possible to add more classes later without the need to change the original classes, by just adding another template function in another header file. If the only problem is the compile speed - you can implement the template function in a source file apart from the header and use explicit template instanciation.