【发布时间】:2019-06-10 15:59:18
【问题描述】:
我在一个项目中使用了 shared_ptr。在某一时刻,我不得不将原始指针存储为 void,然后在传递 void* 的回调中将其转换回其 shared_ptr 形式。但由于某种原因,代码不断崩溃。我不明白为什么,因为我没有收到任何编译器错误或警告。但我注意到,当我从std::enable_shared_from_this 继承时,我并没有将其指定为公共继承。这就是导致崩溃的原因。
我写了一个示例代码,我只是想知道为什么会这样。
#include <memory>
#include <iostream>
class TestShared : public std::enable_shared_from_this<TestShared>{
private:
int32_t id;
public:
TestShared(int32_t id){
this->id = id;
}
std::shared_ptr<TestShared> getshared(){
return shared_from_this();
}
int32_t getid(){
return id;
}
};
int main(){
std::shared_ptr<TestShared> ts(new TestShared(0xFF));
void* tsp = ts.get();
std::shared_ptr<TestShared> tsn = ((TestShared*)tsp)->getshared();
std::cout << std::hex << tsn->getid();
return 0;
}
这样代码就能正常执行和运行,我得到了预期的结果。
但是当我从继承中删除 public 时:
#include <memory>
#include <iostream>
class TestShared : std::enable_shared_from_this<TestShared>{
private:
int32_t id;
public:
TestShared(int32_t id){
this->id = id;
}
std::shared_ptr<TestShared> getshared(){
return shared_from_this();
}
int32_t getid(){
return id;
}
};
int main(){
std::shared_ptr<TestShared> ts(new TestShared(0xFF));
void* tsp = ts.get();
std::shared_ptr<TestShared> tsn = ((TestShared*)tsp)->getshared();
std::cout << std::hex << tsn->getid();
return 0;
}
然后它会导致崩溃。那么为什么public 在这里有所作为,为什么编译器不给出警告/错误呢?
【问题讨论】:
-
无关:为什么需要将拥有的指针转换为
void*?它与shared_ptr并排看起来非常格格不入。 -
因为我是一个使用 C 库的人,它触发了我实现的回调。传递给回调的对象有一个用户上下文,它是一个 void*。所以我将我的对象转换为 void* 作为要在回调中传递的上下文。这个特定示例中的 void* 只是为了准确复制我在项目中所做的事情。
-
完全有道理;继续。我只是担心你可能在做某种类型的双关语或多态性黑客,但似乎你知道你在做什么:-)
标签: c++ shared-ptr private-inheritance enable-shared-from-this