簡體   English   中英

在C ++中復制類似的類

[英]Copying similar classes in C++

我有兩個結構相似的課程。

class A{
    int a;
    char *b;
    float c;
    A(char *str) { //allocate mem and assign to b }
};

class B{
    int a;
    char *b;
    float c;
    B(char *str) { //allocate mem and assign to b }
    B(B & bref) { //properly copies all the data }
};

我想將B的對象復制到A的對象。 以下轉換可以嗎?

A aobj("aobjstr");
B bobj("bobjstr");
bobj = aobj;    //case 1
bobj = B(aobj); //case 2

案例2會奏效嗎? 當調用B的副本構造函數時, aobj可以正確轉換並解釋為B &

編輯 :那呢?

B bobj(aobj)

不,如果不編寫轉換構造函數或轉換運算符,就無法在不相關的類型之間隱式轉換。 大概是您的編譯器告訴您的。 我的錯誤如下:

error: no match for ‘operator=’ in ‘bobj = aobj’
note:  no known conversion for argument 1 from ‘A’ to ‘const B&’
error: no matching function for call to ‘B::B(A&)’

您可以通過給B一個轉換構造函數來允許轉換:

class B {
    // ...
    B(A const & a) { /* properly copy the data */ }
};

如果您不能更改類,則將需要一個非成員函數來進行轉換。 但這只有在班級成員是公開的情況下才有可能。 在您的示例中,所有成員(包括構造函數)都是私有的,因此根本無法使用這些類。 據推測,在您的實際代碼中情況並非如此。

如果您想過着危險的生活,則可以通過將A對象顯式重新解釋為B來擺脫困境,因為它們都是具有相同數據成員的標准布局類型:

// DANGER: this will break if the layout of either class changes
bobj = reinterpret_cast<B const &>(a);

注意,由於您的類分配了內存,因此大概需要在其析構函數中對其進行分配。 為了避免重復刪除,您還必須按照“三規則”正確實現復制構造函數和復制分配運算符。

如果聽起來一切都太麻煩了,為什么不使用std::string ,它可以為您管理內存呢?

如果您嘗試對其進行編譯,您會發現這些都不起作用。 一方面,您的構造函數是private

bobj = aobj;    //case 1

這嘗試使用簽名來調用賦值運算符:

B& B::operator =(A const&)

這不存在,編譯將失敗。

bobj = B(aobj); //case 2

這將嘗試調用A::operator B() ,該命令不存在,並且編譯將失敗。

最后:

B bobj(aobj)

這將嘗試使用簽名B::B(A const&)調用構造函數,該簽名不存在,並且編譯將失敗。

你說,

我不能更改/修改類A和B,它們是生成的。

然后要么需要修復生成器,要么必須編寫自己的適配器。

您可以考慮以下注意事項:

1) char* b出了問題。 當您將aobj復制到bobj時,指針aobj.b的值將被復制到bobj.b ,這意味着它們都指向相同的內存位置,並且像這樣更改一個位置: aobj.b[0] = 'Z'將導致bobj.b進行更改。

您可以通過將b從指針更改為平面數組來解決此問題:

//...
char b[MAXLEN];
//...

對此的更好解決方案是定義一個構造函數(接受其他類型),並至少對類B重載賦值(=)運算符,並處理指針賦值(為新指針分配緩沖區並向其復制內容)。

2)更新:示例語法如下:

   bobj = B(reinterpret_cast<B&> (aobj));

   // or simply:
   bobj = reinterpret_cast<B&> (aobj);

3)請注意,這很危險,不安全,因此不建議這樣做。 這意味着您的解決方案的設計可能應該更改。 例如,A和B都可以從公共基類繼承; B從A繼承; 或B顯式定義了類A的構造函數和賦值運算符。強烈建議使用它們。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM