gpt4 book ai didi

c++ - 为什么这个自定义指针类会崩溃?

转载 作者:太空狗 更新时间:2023-10-29 20:20:36 25 4
gpt4 key购买 nike

我正在实现一个特殊用途的句柄类。

ihandle是一个所有句柄都必须实现的接口(interface),在我的真实代码中它将具有 -> 的运算符重载* .但是对于这个例子,我想保持简单,它只有 get。功能。

template <typename T>
class ihandle {
public:
virtual T* get();
};

一个可能的实现是 ptr , 这只是一个原始指针。

template <typename T>
class ptr : public ihandle<T>
{
T* t;
public:
ptr(T* t = nullptr) : t(t) {}
T* get(){return t;}
};

然后是handle用于进行空安全检查。

template <typename T>
class handle
{
public:
ihandle<T>* h;

T* get(){return h->get();}
handle(ihandle<T>* h = nullptr) : h(h) {}

template <typename D>
handle(handle<D>& hd)
: h((ihandle<T>*)hd.h)
{
static_assert(is_base_of<T, D>::value, "error");
}
};

有这个构造函数可以从继承类的句柄转换为基类的句柄。

template <typename D>
handle(handle<D>& hd)
: h((ihandle<T>*)hd.h)
{
static_assert(is_base_of<T, D>::value, "error");
}

例如,如果 B继承自 A ,我希望能够使用 handle<B> 的实例调用此函数.

void foo(handle<A> ha) {
// do something
}

但这会导致以下示例测试出现段错误。

struct A {
virtual void talk() {printf("A\n");}
};

struct B : public A {
void talk() {printf("B\n");}
};

int main()
{
handle<B> hb(new ptr<B>(new B));
//hb.get()->talk(); // if uncomment, no segfault
handle<A> ha = hb;
ha.get()->talk(); // segfault here

return 0;
}

我怀疑问题可能在 handle(handle<D>& hd) 中构造函数,但我不明白发生了什么。

您可以点击此链接进行测试: https://onlinegdb.com/BkAYuQZ3z

最佳答案

即使条件is_base_of<T, D>::value是真的它不会(ihandle<T>*) hd.h转换有效因为 ptr<B>ihandle<A>类型不相关。我想这是一个绝对应该避免使用 c 风格转换的例子。要安全地执行转换,您可以使用 dynamic_cast用支票:

: h(dynamic_cast<ihandle<T>*>(hd.h))
{
if(hd.h && !h)
{
throw ::std::runtime_error{"pointers are not related"};
}
}

关于c++ - 为什么这个自定义指针类会崩溃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49846030/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com