我写了MyString和MyStringConst类。现在我需要不时地将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上测试了它并且它正常工作,但我不知道它是否可以在生产代码中使用,可以使用不同的编译器进行编译。
答案 0 :(得分:2)
数据成员的公共初始序列是不同的,在这种情况下,C ++根本不保证布局,即使类型仅通过const
限定也不同。否则union
s的保证将有效地暗示如果类型是标准布局类型,则需要具有共同布局(根据9.5 [class.union]第1段中的注释)。
在实践中,我希望这两种类型的布局完全相同,reinterpret_cast
可以正常工作,但标准无法保证。根据你的评论MyStringConst
只保存一个指向字符串的指针,即不是转换为引用,而是返回一个适当构造的MyStringConst
并避免依赖于未定义的行为:
MyString::operator MyStringConst() const {
return MyStringConst(str, length);
}
MyString
对象仍然必须与转化结果一样长,但这与使用reinterpret_cast
的情况没有区别。
顺便说一句,volatile
上的hashCode
是不明智的:它唯一的影响就是减慢程序的速度。我猜你试图用它来实现线程之间的同步,但是在C ++中volatile
根本没有帮助:当你在一个线程中编写成员时,你得到一个数据竞争,它也被访问为非同步另一个线程。你拼写会员
std::atomic<int> hashCode;
代替。