c++ - static_pointer_cast 导致指向不同位置的shared_ptr

标签 c++ shared-ptr

我创建了一个 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/

相关文章:

c++ - 重置由 lambda 值捕获的 boost::shared_ptr

c++ - 从原始指针构造时 shared_ptr 是否分配?

c++ - 在多个线程/函数之间使用shared_ptr-IDS Peak API

c++ - 堆栈跟踪中的 "pure virtual"调用是什么意思?

c++ - 警告 C4244 : 'argument' : conversion from 'time_t' to 'unsigned int' , 可能丢失数据 -- C++

c++ - 如何防止删除由 QSharedPointer 管理的指针

c++ - 使用 C++11 复制构造 boost::shared_ptr 时出错

c++ - 将 cmake 用于 C++ 模板库

c++ - 在同一语句中返回传入的临时值并从中读取是否安全?

c++ - 当接收到不明确的规范时,表示图形邻接表的数据结构