假设我们有一个像这样的成员类
std::map<unsigned int, std::shared_ptr<ObscureType>> member_
我们不能用具有member
的映射替换std::shared_ptr<const ObscureType>
,因为该类必须对ObscureType
的非常量函数进行操作。
该类现在应该具有一个函数const std::map<unsigned int, std::shared_ptr<const ObscureType>& getUnderlyingMap() const
。
其他类可能将此类作为依赖项,并且必须在ObscureType
的const函数上进行操作。
我们不能简单地写
return member_
中的getUnderlyingMap()
,因为不允许这种隐式转换。
由于static_cast
和const_cast
不起作用,我选择了reinterpret_cast
。
因此方法主体为
const std::map<unsigned int, std::shared_ptr<const ObscureType>& getUnderlyingMap() const {
return reinterpret_cast<const std::map<unsigned int, std::shared_ptr<const ObscureType>&>(member_);
}
在这种情况下使用reinterpret_cast
是否安全?
有没有更好的方法来解决此问题?请注意,由于创建对象的方式(Node-V8集成),不选择不使用shared_ptr
答案 0 :(得分:3)
不,那根本不安全。
我可以想到两个选择:不用公开地图,而是公开所需的功能(较少出错,而且不太干净,并且不能使用要求std::map
的接口):>
std::shared_ptr<const ObscureType> getInUnderlyingMap(unsigned int index) const {
return member_.at(index); // Might want to return nullptr instead of throwing
}
std::size_t sizeOfUnderlyingMap() const noexcept {
return member_.size();
}
// etc.
或者您可以将member_
设为std::map<unsigned int, std::shared_ptr<const ObscureType>>
,在getUnderlyingMap
中通过const引用将其返回,并在内部使用std::const_pointer_cast
在不使用const的情况下使用它(请确保您尽管正在分配非常量指针,所以const_pointer_cast
不是UB):
private:
std::map<unsigned int, std::shared_ptr<const ObscureType>> member_;
std::shared_ptr<ObscureType> obscure_object(const std::shared_ptr<const ObscureType>& p) noexcept {
return std::const_pointer_cast<ObscureType>(p);
}
std::shared_ptr<ObscureType> obscure_object(std::shared_ptr<const ObscureType>&& p) noexcept {
return std::const_pointer_cast<ObscureType>(std::move(p));
}
void internal_method() {
obscure_object(member_[0]).non_const_method();
}
public:
const std::map<unsigned int, std::shared_ptr<const ObscureType>& getUnderlyingMap() const {
return member_;
}
答案 1 :(得分:0)
重新解释类型转换与以往一样不安全且已实现定义,您可以使用C样式的类型转换,该类型至少会向偶然的观察者伸出。由于 $( 'a[href^="#"]' ).on( 'click', function ( event ) {
var target = $( $( this ).attr( 'href' ) );
var znacznik = $( $( this ).attr( 'a' ) );
if ( target.length ) {
event.preventDefault();
$( 'html, body' ).animate( {
scrollTop: target.offset().top - 80
}, 1000 );
}
} );
和map<key, value*>
不太可能具有不同的二进制布局,因此剩下的只是用于编译时机制的类型安全检查,因此这应该在实践中起作用。
尽管要当心:
map<key, value const*>
尽管您的示例正确无误,但您一次将const添加到两个级别上可以避免进行修改。