0
#include <iostream> 

class Bar 
{ 
    protected: 

public: 
     int & x; 
     Bar(int & new_x) 
     :x(new_x) 
     {} 
     Bar & operator = (const Bar toCopy) 
     { 
      x = toCopy.x; 
      return *this; 
     } 
}; 

int main() 
{ 
    int x1(1); 
    int x2(2); 

    Bar bar = Bar(x1); 
    std::cout << bar.x << std::endl; 

    bar = Bar(x2); 
    std::cout << bar.x << std::endl; 

    bar.x = 5; 
    std::cout << bar.x << std::endl; 

    std::cout << x1 << std::endl; 
    std::cout << x2 << std::endl; 

} 

輸出是:寫作`運營商=`非靜態基準部件類

1 
2 
5 
5 
2 

我所試圖做的是副本x和對象bar內保存。

輸出表明,賦值運算符沒有完成它的魔術,無論是在複製方面,並採取新對象的值。我遵循this link

x更改爲值而不是參考是不可能的,因爲在真正的程序x是一個抽象類。

如果可能,請放棄使用堆分配。

編輯: 1.我意識到我只是屠殺了C++語言。我想向所有「C++ ian」講電腦道歉。我的動機是在堆棧上分配一個成員抽象變量。據我所知,它不能在堆棧上完成,因爲派生類的大小在編譯時並不知道。 2.好的...我總共是100B ...(不,謝謝,Sherlock!)。 「有效的C++編程」@rhalbersma是必須的。它包含必需品,但你不會在任何地方找到它們(複製構造,複製初始化),..在任何地方。

+3

公共參考數據,通過非const引用或const值傳遞參數:您可能會開始閱讀Effective C++或類似的函數,以使您的基本類成員正確。 – TemplateRex

+0

我從不使用引用作爲成員,我用指針代替,你仍然可以做所有事情(例如用&new_x初始化指針)等等。有些人喜歡引用作爲成員,因爲他們受到的限制很多... –

回答

1

參考文獻可能會引起混淆。那麼可以用const指針。我會盡量通過同時談論他們兩個來解決問題。我能說什麼,我是一個樂觀主義者。

首先,const指針。

我們將從一個名爲Foo的類開始。我們可以有一個指向這個類的指針 - 一個Foo*。我們可以有一個指向這個類的const實例的指針 - 一個Foo const*。並且我們可以有一個const指針指向此類的非const實例 - Foo*const

A Foo const*是一個指針,你可以更改爲你無法更改的數據。

A Foo*const是一個指針,你不能改變你的數據你可以改變。

我假設你明白了。畢竟,我是一個樂觀主義者。接下來,讓我們看看參考。

雖然引用是別名的確如此,但有時候在世界上有其他類型的具體實現的世界中思考它們是有幫助的。

A Foo&類似於Foo*const - 您可以更改Foo實例的不可更改「指針」。所以你所說的Foo總是一樣的,但你可以改變它的狀態。

現在,它有點多了。有一些語法糖。當您創建對另一個變量的引用時,它會自動執行& - 因此,當您執行Foo& f = a;時,這與Foo*const f = &a;類似。

其次,當您使用.時,它與指針案例中的->一樣。 (對於(大多數?)其他操作員也是如此)

第三,當您進行賦值時,顯然不能更改指針的值 - 因爲它是const - 但它改變了指向的值的值。所以Foo& f = a; a = b;做了相當於Foo*const f = &a; *f = b;

當您使用operator=時,它將指定的東西指向而不是指針。但是,當初始化它時,即使您有一個=令牌,它也不會使用operator=

初始化與一般的賦值並不相同,在初始化和賦值時&引用和*指針發生的語義有很大不同。

Foo& f = a; f = b;做了兩件完全不同的事情。參考的初始化會初始化「const指針」部分 - 分配給參考會修改指向的東西

我的個人名稱是關於初始化和賦值如何引用不同的東西,而是「引用語義」,而不是「指針語義」,其中初始化和賦值都會改變指向的東西。在「引用語義」中,初始化選擇指向什麼東西,並且賦值會改變指向的東西的狀態。

這是非常令人困惑的,我希望我以另一種方式讓它變得困惑。

3

Bar bar = Bar(x1);不是賦值,而是複製初始化。它調用複製構造函數,而不是複製賦值運算符。

雖然問題是你不明白引用 - 成員Bar::x只是另一個變量的別名。分配一些東西也會修改原來的東西。

+0

引用不是我的第一選擇,但我需要解決這個事實,即在我真正的程序中x是抽象類型 – aiao

+3

@aiao使用智能指針那麼,不是一個參考。 –

0

x內部bar同一變量作爲一個在main稱爲「X1」。
這就是參考文獻所做的 - 他們採取一個變量,並給它另一個名稱,你可以用它來引用它。
無論你在這個新名字下對該變量所做的操作與以其他任何名稱操作變量相同。

首先,

Bar bar = Bar(x1); 

後(這是複製的初始化,而不是分配)
「bar.x」指的是相同的變量如在右手側上的「X」匿名對象的內部,這反過來又是主要的「x1」的不同名稱。

在此之後,名稱「bar.x」指的是與名稱「x1」相同的變量。

bar = Bar(x2); 

分配值(即,2)的匿名對象的x,這是相同的變量作爲x2,給變量被稱爲「X」內bar,但其名稱在main中爲「x1」。

bar.x = 5; 

然後將值5分配給其名稱是「bar.x」這又是相同的變量作爲主「X1」的變量中。

你不能讓它指向一個不同的變量。
如果你想要引用不同變量的東西,你必須使用一個指針。