c++对std::shared_ptr引用的reinterpret_cast进行优化
C++ reinterpret_cast of std::shared_ptr reference to optimize
您有两个类Animal
和Dog
(其中Dog
继承自Animal
),并且您有一种情况,您经常期待一只动物,但却发送了一只狗的实例。在我的特殊情况下,我经常将强指针(std::shared_ptr<Dog>
)转换为动物期望函数(std::shared_ptr<Animal>
)。
如果我们接受我们可以使函数参数成为引用(std::shared_ptr<Animal>&
,避免参数,为什么你不应该有强指针作为引用参数,因为担心改变线程的所有权),我认为我们将是安全的内存明智的转换std::shared_ptr<Dog> dog
使用reinterpret_cast<std::shared_ptr<Animal>&>(dog)
,对吗?
如果是这样,除了线程问题还会出现什么?比如参考计数品种?
要清楚,目的是有一个解决方案,将在许多情况下使用,一次强制转换不是一个真正可行的解决方案。更重要的是,有很多对象需要被投射。此外,忽略std::unique_ptr
可能是也可能不是更好的解决方案。
添加最后一个要求-使用普通指针将不允许我在通用序列化器类函数是虚拟的情况下更改原始std::shared_ptr
,因此不能被模板化
由于不可能直接在std::shared_ptr
上使用static_cast
, const_cast
, dynamic_cast
和reinterpret_cast
来检索与作为参数传递的指针共享所有权的指针,因此应该使用std::static_pointer_cast
, std::const_pointer_cast
, std::dynamic_pointer_cast
和std::reinterpret_pointer_cast
函数。
std::reinterpret_pointer_cast
在c++ 11和c++ 14中不可用,因为它仅由N3920提出,并于2014年2月被采纳到Library Fundamentals TS中。但是,它可以这样实现:
template <typename To, typename From>
inline std::shared_ptr<To> reinterpret_pointer_cast(
std::shared_ptr<From> const & ptr) noexcept
{ return std::shared_ptr<To>(ptr, reinterpret_cast<To *>(ptr.get())); }
我经常将强指针(
std::shared_ptr<Dog>
)转换为动物期望函数(std::shared_ptr<Animal>
)。
不需要强制类型转换(即显式转换)。指向派生类型的共享指针可隐式转换(1)为指向基类的共享指针。
(a)如果我们接受可以使函数形参成为引用
如果满足一些要求,我们只能接受这个假设。首先,函数不能将引用的实参存储在函数作用域之外(复制除外)。其次,作为引用传递的指针必须是本地指针或临时指针,如果不是,则函数不得调用任何可以直接或间接访问被引用指针的函数。
还应考虑,如果引用是非const,则不能依赖隐式转换(1)。相反,必须创建一个正确类型的单独共享指针(可以使用隐式转换创建它并传递它)。const引用形参或非引用形参就没有这个问题。
(b)我认为我们将是安全的内存明智的转换std::shared_ptr狗使用
reinterpret_cast<std::shared_ptr<Animal>&>(dog)
,对吗?
标准方面,您建议的cast是不安全的-它具有未定义的行为。我不明白假设(b)是如何从假设(a)推导出来的。
如果在您的情况下使用shared_ptr的引用作为参数是可以的,但是由于转换(派生到基,非const到const),您无法避免refcounter的自增/自减,我建议使用裸指针作为参数。
- 如何理解C++标准N3337中的expr.const.cast子句8
- C++Cast运算符过载
- 错误:"cast"未命名类型void setCastDescription(std::string
- 通过使用 const-cast 的非常量引用来延长临时的寿命
- "(void) cast"与功能有什么区别 "__attributes__"来沉默未使用的参数警告?
- C++:"Expected '(' for function-style cast or type construction"错误
- 为什么选择 g++ 给予者:"error: cast to pointer from integer of different size [-Werror=int-to-pointer-cast]"
- Gtk+ g_signal_connect() 和 C++ lambda 会导致"invalid cast"错误
- Shared_ptr cast vs static_cast speed
- C++20 中的严格别名规则是否允许标准 c++ unicode 字符和下划线类型之间"reinterpret
- 在 iOS 上使用 Aruco 构建 OpenCV 时"Functional-style cast from id to double is not allowed"
- 覆盖 CAST 运算符(我认为它被称为向下转换)
- C++错误,隐 <function-style-cast> 式要求使用模板化类一次调用多个构造函数的多个转换
- 如何修复<function-style-cast>错误:无法从'initializer list'转换为asdending比较<W>(模板函子)
- C++ C++ 中的函数声明,键入 CAST
- static_cast会丢弃错误,但C风格的演员cast有效
- C++ cast char * to unsigned char
- 禁用 Clang 中的"cast from pointer to smaller type uint32_t"错误
- 是否可以使用gcc 3.3版修复与int*cast相关的Sun Solaris OS 5.8分段故障
- C++ const-cast 一个引用