我创建了一个 World
类来存储派生的 Object
列表。我最终得到以下结果:
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_;
};
我偶然发现了一些让我困惑的事情。对于 T
实现的每个其他类,static_pointer_cast
生成的指针指向原始指针 (sp
) 之后的 4 个字节。 (我希望这是有道理的)
例如:
我将此行添加到 registerObject
std::cout << "sp:\t\t" << sp.get() << "\nop:\t\t" << op.get() << std::endl;
然后我创建了以下类:
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 {
};
以此作为我的主要功能:
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;
}
并得到这个输出:
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
我设法让 op
指向与 sp
相同的地址的唯一方法是其他基类为空。
那么为什么会发生这种情况呢?它仍然指向该对象,只是地址不同。
抱歉,如果这是一个愚蠢的问题。我自己尝试过解决这个问题,并且我有一个“理论”,但我刚刚完成了大学计算机科学的第一年,这让我有点超出了我的能力范围。
最佳答案
它并非特定于 static_pointer_cast
,因为普通的 static_cast
将表现出相同的行为。这通常是实现处理多重继承的方式。对象指针将指向不同的位置,具体取决于它实际指向的类型。
关于c++ - static_pointer_cast 导致指向不同位置的shared_ptr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12015153/