繁体   English   中英

向右强制转换为void *指针

[英]Right cast for a void* pointer

我正在尝试使用一个可以指向任何value字段实现C ++类(有点像boost :: any)。 目前,我正在执行以下操作:

class MyClass {
  void* value;
  template<typename T>
  Myclass(const &T v) {
    value = (void*)(new T(v));
  }
};

现在的问题是实现一个getValue()操作,该操作创建具有正确类型的内部值的副本:

template<typename T>
T getValue() {
 return *value;
}

在这里它不能工作,因为我试图取消引用void *指针。 我想知道应该使用哪种类型的转换(static_cast?dynamic_cast?other ...),以便将* value正确转换为T对象,并且如果value最初不是这种类型,则会引发异常?

谢谢

您不能取消引用void* ,这根本没有意义。 为什么不使类本身具有泛型? 然后您可以拥有:

template<typename T>
class MyClass {
  T* value;

  MyClass(const T& v) {
    value = new T(v);
  }

  T getValue() {
    return *value;
  }
};

确保创建一个析构函数,该析构函数可以分配value并遵循“三法则” 您也可以创建一个getValue版本,该版本返回const T& (指向T const引用)以避免不必要的复制。

我应该使用哪种转换(static_cast?dynamic_cast?other ...),以便将* value正确转换为T对象

如果必须执行此转换,则应使用static_cast ,通常将其用于(除其他事项外)撤消任何标准转换。 从任何对象指针类型到void*都有标准转换,您的getter会将其反转,因此请使用为此设计的强制转换:

return *static_cast<T*>(value);

您还应该从构造函数中删除C样式static_cast ,或者也将其替换为static_cast

reinterpret_cast也可以,但是“过度杀伤”。 通常,在执行所需转换的同时,应使用尽可能严格的转换。

如果value最初不是此类型,则抛出异常

您真不走运-一旦将指针转换为void* ,C ++通常就无法确定对象的原始类型是什么。 您的代码依赖于调用方以正确的类型调用getValue 例如,考虑一下如果原始类型是char ,会发生什么情况-在C ++中只有一个字节,那么就没有为任何类型信息留出空间,这将允许编译器检查getValue中的getValue

dynamic_cast在某些有限的情况下会检查类型,但是由于您的模板是完全通用的,因此这些有限的情况可能不适用。

如果您不喜欢这样做,则除了对象指针外,还可以更改类以存储指向type_info对象的指针(使用typeid运算符)。 参见标准标题<typeinfo> 然后,您可以比较type_info对象类型T的构造,与type_info的对象类型TgetValue ,并抛出,如果他们不匹配。

就像您说的那样,您的类打算有点像boost::any ,而getValue就像any_cast 您可以查阅该类的源代码和文档,以了解完成所需的技巧。 如果有一种简单的方法,那么boost::any将是一个简单的类!

你不能 C ++不会(至少不是直接)提供这种机制,不是针对void* void*没有任何信息表明计算机将需要确定它是什么,并且尝试“检查”它是否是有效的(随便播报)是不可能的,因为没有针对它的特定标志。

虽然有选择。 首先是使用某种类似于Java的Object的通用基类,并从中派生所有其他类。 现在, dynamic_cast将按照您想要的方式工作(如果对象不是将其强制转换为的类的有效对象,则返回NULL )。

另一个是简单地跟踪您自己属于哪种类型的对象。 这意味着用另一个值扩展void* ,它告诉您需要将其强制转换为什么。

但是,实际上,这些东西都不是我的好主意。 我认为您的设计中几乎有其他方面应该更改而不是使用这些方面。 使用模板,如@EdS。 建议,例如,这是一个非常好的选择。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM