gpt4 book ai didi

c++ - 转换持有多态类型的模板时的未定义行为

转载 作者:搜寻专家 更新时间:2023-10-30 23:54:58 25 4
gpt4 key购买 nike

出于类型删除的原因,我有一个模板 A<T>它可以容纳任何数据类型。当A持有多态类型 Derived源自 Base我把它转换到 A<Base> , GCC 的未定义行为 sanitizer 报告运行时错误:

#include <iostream>

struct I
{
virtual ~I() = default;
};

template<typename T>
struct A : public I
{
explicit A(T&& value) : value(std::move(value)) {}
T& get() { return value; }
private:
T value;
};

struct Base
{
virtual ~Base() = default;
virtual void fun()
{
std::cout << "Derived" << std::endl;
}
};

struct Derived : Base
{
void fun() override
{
std::cout << "Derived" << std::endl;
}
};

int main()
{
I* a_holding_derived = new A<Derived>(Derived());
A<Base>* a_base = static_cast<A<Base>*>(a_holding_derived);
Base& b = a_base->get();
b.fun();
return 0;
}

编译运行

$ g++ -fsanitize=undefined -g -std=c++11 -O0 -fno-omit-frame-pointer && ./a.out

输出:

main.cpp:37:62: runtime error: downcast of address 0x000001902c20 which does not point to an object of type 'A'

0x000001902c20: note: object is of type 'A<Derived>'

00 00 00 00 20 1e 40 00 00 00 00 00 40 1e 40 00 00 00 00 00 00 00 00 00 00 00 00 00 21 00 00 00

^~~~~~~~~~~~~~~~~~~~~~~

vptr for 'A<Derived>'

#0 0x400e96 in main /tmp/1450529422.93451/main.cpp:37

#1 0x7f35cb1a176c in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2176c)

#2 0x400be8 (/tmp/1450529422.93451/a.out+0x400be8)


main.cpp:38:27: runtime error: member call on address 0x000001902c20 which does not point to an object of type 'A'

0x000001902c20: note: object is of type 'A<Derived>'

00 00 00 00 20 1e 40 00 00 00 00 00 40 1e 40 00 00 00 00 00 00 00 00 00 00 00 00 00 21 00 00 00

^~~~~~~~~~~~~~~~~~~~~~~

vptr for 'A<Derived>'

#0 0x400f5b in main /tmp/1450529422.93451/main.cpp:38

#1 0x7f35cb1a176c in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2176c)

#2 0x400be8 (/tmp/1450529422.93451/a.out+0x400be8)


Derived

live example on coliru

我有两个问题:

  1. sanitizer 的输出是否正确?
  2. 如果是,如何从 A<Derived> 进行有效转换?至 A<Base>看起来像?

最佳答案

问题是 A<Base>A<Derived>彼此之间根本没有任何关系。它们的表示可能完全不同。对于你正在尝试做的 Actor ,有必要 A<Base>A<Derived> 的基类显然不是这样。

看来,您想要创建类似于值类型的智能指针之类的东西。副手,我不确定是否可以创建支持所有必要转换的值类型。如果在需要支持转换的类型组中存在特定需求或已知公共(public)基类,则可以实现相应的类。

关于c++ - 转换持有多态类型的模板时的未定义行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34371058/

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