【c++】必須在類初始化列表中初始化的幾種情況


本文轉載自 http://www.cnblogs.com/kaituorensheng/p/3477630.html,感謝作者分享

1. 類成員為const類型

2. 類成員為引用類型

復制代碼
#include <iostream>
using namespace std;

class A
{
    public:
        A(int &v) : i(v), p(v), j(v) {}
        void print_val() { cout << "hello:" << i << "  " << j << endl;}
    private:
        const int i;
        int p;
        int &j;
};

int main(int argc ,char **argv)
{
    int pp = 45;
    A b(pp);
    b.print_val();
}
復制代碼

究其因

const對象或引用只能初始化但是不能賦值。構造函數的函數體內只能做賦值而不是初始化,因此初始化const對象或引用的唯一機會是構造函數函數體之前的初始化列表中。

從無到有叫初始化,初始化(調用拷貝構造函數)創建了新對象;賦值(調用賦值操作符)沒有創建新對象,而是對已有的對象賦值。

 

 1 #include <iostream>
 2 using namespace std;
 3 
 4 class Base
 5 {
 6     public:
 7     Base(){cout << "Base()" << endl;}
 8         Base(int a) : val(a) {cout << "Base(int a) : val(a)" << endl;}
 9     private:
10         int val;
11 };
12 
13 class A
14 {
15     public:
16         A(int v) : p(v),b(v) {cout << "A(int v) : p(v), b(v)" << endl;}
17         void print_val() { cout << "hello:" << p << endl;}
18     private:
19         int p;
20         Base b;
21 };
22 
23 int main(int argc ,char **argv)
24 {
25     int pp = 45;
26     A b(pp);
27     b.print_val();
28 }
View Code

 

 1 #include <iostream>
 2 using namespace std;
 3 
 4 class Base
 5 {
 6     public:
 7     Base(){cout << "Base()" << endl;}
 8         Base(int a) : val(a) {cout << "Base(int a) : val(a)" << endl;}
 9     private:
10         int val;
11 };
12 
13 class A : public Base
14 {
15     public:
16         A(int v) : p(v) {cout << "A(int v) : p(v), Base(v)" << endl;}
17         void print_val() { cout << "hello:" << p << endl;}
18     private:
19         int p;
20 };
21 
22 int main(int argc ,char **argv)
23 {
24     int pp = 45;
25     A b(pp);
26     b.print_val();
27 }
View Code

 

#include <iostream>
using namespace std;

class Base
{
    public:
    //Base(){cout << "Base()" << endl;}
        Base(int a) : val(a) {cout << "Base(int a) : val(a)" << endl;}
    private:
        int val;
};

class A : public Base
{
    public:
        A(int v) : p(v),Base(v) {cout << "A(int v) : p(v), Base(v)" << endl;}
        void print_val() { cout << "hello:" << p << endl;}
    private:
        int p;
};

int main(int argc ,char **argv)
{
    int pp = 45;
    A b(pp);
    b.print_val();
}
View Code

 

 

3. 類成員為沒有默認構造函數的類類型

復制代碼
#include <iostream>
using namespace std;

class Base
{
    public:
        Base(int a) : val(a) {}
    private:
        int val;
};

class A
{
    public:
        A(int v) : p(v), b(v) {}//因為Base有自定義的帶參構造函數,就不會產生無參構造函數,就無法產生類對象了
        void print_val() { cout << "hello:" << p << endl;}
    private:
        int p;
Base b; }; int main(int argc ,char **argv) { int pp = 45; A b(pp); b.print_val(); }
復制代碼

原因同樣是創建對象時,要初始類成員的每一個成員

 

4. 如果類存在繼承關系,派生類必須在其初始化列表中調用基類的構造函數

復制代碼
#include <iostream>
using namespace std;

class Base
{
    public:
        Base(int a) : val(a) {}
    private:
        int val;
};

class A : public Base
{
    public:
        A(int v) : p(v), Base(v) {}
        void print_val() { cout << "hello:" << p << endl;}
    private:
        int p;
};

int main(int argc ,char **argv)
{
    int pp = 45;
    A b(pp);
    b.print_val();
}
復制代碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM