我希望有一个类MyClass
来存储不同类型的队列。为此,我创建了一个接口ValueInterface
和一个派生类Value<T>
。我现在可以在MyClass
中使用queue<ValueInterface>
成员变量存储此派生类的实例。
注意 :出于我自己的目的,我故意试图保持MyClass
非模板,我想要依靠模板化的功能。
我有下面的代码编译,但在下面的测试代码中运行会导致核心转储。我认为在使用std::unique_ptr
时我非常小心,并确保在可能的情况下使用std::move
。 GetValueAndAdvance<T>
函数会导致错误。当我尝试从模板化队列中检索时出错了。我知道它很乱,我假设static_cast
会起作用,但是我怎样才能从Value<T>
中检索std::queue
,哪个存储ValueInterface
?
我不知道问题是在StoreValue
还是GetValueAndAdvance
,还是整个设计存在缺陷,而且在类型敏感的语言中是不可能的。
测试中的用法:
这是我想要完成的功能。这假设每个MyClass
一次只能用于一种类型。因此,我们假设没有人会在同一个StoreValue<int>(4)
对象上调用StoreValue<string>("hello")
和MyClass
。但出于我自己的原因,我想保持MyClass
非模板化。
MyClass my_class;
my_class.StoreValue<int>(5);
int val;
my_class.GetValueAndAdvance<int>(&val);
std::cout << "value: " << val; // Should print "value: 5"
代码:
class ValueInterface {};
template <class T>
class Value : public ValueInterface {
public:
Value(T val) : value_(val){};
T get() { return value_; }
private:
const T& value_;
};
class MyClass {
public:
template <class T>
void GetValueAndAdvance(T* out_val) {
if (!queued_values_.empty()) {
auto unique_value = std::move(queued_values_.front());
queued_values_.pop();
auto unique_value_typed = static_cast<Value<T>*>(unique_value.get());
*out_val = unique_value_typed->get();
// Prints 0 even though it should return 5 based on the test code (below)
std::cout << "value: " << unique_value_typed->get();
}
return;
}
template <class T>
MyClass* StoreValue(const T& value) {
auto wrapped_value = std::make_unique<Value<T>>(value);
queued_values_.push(std::move(wrapped_value));
return this;
}
private:
std::queue<std::unique_ptr<ValueInterface>> queued_values_;
};
错误消息的摘录
F0418 18:08:57.928949 244111 debugallocation.cc:763] RAW: delete size mismatch: passed size 1 != true size 4
@ 0x7fda024f8a1f (anonymous namespace)::RawLogVA()
@ 0x7fda024f8525 base_raw_logging::RawLog()
@ 0x42b162 tc_delete_sized
@ 0x40c595 std::default_delete<>::operator()()
@ 0x40c503 std::unique_ptr<>::~unique_ptr()
@ 0x40b552 mynamespace::MyClass::GetValueAndAdvance<>()
答案 0 :(得分:1)
问题出在Value
类,其中value_
被定义为引用到常量值
const T& value_;
将value_
定义为正常(非参考)值
const T value_;
您应该从5
获得std::cout
。
观察Value<T>
Value(T val) : value_(val){};
value_
引用初始化为(绑定到)临时变量(val
),该变量超出了构造函数末尾的范围。
所以value_
被限制在一个可以重用的内存中,因此具有未定义的值。