類中有引用需要注意——非靜態的引用成員錯誤提示,不能使用預設的賦值運算子
我們知道,當我們我們沒有定義賦值操作符時,編譯器會生成一個預設的賦值操作符執行淺拷貝,就像預設建構函式一樣是編譯器預設生成的。而如果勒種有引用就需要注意一個大大的誤區。我們知道引用在定義的時候就需要初始化,指定這個引用變數是哪個變數的別名,否則就會報錯。當一個類中使用了引用但沒有定義賦值操作符,會導致什麼問題呢?
#include<iostream>
using namespace std;
class Test
{
int x;
int &ref;
public:
Test (int i):x(i), ref(x) {} //有參構造,引用看似是賦初始值了
void print() { cout << ref; }
void setX(int i) { x = i; }
};
int main()
{
Test t1(10);
Test t2(20);
t2 = t1;
t1.setX(40);
t2.print();
return 0;
}
上面的程式會編譯報錯:
Compiler Error: non-static reference member 'int& Test::ref', can't use default assignment operator
意思就是非靜態的引用成員,’int& Test::ref’,不能使用預設的賦值運算子。
那麼這裡為什麼不能使用預設的賦值運算子呢?其實C++中是有規定的,在下面的這些情況下,編譯器不會自動建立預設賦值操作符:
1. 類中包含const或volatile型別的非靜態資料成員
2. 類中包含一個非靜態的資料成員,並且其型別是不能賦值的(例如引用)。
3. 被繼承的基類中不能使用賦值操作符(例如基類中包含引用型別的成員)。
只要上面的某個條件成立,則使用者必須自定義賦值操作符。所以我們需要修改上面的程式,增加一個賦值運算子的過載就可以了。
#include<iostream>
using namespace std;
class Test
{
int x;
int &ref;
public:
Test (int i):x(i), ref(x) {} //有了賦值運算子才可以直接賦值
void print() { cout << ref; }
void setX(int i) { x = i; }
Test &operator = (const Test &t) { x = t.x; return *this; } // 過載賦值運算子
};
int main()
{
Test t1(10);
Test t2(20);
t2 = t1;
t1.setX(40);
t2.print();
return 0;
}
輸出: 10
相關文章
- java 非靜態內部類與外部類引用之間的關係Java
- 運算子-賦值運算子賦值
- Java的靜態成員類Java
- 注意!非靜態內部類和非靜態方法的匿名類的this$0屬性
- c#物件導向- 靜態成員和非靜態成員的區別C#物件
- vue中 靜態檔案引用注意事項Vue
- c++類的靜態成員C++
- C++:類的靜態成員C++
- C++ 類的靜態成員C++
- #### 使用方法引用的使用場景--通過物件名引用成員方法物件
- 常被新手忽略的值賦值和引用賦值(偏redux向)賦值Redux
- php之普通變數賦值、物件賦值、引用賦值的區別PHP變數賦值物件
- 類內的靜態成員函式函式
- C++類中的常成員和靜態成員C++
- php函式的傳值如果需要引用傳遞注意的細節PHP函式
- 使用 foreach 使用引用變數需要注意的問題變數
- Mybatis出現成員賦值都是null或者預設值MyBatis賦值Null
- 賦值運算子(轉)賦值
- Effective Java 3rd 條目24 靜態成員類優於非靜態Java
- C++類靜態成員C++
- 第九章:過載賦值運算子中需要注意的兩個問題賦值
- If-Let 賦值運算子賦值
- 8.Golang中的運算子-算術運算子、關係運算子、邏輯運算子、賦值運算子Golang賦值
- 使用 ref 引用值
- JAVA 物件引用,以及物件賦值Java物件賦值
- 給物件引用變數賦值(轉)物件變數賦值
- PHP 物件導向 (四)類物件賦值為引用傳遞PHP物件賦值
- Python的靜態方法和類成員方法Python
- Javascript需要注意的幾個運算子JavaScript
- oop類的繼承與類靜態成員學習OOP繼承
- c# 非靜態欄位、方法或屬性要求物件引用C#物件
- Python中的包模組引用成員的方法Python
- JavaScript 等號 = 賦值運算子JavaScript賦值
- 1:賦值運算子函式賦值函式
- 按位“或”賦值運算子 (|=)賦值
- 問題分享:Js引用型別賦值JS型別賦值
- 深入理解PHP中賦值與引用PHP賦值
- 靜態資料成員和靜態成員函式函式