C++ reinterpret_cast - 这总是能正常工作吗?
C++ reinterpret_cast - will this always work correctly?
我写了 MyString 和 MyStringConst class。现在我需要不时地将 MyString 作为 MyStringConst 传递,因此重载强制转换运算符。我写了这个
MyString::operator const MyStringConst &() const
{
return reinterpret_cast<const MyStringConst &>(*this);
}
MyString 有这个数据
char * str;
int length;
volatile int hashCode;
int bufferSize;
MyStringConst 有这个数据
const char * c_str;
int length;
volatile int hashCode;
此外还有一些方法,可以在两个字符串中重新计算hashCode。
这段代码写对了吗?我已经在 MSVC 2013 上测试过它并且它工作正常,但我不知道它是否可以用于生产代码,可以用不同的编译器编译。
数据成员的公共初始序列不同,C++ 根本不保证这种情况下的布局,即使类型仅在 const
条件上有所不同。否则,union
s 的保证将有效地暗示如果类型是标准布局类型,则它们需要具有通用布局(根据 9.5 [class.union] 第 1 段中的注释)。
在实践中,我希望这两种类型的布局相同并且 reinterpret_cast
可以工作,但标准不能保证。根据您的评论 MyStringConst
仅包含指向字符串的指针,即,我不会转换为引用,而是 return 适当构造的 MyStringConst
并避免依赖未定义的行为:
MyString::operator MyStringConst() const {
return MyStringConst(str, length);
}
MyString
对象仍然必须与转换结果一样长,但这与使用 reinterpret_cast
的情况没有什么不同。
顺便说一句,hashCode
上的 volatile
是不明智的:它唯一的效果就是减慢程序速度。我猜你正试图用它来实现线程之间的同步,但在 C++ 中 volatile
根本没有帮助:在一个线程中写入成员时你会发生数据竞争,它也会在另一个线程中被不同步地访问.你会拼写成员
std::atomic<int> hashCode;
相反。
我写了 MyString 和 MyStringConst class。现在我需要不时地将 MyString 作为 MyStringConst 传递,因此重载强制转换运算符。我写了这个
MyString::operator const MyStringConst &() const
{
return reinterpret_cast<const MyStringConst &>(*this);
}
MyString 有这个数据
char * str;
int length;
volatile int hashCode;
int bufferSize;
MyStringConst 有这个数据
const char * c_str;
int length;
volatile int hashCode;
此外还有一些方法,可以在两个字符串中重新计算hashCode。
这段代码写对了吗?我已经在 MSVC 2013 上测试过它并且它工作正常,但我不知道它是否可以用于生产代码,可以用不同的编译器编译。
数据成员的公共初始序列不同,C++ 根本不保证这种情况下的布局,即使类型仅在 const
条件上有所不同。否则,union
s 的保证将有效地暗示如果类型是标准布局类型,则它们需要具有通用布局(根据 9.5 [class.union] 第 1 段中的注释)。
在实践中,我希望这两种类型的布局相同并且 reinterpret_cast
可以工作,但标准不能保证。根据您的评论 MyStringConst
仅包含指向字符串的指针,即,我不会转换为引用,而是 return 适当构造的 MyStringConst
并避免依赖未定义的行为:
MyString::operator MyStringConst() const {
return MyStringConst(str, length);
}
MyString
对象仍然必须与转换结果一样长,但这与使用 reinterpret_cast
的情况没有什么不同。
顺便说一句,hashCode
上的 volatile
是不明智的:它唯一的效果就是减慢程序速度。我猜你正试图用它来实现线程之间的同步,但在 C++ 中 volatile
根本没有帮助:在一个线程中写入成员时你会发生数据竞争,它也会在另一个线程中被不同步地访问.你会拼写成员
std::atomic<int> hashCode;
相反。