C ++ reinterpret_cast - 这总能正常工作吗?

时间:2015-03-01 10:36:17

标签: c++ casting operator-overloading

我写了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上测试了它并且它正常工作,但我不知道它是否可以在生产代码中使用,可以使用不同的编译器进行编译。

1 个答案:

答案 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;

代替。