I have a header...
Components.h
namespace ComponentManager
{
void InitializeComponents(std::size_t numComponents);
void AddComponent(const Component& c, std::size_t position);
std::vector<Component> GetComponents();
}
... and the implementation:
Components.cpp
#include "Components.h"
std::vector<ComponentManager::Component> components;
void ComponentManager::InitializeComponents(std::size_t numComponents)
{
components.resize(numComponents, Component());
}
void ComponentManager::AddComponent(const Component& c, std::size_t pos)
{
components[pos] = c;
}
std::vector<ComponentManager::Component> ComponentManager::GetComponents()
{
return components;
}
In main.cpp, I make sure to initialize the components vector, and I add several components. Upon debugging each AddComponent(...) call, I see that the components are actually stored in the vector. However, when I call GetComponents(), the returned vector is different, as if the components were never stored.
What am I missing?
EDIT: Adding main.cpp (inside main() function)
//Inside EntityManager::Initialize(), I call ComponentManager::InitializeComponents()
EntityManager::Initialize(5000);
for (unsigned int i = 0; i < 10; ++i)
{
uint16_t handle = EntityManager::CreatePlayer(static_cast<float>(i), 50.0f * i);
//Inside EntityManager::AddComponent, I call ComponentManager::AddComponent(..)
EntityManager::AddComponent(handle, ComponentManager::POSITION_COMPONENT | ComponentManager::RENDERABLE_COMPONENT);
}
auto components = ComponentManager::GetComponents(); //this vector does not contain the elements that were added.
Originally, this was the definition of Component:
union Component
{
PositionComponent positionComponent;
VelocityComponent velocityComponent;
AccelerationComponent accelerationComponent;
RenderableComponent renderableComponent;
Component() {}
~Component() {}
Component(const Component& other) {}
Component& operator=(const Component& other)
{
std::memmove(this, &other, sizeof(other));
return *this;
}
};
Adding the definition for the constructor and for the copy constructor was the fix:
union Component
{
PositionComponent positionComponent;
VelocityComponent velocityComponent;
AccelerationComponent accelerationComponent;
RenderableComponent renderableComponent;
Component()
{
std::memset(this, 0, sizeof(Component));
}
~Component() {}
Component(const Component& other)
{
std::memmove(this, &other, sizeof(other));
}
Component& operator=(const Component& other)
{
std::memmove(this, &other, sizeof(other));
return *this;
}
};
Related
I created sets of functions using the type-erasure design pattern:
Encodable: encode(), decode()
Printable: print()
If I overload these functions with MyStruct1 and MyStruct2, I'll be able to wrap these types in the type-erasure wrappers Encodable and Printable and indirectly call those functions using the wrappers functions and store MyStruct1 and MyStruct2 in a heterogeneous container like std::vector<Encodable>.
My problem arised when I wanted to use these objects both as an Encodable and a Printable or when I wanted to convert one to the other.
#include <cstdint>
#include <utility>
#include <memory>
#include <vector>
class Encodable {
private:
struct EncodableConcept {
virtual ~EncodableConcept() = default;
virtual std::vector<uint8_t> _encode() const = 0;
virtual bool _decode(std::vector<uint8_t> const& byteVector) = 0;
virtual std::unique_ptr<EncodableConcept> clone() const = 0;
};
template<typename EncodableT>
struct EncodableModel : public EncodableConcept {
EncodableModel(EncodableT inst) : _inst{std::move(inst)}
{}
std::vector<uint8_t> _encode() const override {
return encode(_inst);
}
bool _decode(std::vector<uint8_t> const& byteVector) override {
return decode(_inst, byteVector);
}
std::unique_ptr<EncodableConcept> clone() const override {
return std::make_unique<EncodableModel>(*this);
}
EncodableT _inst;
};
friend std::vector<uint8_t> encode(Encodable const& inst) {
return inst.pimpl->_encode();
}
friend bool decode(Encodable & inst, std::vector<uint8_t> const& byteVector) {
return inst.pimpl->_decode(byteVector);
}
public:
template<typename EncodableT>
Encodable(EncodableT inst)
: pimpl{std::make_unique<EncodableModel<EncodableT>>(std::move(inst))}
{}
Encodable(Encodable const& other)
: pimpl(other.pimpl->clone())
{}
Encodable& operator=(Encodable const& other) {
// Copy-and-swap idiom
Encodable tmp(other);
std::swap(pimpl, tmp.pimpl);
return *this;
}
// Move is not implemented to prevent the pimpl to be nullptr after move operation.
// Upon move the copy constructor or the copy assignment operator is going to be called.
private:
std::unique_ptr<EncodableConcept> pimpl;
};
class Printable {
private:
struct PrintableConcept {
virtual ~PrintableConcept() = default;
virtual void _print() const = 0;
virtual std::unique_ptr<PrintableConcept> clone() const = 0;
};
template<typename PrintableT>
struct PrintableModel : public PrintableConcept {
PrintableModel(PrintableT inst) : _inst{std::move(inst)}
{}
void _print() const override {
print(_inst);
}
std::unique_ptr<PrintableConcept> clone() const override {
return std::make_unique<PrintableModel>(*this);
}
PrintableT _inst;
};
friend void print(Printable const& inst) {
inst.pimpl->_print();
}
public:
template<typename PrintableT>
Printable(PrintableT inst)
: pimpl{std::make_unique<PrintableModel<PrintableT>>(std::move(inst))}
{}
Printable(Printable const& other)
: pimpl(other.pimpl->clone())
{}
Printable& operator=(Printable const& other) {
// Copy-and-swap idiom
Printable tmp(other);
std::swap(pimpl, tmp.pimpl);
return *this;
}
// Move is not implemented to prevent the pimpl to be nullptr after move operation.
// Upon move the copy constructor or the copy assignment operator is going to be called.
private:
std::unique_ptr<PrintableConcept> pimpl;
};
struct MyStruct1 {
MyStruct1(int x) : x{x} {}
int x;
};
std::vector<uint8_t> encode(MyStruct1 const& inst) {
std::vector<uint8_t> byteVector;
// ...
return byteVector;
}
bool decode(MyStruct1 & inst, std::vector<uint8_t> const& byteVector) {
// ...
return true; // Success
}
void print(MyStruct1 const& inst) {
printf("MyStruct1{%d}\n", inst.x);
}
struct MyStruct2 {
MyStruct2(float y) : y{y} {}
float y;
};
std::vector<uint8_t> encode(MyStruct2 const& inst) {
std::vector<uint8_t> byteVector;
// ...
return byteVector;
}
bool decode(MyStruct2 & inst, std::vector<uint8_t> const& byteVector) {
// ...
return true; // Success
}
void print(MyStruct2 const& inst) {
printf("MyStruct2{%f}\n", inst.y);
}
std::vector<Encodable> readFromSomewhere() {
std::vector<Encodable> readEncodables;
// Read from file, socket, etc...
readEncodables = {MyStruct1{1}, MyStruct2{2.2}, MyStruct1{3}, MyStruct2{4.4}};
return readEncodables;
}
int main(int argc, char** argv) {
std::vector<Encodable> readEncodables = readFromSomewhere();
// TODO: How can I print readEncodables using the overloaded print functions?
// For example:
for (Encodable const& obj : readEncodables) {
// print(obj); // Compilation error (thanks god)
}
// TODO: How can I convert an Encodable to a Printable object?
std::vector<Printable> convertedPrintables;
for (Encodable const& obj : readEncodables) {
// convertedPrintables.emplace_back(obj); // Compilation error (thanks god)
// print(*convertedPrintables.crbegin());
}
return 0;
}
How can I easily convert an Encodable to a Printable and vice versa?
Can I somehow directly use an Encodable as a Printable if the print() function is overloaded for the given type?
My only (bad) solution is to create a templated get() function in the wrappers to unwrap the contained object run-time. If the type of the template argument matches the object the unwrap succeeds and I can rewrap it into a Printable or just directly use the overloaded print() free function.
template<typename EncodableT>
EncodableT* get() const {
EncodableModel<EncodableT>* modelPtr = dynamic_cast<EncodableModel<EncodableT>*> pimpl.get());
if (modelPtr == nullptr) return nullptr;
return &modelPtr->_inst;
}
However the usage of this function would be rather ugly and inconvenient:
for (Encodable const& obj : readEncodables) {
auto* ptr1 = obj.get<MyStruct1>();
if (ptr1 != nullptr) {
print(*ptr1);
continue;
}
auto* ptr2 = obj.get<MyStruct2>();
if (ptr2 != nullptr) {
print(*ptr2);
continue;
}
// ...
}
This could be made a bit nicer by storing std::type_index the wrappers, but I'd still have create if-else or switch statements for each type for calling a simple print() free function...
Edit: I had copied the base template for the statisticscompiler class from another solution, and it seems I somehow had ended up editing the original one while including the new one (that hadn't been edited yet) which is what led to the errors. So a tale of caution against copy pasting code into another file with the same name.
I will just post the header files because I think that's what matters here, let me know if otherwise and I can post the cpp. I have one base class that collects statistics from a process, with two derived classes and then a class that let's me use several statistics classes at once
Statistics.h
#pragma once
#define STATISTIC_H
#include <vector>
#include "Arrays.h"
class Statistics
{
public:
Statistics() {}
virtual void DumpOnePath(MJArray results) = 0;
virtual std::vector<std::vector<double>> GetResultsSoFar() const = 0;
virtual Statistics* clone() const = 0;
virtual ~Statistics() {}
private:
};
class StatisticsMean : public Statistics
{
public:
StatisticsMean();
virtual void DumpOnePath(MJArray results) ;
virtual std::vector<std::vector<double>> GetResultsSoFar() const ;
virtual Statistics* clone() const;
private:
MJArray RunningSums;
unsigned long PathsDone;
};
class StatisticsQuantiles : public Statistics
{
public:
StatisticsQuantiles(double p_lower_, double p_upper_);
virtual void DumpOnePath(MJArray results);
virtual std::vector<std::vector<double>> GetResultsSoFar() const;
virtual Statistics* clone() const;
private:
std::vector<MJArray> RunningResults;
unsigned long PathsDone;
double p_lower;
double p_upper;
};
StatisticsCompiler.h
#pragma once
#define STATISTICS_COMPILER_H
#include "statistics.h"
#include "wrapper.h"
class StatisticsCompiler : public Statistics
{
public:
StatisticsCompiler(const std::vector <Wrapper<Statistics>>& Inner_);
virtual Statistics* clone() const;
virtual void DumpOnePath(MJArray results);
virtual std::vector<std::vector<double>> GetResultsSoFar() const;
private:
std::vector <Wrapper<Statistics>> Inner;
};
And in my main class I'm trying to do this:
StatisticsMean meanGatherer;
StatisticsQuantiles quantileGatherer(p_lower, p_upper);
vector<Wrapper<Statistics>> gathererArray{ meanGatherer, quantileGatherer};
StatisticsCompiler meanAndQuantileGatherer(gathererArray);
Which gives an error no the last line complaining that "No instance of constructor matches the argument list. Argument types are:
(std::vector<Wrapper<Statistics>, std::allocator<Wrapper<Statistics>>>)."
But isn't that exactly what I've defined the constructor to accept? at least the first part, I don't know what
std::allocator<Wrapper<Statistics>>
means.
Wrapper.h in case needed. It does the memory handling
#pragma once
#define WRAPPER_H
template< class T>
class Wrapper
{
public:
Wrapper()
{
DataPtr = 0;
}
Wrapper(const T& inner)
{
DataPtr = inner.clone();
}
~Wrapper()
{
if (DataPtr != 0)
delete DataPtr;
}
Wrapper(const Wrapper<T>& original)
{
if (original.DataPtr != 0)
DataPtr = original.DataPtr->clone();
else
DataPtr = 0;
}
Wrapper& operator=(const Wrapper<T>& original)
{
if (this != &original)
{
if (DataPtr != 0) {
delete DataPtr;
}
DataPtr = (original.DataPtr != 0) ? original.DataPtr->clone() : 0;
}
return *this;
}
T& operator*()
{
return *DataPtr;
}
const T& operator*() const
{
return *DataPtr;
}
const T* const operator->() const
{
return DataPtr;
}
T* operator->()
{
return DataPtr;
}
private:
T* DataPtr;
};
How can I delete all the pointer in my vector before that I going to copy to my vector new pointers (in case of const object)?
class Element {
int val;
public:
Element(int val) :
val(val) {
}
};
class MyClass {
vector<Element*> v;
static void FreeMemory(vector<Element*>& vec) {
for (unsigned int i = 0; i < vec.size(); i++) {
delete vec[i];
}
}
public:
MyClass() = default;
MyClass(const MyClass& mc) {
//...
}
MyClass& operator=(const MyClass& mc) {
if (this == &mc) {
return *this;
}
//...
FreeMemory(mc.v); //**error** - how can I delete the memory of any Element?
//...
return *this;
}
// ....
// ....
};
binding 'const std::vector' to reference of type 'std::vector&' discards qualifiers
Can I fix it with smart_pointers?
Here is a sketch of a class owning a std::vector of Element objects managed by std::unique_ptr. Not fully worked out, but it might work as a starting point.
class Element {
int val;
public:
explicit Element(int val) : val(val) {}
virtual ~Element() = default;
/* Subclasses must implement this method: */
virtual std::unique_ptr<Element> clone() const = 0;
};
class ExclusivelyOwning {
private:
std::vector<std::unique_ptr<Element>> v;
public:
ExclusivelyOwning() = default;
ExclusivelyOwning(const ExclusivelyOwning& other) {
v.reserve(other.v.size());
for (const auto& element : other.v)
v.push_back(element->clone());
}
ExclusivelyOwning& operator=(const ExclusivelyOwning& rhs) {
/* Use copy-swap idiom, not shown here. */
return *this;
}
ExclusivelyOwning(ExclusivelyOwning&&) = default;
ExclusivelyOwning& operator = (ExclusivelyOwning&&) = default;
~ExclusivelyOwning() = default;
};
Note that copying an object with references to abstract classes (as Element in the code above) requires further techniques to render the copying meaningful. Here, I used a "virtual constructor" - the clone method.
Consider the following class that wraps a container and type-erases its type:
class C final {
struct B {
virtual bool empty() const noexcept = 0;
};
template<class T, class A>
struct D: public B {
// several constructors aimed to
// correctly initialize the underlying container
bool empty() const noexcept override { return v.empty(); }
private:
std::vector<T, A> v;
};
// ...
public:
//...
bool operator==(const C &other) const noexcept {
// ??
// would like to compare the underlying
// container of other.b with the one
// of this->b
}
private:
// initialized somehow
B *b;
};
I'd like to add the operator== to the class C.
Internally, it should simply invoke the same operator on the underlying containers, but I'm stuck on this problem, for I don't know how to do that.
The idea is that two instances of C are equal if the operator== of their underlying containers return true.
Whatever I've tried till now, I ever ended up being unable to get the type of one of the two underlying containers, mainly the one of other.
Is there an easy solution I can't see at the moment or I should give up?
Despite the good suggestion from juanchopanza, I found that, as far as the underlying containers represent the same concept (as an example, different specializations of a vector), maybe there is no need of a type-erased iterator.
Below it's a possible implementation that relies on the operator[] and the size member method:
#include <vector>
#include <cassert>
class Clazz final {
struct BaseContainer {
virtual std::size_t size() const noexcept = 0;
virtual int operator[](std::size_t) const = 0;
virtual void push_back(int) = 0;
};
template<class Allocator>
struct Container: public BaseContainer {
Container(Allocator alloc): v{alloc} { }
std::size_t size() const noexcept override { return v.size(); }
int operator[](std::size_t pos) const override { return v[pos]; }
void push_back(int e) override { v.push_back(e); }
private:
std::vector<int, Allocator> v;
};
public:
template<class Allocator = std::allocator<int>>
Clazz(const Allocator &alloc = Allocator{})
: container{new Container<Allocator>{alloc}} { }
~Clazz() { delete container; }
void push_back(int e) { container->push_back(e); }
bool operator==(const Clazz &other) const noexcept {
const BaseContainer &cont = *container;
const BaseContainer &oCont = *(other.container);
bool ret = (cont.size() == oCont.size());
for(std::vector<int>::size_type i = 0, s = cont.size(); i < s && ret; i++) {
ret = (cont[i] == oCont[i]);
}
return ret;
}
bool operator!=(const Clazz &other) const noexcept {
return !(*this == other);
}
private:
BaseContainer *container;
};
int main() {
Clazz c1{}, c2{}, c3{};
c1.push_back(42);
c2.push_back(42);
assert(c1 == c2);
assert(c1 != c3);
}
Open to criticism, hoping this answer can help other users. :-)
Assuming you wish to return false when the comparing two different containers, this should do the job (caution: untested):
class Container
{
struct Concept
{
virtual ~Concept() = default;
virtual Concept* clone() const = 0;
virtual bool equals(Concept const*) const = 0;
};
template<typename T>
struct Model final : Concept
{
Model(T t) : data{std::move(t)} {}
Model* clone() const override { return new Model{*this}; }
virtual bool equals(Concept const* rhs) const override
{
if (typeid(*this) != typeid(*rhs))
return false;
return data == static_cast<Model const*>(rhs)->data;
}
T data;
};
std::unique_ptr<Concept> object;
public:
template<typename T>
Container(T t) : object(new Model<T>{std::move(t)}) {}
Container(Container const& that) : object{that.object->clone()} {}
Container(Container&& that) = default;
Container& operator=(Container that)
{ object = std::move(that.object); return *this; }
friend bool operator==(Container const& lhs, Container const& rhs)
{ return lhs.object->equals(rhs.object.get()); }
};
I realize that I'll most likely get a lot of "you shouldn't do that because..." answers and they are most welcome and I'll probably totally agree with your reasoning, but I'm curious as to whether this is possible (as I envision it).
Is it possible to define a type of dynamic/generic object in C++ where I can dynamically create properties that are stored and retrieved in a key/value type of system? Example:
MyType myObject;
std::string myStr("string1");
myObject.somethingIJustMadeUp = myStr;
Note that obviously, somethingIJustMadeUp is not actually a defined member of MyType but it would be defined dynamically. Then later I could do something like:
if(myObject.somethingIJustMadeUp != NULL);
or
if(myObject["somethingIJustMadeUp"]);
Believe me, I realize just how terrible this is, but I'm still curious as to whether it's possible and if it can be done in a way that minimizes it's terrible-ness.
C++Script is what you want!
Example:
#include <cppscript>
var script_main(var args)
{
var x = object();
x["abc"] = 10;
writeln(x["abc"]);
return 0;
}
and it's a valid C++.
You can do something very similar with std::map:
std::map<std::string, std::string> myObject;
myObject["somethingIJustMadeUp"] = myStr;
Now if you want generic value types, then you can use boost::any as:
std::map<std::string, boost::any> myObject;
myObject["somethingIJustMadeUp"] = myStr;
And you can also check if a value exists or not:
if(myObject.find ("somethingIJustMadeUp") != myObject.end())
std::cout << "Exists" << std::endl;
If you use boost::any, then you can know the actual type of value it holds, by calling .type() as:
if (myObject.find("Xyz") != myObject.end())
{
if(myObject["Xyz"].type() == typeid(std::string))
{
std::string value = boost::any_cast<std::string>(myObject["Xyz"]);
std::cout <<"Stored value is string = " << value << std::endl;
}
}
This also shows how you can use boost::any_cast to get the value stored in object of boost::any type.
This can be a solution, using RTTI polymorphism
#include <map>
#include <memory>
#include <iostream>
#include <stdexcept>
namespace dynamic
{
template<class T, class E>
T& enforce(T& z, const E& e)
{ if(!z) throw e; return z; }
template<class T, class E>
const T& enforce(const T& z, const E& e)
{ if(!z) throw e; return z; }
template<class Derived>
class interface;
class aggregate;
//polymorphic uncopyable unmovable
class property
{
public:
property() :pagg() {}
property(const property&) =delete;
property& operator=(const property&) =delete;
virtual ~property() {} //just make it polymorphic
template<class Interface>
operator Interface*() const
{
if(!pagg) return 0;
return *pagg; //let the aggregate do the magic!
}
aggregate* get_aggregate() const { return pagg; }
private:
template<class Derived>
friend class interface;
friend class aggregate;
static unsigned gen_id()
{
static unsigned x=0;
return enforce(++x,std::overflow_error("too many ids"));
}
template<class T>
static unsigned id_of()
{ static unsigned z = gen_id(); return z; }
aggregate* pagg;
};
template<class Derived>
class interface: public property
{
public:
interface() {}
virtual ~interface() {}
unsigned id() const { return property::id_of<Derived>(); }
};
//sealed movable
class aggregate
{
public:
aggregate() {}
aggregate(const aggregate&) = delete;
aggregate& operator=(const aggregate&) = delete;
aggregate(aggregate&& s) :m(std::move(s.m)) {}
aggregate& operator=(aggregate&& s)
{ if(this!=&s) { m.clear(); std::swap(m, s.m); } return *this; }
template<class Interface>
aggregate& add_interface(interface<Interface>* pi)
{
m[pi->id()] = std::unique_ptr<property>(pi);
static_cast<property*>(pi)->pagg = this;
return *this;
}
template<class Inteface>
aggregate& remove_interface()
{ m.erase[property::id_of<Inteface>()]; return *this; }
void clear() { m.clear(); }
bool empty() const { return m.empty(); }
explicit operator bool() const { return empty(); }
template<class Interface>
operator Interface*() const
{
auto i = m.find(property::id_of<Interface>());
if(i==m.end()) return nullptr;
return dynamic_cast<Interface*>(i->second.get());
}
template<class Interface>
friend aggregate& operator<<(aggregate& s, interface<Interface>* pi)
{ return s.add_interface(pi); }
private:
typedef std::map<unsigned, std::unique_ptr<property> > map_t;
map_t m;
};
}
/// this is a sample on how it can workout
class interface_A: public dynamic::interface<interface_A>
{
public:
virtual void methodA1() =0;
virtual void methodA2() =0;
};
class impl_A1: public interface_A
{
public:
impl_A1() { std::cout<<"creating impl_A1["<<this<<"]"<<std::endl; }
virtual ~impl_A1() { std::cout<<"deleting impl_A1["<<this<<"]"<<std::endl; }
virtual void methodA1() { std::cout<<"interface_A["<<this<<"]::methodA1 on impl_A1 in aggregate "<<get_aggregate()<<std::endl; }
virtual void methodA2() { std::cout<<"interface_A["<<this<<"]::methodA2 on impl_A1 in aggregate "<<get_aggregate()<<std::endl; }
};
class impl_A2: public interface_A
{
public:
impl_A2() { std::cout<<"creating impl_A2["<<this<<"]"<<std::endl; }
virtual ~impl_A2() { std::cout<<"deleting impl_A2["<<this<<"]"<<std::endl; }
virtual void methodA1() { std::cout<<"interface_A["<<this<<"]::methodA1 on impl_A2 in aggregate "<<get_aggregate()<<std::endl; }
virtual void methodA2() { std::cout<<"interface_A["<<this<<"]::methodA2 on impl_A2 in aggregate "<<get_aggregate()<<std::endl; }
};
class interface_B: public dynamic::interface<interface_B>
{
public:
virtual void methodB1() =0;
virtual void methodB2() =0;
};
class impl_B1: public interface_B
{
public:
impl_B1() { std::cout<<"creating impl_B1["<<this<<"]"<<std::endl; }
virtual ~impl_B1() { std::cout<<"deleting impl_B1["<<this<<"]"<<std::endl; }
virtual void methodB1() { std::cout<<"interface_B["<<this<<"]::methodB1 on impl_B1 in aggregate "<<get_aggregate()<<std::endl; }
virtual void methodB2() { std::cout<<"interface_B["<<this<<"]::methodB2 on impl_B1 in aggregate "<<get_aggregate()<<std::endl; }
};
class impl_B2: public interface_B
{
public:
impl_B2() { std::cout<<"creating impl_B2["<<this<<"]"<<std::endl; }
virtual ~impl_B2() { std::cout<<"deleting impl_B2["<<this<<"]"<<std::endl; }
virtual void methodB1() { std::cout<<"interface_B["<<this<<"]::methodB1 on impl_B2 in aggregate "<<get_aggregate()<<std::endl; }
virtual void methodB2() { std::cout<<"interface_B["<<this<<"]::methodB2 on impl_B2 in aggregate "<<get_aggregate()<<std::endl; }
};
int main()
{
dynamic::aggregate agg1;
agg1 << new impl_A1 << new impl_B1;
dynamic::aggregate agg2;
agg2 << new impl_A2 << new impl_B2;
interface_A* pa = 0;
interface_B* pb = 0;
pa = agg1; if(pa) { pa->methodA1(); pa->methodA2(); }
pb = *pa; if(pb) { pb->methodB1(); pb->methodB2(); }
pa = agg2; if(pa) { pa->methodA1(); pa->methodA2(); }
pb = *pa; if(pb) { pb->methodB1(); pb->methodB2(); }
agg2 = std::move(agg1);
pa = agg2; if(pa) { pa->methodA1(); pa->methodA2(); }
pb = *pa; if(pb) { pb->methodB1(); pb->methodB2(); }
return 0;
}
tested with MINGW4.6 on WinXPsp3
Yes it is terrible. :D
It had been done numerous times to different extents and success levels.
QT has Qobject from which everything related to them decends.
MFC has CObject from which eveything decends as does C++.net
I don't know if there is a way to make it less bad, I guess if you avoid multiple inheritance like the plague (which is otherwise a useful language feature) and reimplement the stdlib it would be better. But really if that is what you are after you are probably using the wrong language for the task.
Java and C# are much better suited to this style of programming.
#note if I have read your question wrong just delete this answer.
Check out Dynamic C++