2

我创建了一个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_;
};

我偶然发现了一些让我感到困惑的东西。这static_pointer_cast会产生一个指针,该指针指向sp每个其他T实现的类的原始指针 ( ) 之后的 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

那么为什么会这样呢?它仍然指向对象,只是地址不同。

对不起,如果这是一个愚蠢的问题。我已经尝试自己解决这个问题,并且我有一个“理论”,但我刚刚完成了我在 Uni 的第一年 CS,这让我有点不知所措。

4

1 回答 1

2

它不是特定于static_pointer_cast,因为正常static_cast会表现出相同的行为。这通常是实现处理多重继承的方式。对象指针将指向不同的位置,具体取决于它真正指向的类型。

于 2012-08-18T02:03:05.243 回答