I have made a World
class to store a list of derived Object
. I have ended up with the below:
class World {
typedef std::shared_ptr<Object> object_ptr;
public:
template<class T> void registerObject(T& object) {
auto sp = std::shared_ptr<T>(&object, [](T*){});
object_ptr op = std::static_pointer_cast<Object>(sp);
objects_.push_back(op);
}
private:
std::list<object_ptr> objects_;
};
I stumbled across something which is confusing me. The static_pointer_cast
is resulting in a pointer that points 4 bytes after the original pointer (sp
) for every other class that T
implements. (I hope that made sense)
For instance:
I add this line to registerObject
std::cout << "sp:\t\t" << sp.get() << "\nop:\t\t" << op.get() << std::endl;
I then created the below classes:
class Object {
protected:
int o; //the base classes can't be empty, the amount inside them doesn't effect anything as long as they're not empty.
};
class Bar {
protected:
int b;
};
class Foo {
protected:
int f;
};
class Derive1 : public Object {
};
class Derive2 : public Bar, public Object {
};
class Derive3 : public Foo, public Bar, public Object {
};
With this as my main function:
int main() {
World w;
Derive1 d1;
Derive2 d2;
Derive3 d3;
std::cout << "d1:\t\t" << &d1 << std::endl;
w.registerObject(d1);
std::cout << "d2:\t\t" << &d2 << std::endl;
w.registerObject(d2);
std::cout << "d3:\t\t" << &d3 << std::endl;
w.registerObject(d3);
return 0;
}
And get this output:
Deriving 0 other classes:
d1: 0xbf91f41c
sp: 0xbf91f41c
op: 0xbf91f41c
Deriving 1 other class:
d2: 0xbf91f414
sp: 0xbf91f414
op: 0xbf91f418
Deriving 2 other classes:
d3: 0xbf91f408
sp: 0xbf91f408
op: 0xbf91f410
The only way I have managed to get op
pointing to the same address as sp
is if the other base classes are empty.
So why is this happening? It still points to the object, just not the same address.
Sorry if this is a silly question. I've tried to work it out myself and I have a "theory" but I've only just finished my first year of CS at Uni and this has me a bit out of my depth.