原文鏈接:https://www.zhoubotong.site/post/87.html
之所以寫這篇文章,是覺得里面有些細節如果不注意,很容易出錯或踩坑,網上有很多教程對這塊的描述部分存在錯誤,希望下面的介紹能給大家帶來幫助,
大家知道當我們需要初始化類中的成員變數時,除了可以直接在建構式里面進行直接賦值,還可以使用初始化串列的方式來對成員變數進行初始化,
提到這里,順便說下什么是建構式初始化串列,
C++初始化串列
語法
Contructor(type1 var1, type2 var2): m_var1(var1), m_var2(var2)
{
}
引數
| 屬性 | 描述 |
|---|---|
| type1 | 形參 var1 的型別, |
| var1 | 形參 var1, |
| type2 | 形參 var2 的型別, |
| var2 | 形參 var2, |
| m_var1 | 成員變數 m_var1, |
| m_var2 | 成員變數 m_var2, |
說明
我們使用初始化串列的方式,用形參 var1 初始化了成員變數 m_var1,用形參 var2 初始化了成員變數 m_var2,舉個例子:
#include <iostream>
using namespace std;
class Student {
private:
char *m_name;
int m_age;
float m_score;
public:
Student(char *name, int age, float score);
void show();
};
// 采用初始化串列
Student::Student(char *name, int age, float score)
: m_name(name), m_age(age), m_score(score) {
// TODO
}
void Student::show() {
cout << m_name << " age is " << m_age << "score is " << m_score << endl;
}
int main() {
Student stu((char *)"鳩摩智", 28, 5);
stu.show();
Student *pstu =
new Student((char *)"慕容復", 27, 86); // 使用指標物件 new 實體化
pstu->show();
return 0;
}
上面的例子定義建構式時并沒有在函式體中對成員變數賦值,而是在函式首部與函式體之間添加了一個冒號:,后面緊跟m_name(name), m_age(age), m_score(score)陳述句,
可以理解成相當于函式體內部的m_name = name; m_age = age; m_score = score;也是賦值的意思,
注意:使用建構式初始化串列并沒有效率上的優勢,僅僅是書寫方便,當成員變數較多時這種寫法非常簡潔,
下面重點說下需要注意的地方:
初始化串列可以用于全部成員變數,也可以只用于部分成員變數,什么意思?比如我們只對 m_name 使用初始化串列,其他成員變數還是=賦值:
// 采用初始化串列
Student::Student(char *name, int age, float score)
: m_name(name) { // 只用于部分成員變數
m_age = age;
m_score = score;
}
輸出結果是一樣的, 注意!注意!注意!,成員變數的初始化順序與初始化串列中列出的變數的順序無關,它只與成員變數在類中宣告的順序有關,
請大家仔細看下面的代碼:
#include <iostream>
using namespace std;
class Student {
private:
int m_age;
float m_score;
public:
Student(float s);
void show();
};
Student::Student(float s) : m_score(s), m_age(m_score) {} //注意這里:我們將m_score放在了m_age的前面,看起來是先給m_score賦值,再給m_age賦值(m_age=m_score),其實不是的
void Student::show() { cout << m_age << ", " << m_score << endl; }
int main() {
Student stu(99);
stu.show();
return 0;
}
結論
所以成員變數的賦值順序由它們在類中的宣告順序決定,在 上面的Student 類中,我們先宣告的 m_age,再宣告的 m_score,
給 m_age 賦值時,m_score 還未被初始化,所以輸出的m_age的值是默認型別的0;給 m_age 賦值完成后才給m_score 賦值,此時 m_score 的值才是99,
如果大家對上面理解了,我們再看下面的代碼,大家可以猜下輸出啥?
#include <iostream>
using namespace std;
class Student {
private:
int m_age;
float m_score;
public:
Student(float s);
void show();
};
Student::Student(float s) : m_score(s), m_age(m_score) {
m_age = m_score;
m_score = s;
}
void Student::show() { cout << m_age << ", " << m_score << endl; }
int main() {
Student stu(99);
stu.show();
return 0;
}
輸出:99, 99,大家請細品!寫到最后再提下:建構式初始化串列還有一個很重要的作用,那就是初始化 const 成員變數,
網上很多教程說初始化 const 成員變數的唯一方法就是使用初始化串列,這是錯誤的,描述的不夠嚴謹,為什么這樣說,我們來看網上很多教程的例子:
#include <iostream>
using namespace std;
class Student {
public:
Student(string name, int age) {
m_name = name;
m_age = age;
}
void show();
private:
const string m_name;
int m_age;
};
void Student::show() { cout << m_name << ", " << m_age << endl; }
int main() {
Student stu("鳩摩智", 28);
stu.show();
Student stu1("慕容復", 27);
stushow();
return 0;
}
輸出:
于是網上很多教程說只能使用初始化串列的方式,來進行初始化,現在,按照網上的說法修改程式如下:
#include <iostream>
using namespace std;
class Student {
public:
Student(string name, int age) : m_name(name), m_age(age) {}
void show();
private:
const string m_name;
int m_age;
};
void Student::show() { cout << m_name << ", " << m_age << endl; }
int main() {
Student stu("鳩摩智", 28);
stu.show();
Student stu1("慕容復", 27);
stushow();
return 0;
}
這次在建構式上面,使用了初始化串列的方式,初始化了 const 成員變數,這次程式沒有報錯,因此,const 成員變數只可以使用初始化串列的方式進行初始化( 誤人),
這個描述是錯誤的,并不是 const 成員變數只能使用初始化串列,在建構式里面初始化賦值是沒有任何問題的,
針對上面的問題我們來改下代碼,注意這里只是改變了m_name的資料型別為指標型,
#include <iostream>
using namespace std;
class Student {
public:
Student(char *name, int age) { // 使用構造方法初始化賦值
m_name = name;
m_age = age;
}
void show();
private:
const char *m_name; // 注意這里是指標變數的常量
int m_age;
};
void Student::show() { cout << m_name << ", " << m_age << endl; }
int main() {
Student stu((char *)"鳩摩智", 28);
stu.show();
Student stu1((char *)"慕容復", 27);
stushow();
return 0;
}
無論從事什么行業,只要做好兩件事就夠了,一個是你的專業、一個是你的人品,專業決定了你的存在,人品決定了你的人脈,剩下的就是堅持,用善良專業和真誠贏取更多的信任,所以類中對于 const 修飾,既可以使用初始化串列的方式賦值,也可以使用建構式的方式賦值,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/527999.html
標籤:其他





