0

這裏是我的代碼:如何實現對於具有內部放置新的(用的std :: string)類安全拷貝構造函數

struct RS_Token 
{ 
    char id; 
    char cleanup; 
    unsigned char array[sizeof (std::string) > sizeof (double) ? sizeof (std::string) : sizeof (double)]; 

    RS_Token(int a) : 
     id(a), 
     cleanup(0) 
    { 
    } 
    RS_Token(int a, const char* pstr) : // identifier or text 
     id(a), 
     cleanup(1) 
    { 
     new (array) std::basic_string<unsigned char>((unsigned char*)pstr); 
    } 
    RS_Token(int a, int b) : // integer 
     id(a), 
     cleanup(0) 
    { 
     new (array) int(b); 
    } 
    RS_Token(int a, double b) : // float (double) 
     id(a), 
     cleanup(0) 
    { 
     new (array) double(b); 
    } 

    ~RS_Token() 
    { 
     if (cleanup) 
     { 
      std::basic_string<unsigned char>* p = reinterpret_cast<std::basic_string<unsigned char>*>(array); 

      p->~basic_string(); 
     } 
    } 
}; 

如何添加一個拷貝構造函數,妥善處理的情況下任何建議,其中一個std :: string已被內部分配,將不勝感激。

+4

出了什麼問題使獨立'的std :: string'和'double'變量?您擁有的代碼將會出現[嚴重對齊問題](http://www.gotw.ca/gotw/028.htm)等等。如果你讓它們成爲獨立的成員變量,編譯器生成的拷貝構造函數將爲你做正確的事情。 –

+0

Placement-new通常會有一個'void *'的參數,所以你可以把那些乏味的演員都放在一邊。 –

+0

可能'boost :: variant '會處理這些事情。 – visitor

回答

1

我不知道那是你正在做的是在所有好的設計,但爲您解答問題,安置新:您提供的構造函數的參數,就像在任何其他new表達:

構建新的字符串:

typedef std::basic_string<unsigned char> ustring; 

RS_Token(const char* pstr) 
{ 
    void * p = static_cast<void*>(array); 
    new (p) ustring(pstr, pstr + std::strlen(pstr)); 
} 

拷貝構造:

RS_Token(const RS_Token & other) 
{ 
    void * p = static_cast<void*>(array); 
    new (p) ustring(*reinterpret_cast<const ustring *>(other.array)); 
} 

分配:

RS_Token & operator=(const RS_Token & other) 
{ 
    ustring & s = *reinterpret_cast<ustring *>(array); 
    s = *reinterpret_cast<const ustring *>(other.array); 
    return this; 
} 
+0

該副本構造函數只在另一個包含字符串時有效,賦值運算符假定_both_已經是一個字符串。他們需要比這更復雜一點。 –

+0

@Moo:啊,是的,這裏需要添加大量的變體邏輯。但答案涉及處理安置建設,所以我希望OP可以將其整合到她的班級代碼中。 –

+0

呃,夠了。你得到了所有困難的部分。其餘的應該是相當明顯的。 –

相關問題