十八、初始化列表的使用
阿新 • • 發佈:2018-09-25
空間 vat 無法 正在 直接 出現 對象創建 意義 c++ 1、類中定義
1、類中定義const
成員,及其初始化
#include <stdio.h>
class Test
{
private:
const int ci; // 編譯通過,類中可以用const來修飾
public:
int getCI()
{
return ci;
}
};
int main()
{
Test t; // 定義t對象的時候,報錯說ci沒有初始化
printf("t.ci = %d\n", t.getCI());
return 0;
}
如何初始化類裏面的
const
成員?
首先考慮構造函數初始化
class Test
{
private:
const int ci; // 得到的是只讀變量,不能作為左值
// 初始化必須在這裏進行
public:
Test()
{
ci = 10; // ci是只讀成員變量,不能修改,報錯
}
int getCI()
{
return ci;
}
}
於是出現了初始化列表
C++中提供了初始化列表對成員變量進行初始化
語法規則:
// 構造函數 // 初始化列表在構造函數的地方使用 // 在構造函數的定義之後,函數體之前,加 :號,初始化列表對成員變量進行初始化 // 用v1對m1進行初始化,用v1,v2對m2進行初始化,用v3對m3進行初始化 ClassName::ClassName() : m1(v1), m2(v1,v2), m3(v3) {}
通過初始化列表對ci 進行初始化
class Test
{
private:
const int ci;
public:
Test():ci(10) // 編譯通過,用初始化列表的方式初始化了const只讀成員變量,初始化之後,還是可以通過指針的方式修改這個值,只是ci不能做左值
{
// ci = 10;
}
int getCI()
{
return ci;
}
};
類成員的初始化, 註意事項:
- 成員的初始化順序與成員的申明順序相同
- 成員的初始化順序與初始化列表中的位置無關
- 初始化列表先於構造函數的函數體執行
// 初始化順序和初始化列表無關,和聲明順序相同
ClassName::ClassName() : m1(v1), m2(v1,v2), m3(v3)
{}
構造函數是在對象創建完成之後,再調用構造函數進行成員變量的初始化,其實是一個成員變量的賦值函數,並非真正意義上的初始化
初始化列表則是在對象創建的同時就對對象進行了初始化,順序先於構造函數函數體
區別類似於變量的初始化和賦值
int a = 1; // 類似於初始化列表
int a;
a = 1; // 類似於構造函數
#include <stdio.h>
class Value
{
private:
int mi;
public:
Value(int i)
{
printf("i = %d\n", i);
mi = i;
}
int getI()
{
return mi;
}
};
class Test
{
private:
Value m2; // Value 類創建的對象,帶了1個參數
// Value m2(2); // err
Value m3;
Value m1;
public:
Test() : m1(1), m2(2), m3(3) // 使用初始化列表來進行初始化
{
printf("Test::Test()\n");
}
};
int main()
{
Test t; // 打印列表是 2 3 1 , 順序按照成員變量聲明順序
return 0;
}
類中的const
成員
- 類中的
const
成員會被分配空間 - 類中的
const
成員本質是只讀變量 - 類中的
const
成員只能在初始化列表中制定初始值
編譯器無法直接得到
const
成員的初始值,因此無法進入符號表成為真正意義上的常量。
const
成員分配的空間的位置和當前對象一樣,對象在棧區,const
成員就在棧區
#include <stdio.h>
class Value
{
private:
int mi;
public:
Value(int i)
{
printf("i = %d\n", i);
mi = i;
}
int getI()
{
return mi;
}
};
class Test
{
private:
const int ci;
Value m2;
Value m3;
Value m1;
public:
Test() : m1(1), m2(2), m3(3), ci(100)
{
printf("Test::Test()\n");
}
int getCI()
{
return ci;
}
int setCI(int v)
{
int *p = const_cast<int *>(&ci); // 用指針改變const成員變量的值
*p = v;
}
};
int main()
{
Test t;
printf("t.ci = %d\n", t.getCI());
t.setCI(10);
printf("t.ci = %d\n", t.getCI());
return 0;
}
初始化與賦值的區別:
初始化:對正在創建的對象進行初始值設置
賦值:對已經存在的對象進行值設置
2、小結
類中可以使用初始化裏列表對成員進行初始化
初始化列表先於構造函數體進行
類中可以定義
const
成員變量
const
成員變量必須在初始化列表中指定初值
const
成員變量為只讀變量
十八、初始化列表的使用