2014-10-02 60 views
0

我很努力爲包含指針數組的結構寫(我的第一個)交換函數。寫交換函數的問題

struct Foo 
{ 
    unsigned int Count; 
    int* Items; 

    Foo() 
    { 
     Count = 0; 
     Items = 0; 
    } 

    Foo(const Foo& foo) 
    { 
     Items = 0; 
     swap(foo); // cannot convert argument 1 from 'const Foo' to 'Foo *' 
    } 

    Foo(const unsigned int itemCount) 
    { 
     Count = itemCount; 
     Items = new int[itemCount]; 
     for (int i = 0; i < itemCount; i++) 
     { 
      Items[i] = 123; 
     } 
    } 

    Foo& operator=(const Foo& foo) 
    { 
     swap(foo); // cannot convert argument 1 from 'const Foo' to 'Foo *' 

     return *this; 
    } 

    void swap(Foo* foo) 
    { 
     unsigned int a(Count); 
     int* b(Items); 

     Count = foo->Count; 
     Items = foo->Items; 

     foo->Count = a; 
     foo->Items = b; 
    } 

    ~Foo() 
    { 
     delete[] Items; 
    } 
}; 
  1. 誰能請幫助我的語法?

  2. 我這樣做的原因是爲了幫助我理解這可以如何與指針數組一起工作?

  3. 我已經在線閱讀,它是異常安全的,因爲它不分配新的內存來做到這一點?當然,ab都分配了內存,如果內存不可用,因此可能會失敗?

編輯: 基於由lucacox答案...

void swap(Foo* foo1, Foo* foo2) 
{ 
    unsigned int a(foo1->Count); 
    int* b(foo1->Items); 

    foo1->Count = foo2->Count; 
    foo1->Items = foo2->Items; 

    foo2->Count = a; 
    foo2->Items = b; 
} 

這樣調用...

swap(&foo, this); // cannot convert argument 1 from 'const Foo' to 'Foo *' 

我仍然得到一個const轉換錯誤?

+0

任何特定的原因,你不使用'std :: vector '? – Biffen 2014-10-02 12:31:25

+0

是的。這是交換理論的練習。 – Beakie 2014-10-02 12:32:03

+0

@Beakie [三條法則是什麼?](https://stackoverflow.com/questions/4172722/what-is-the-rule-of-ree) – 2014-10-02 12:33:35

回答

1

你不能改變一個常量對象。因此,您可能不會將成員函數swap應用於複製構造函數中的Foo類型對象的常量引用。此外,將它與您的類的複製構造函數一起使用是沒有意義的。替換這個拷貝構造函數

Foo(const Foo& foo) 
{ 
    Items = 0; 
    swap(foo); // cannot convert argument 1 from 'const Foo' to 'Foo *' 
} 

這兩個(一個是沒有交換等一個拷貝構造函數是移動的構造與互換)

Foo(const Foo& foo) : Count(foo.Count) 
{ 
    Items = new int[Count]; 
    std::memcpy(Items, foo.Items, Count * sizeof(int)); 
    // std::copy(foo.Items, foo.Items + foo.Count, Items); 
} 

Foo(Foo&& foo) : Count(0), Items(0) 
{ 
    swap(foo); 
} 

同樣的操作做拷貝賦值操作符是您應該在不使用swap的情況下定義複製賦值運算符,並使用swap定義運算賦值運算符。

只有成員函數swap應被聲明爲void swap(Foo &)

-1

該錯誤是由不同的參數聲明引起:

Foo& operator(const Foo& foo) 

聲明參數FOO作爲一個const(未modificable)參照Foo對象。而

void swap(Foo* foo) 

將參數foo聲明爲指向Foo對象的指針。

您不能將const Foo &轉換爲Foo *,它們是不同的類型。

我建議通過將其富*實現交換功能:

void swap(Foo* foo1) { 
    int count = this->Count; 
    int* items = this->Items; 

    this->Count = foo1->Count; 
    this->Items = foo1->Items; 

    foo1->Count = count; 
    foo1->Items = items; 
} 
+1

這是如何解決這個事實,我的Foo是一個常量? – Beakie 2014-10-02 12:42:21

+0

您不使用operator =,而是使用foo-> swap(foo1) – Lucacox 2014-10-02 12:45:36

+0

此答案不解決任何問題。 – leemes 2014-10-02 12:46:58

0

美孚&運算符=(const的富&富) 需要FOO的常量性 之間的衝突, 和交換,實際上修改它的參數是基本的一個在C++中。它甚至引起語言標準的變化,其中包括「右值」和「移動構造函數」。谷歌「C++移動語義」以獲得更多解釋。