網頁

2022/8/3

C++ 類別建構式成員初始化 class constructor member initialization

C++類別參數建構式初始化屬性的方式如下。


方法一 - 主體初始化

在建構式主體中將參數分派至屬性。例如下面的建構式Car(string model, int speed)在主體中將參數分派給this指向的同名屬性。

main.cpp

#include <iostream>
#include <string>
using namespace std;

class Car {
    private:
        string model;
        int speed;

    public:
        Car(string model, int speed) {
            this->model = model;
            this->speed = speed;
        }

        string GetModel() { return model; }
        int GetSpeed() { return speed; }
};

int main() {
    Car car = {"MAZDA CX-30", 1};
    cout << car.GetModel() << endl; // MAZDA CX-30
    cout << car.GetSpeed() << endl; // 1

    return 0;
}

注意若初始化的屬性型別為類別,則該類別必須提供預設建構式(無參數建構式),因為在主體初始化前會呼叫該屬性的預設建構式,若屬性的類別無預設建構式則會拋錯。

例如在Car類別新增一個屬性型別為Engine無預設建構式,則編譯時會出現錯誤 - error: constructor for 'Car' must explicitly initialize the member 'engine' which does not have a default constructor

main.cpp

#include <iostream>
#include <string>
using namespace std;

class Engine {
    private:
        string type;
        int cc;

    public:
        Engine(string type, int cc) : type(type), cc(cc) {}
        
        ...
};

class Car {
    private:
        string model;
        int speed;
        Engine engine;

    public:
        Car(string model, int speed, Engine engine ){
            this->engine = engine;
            this->speed = speed;
            this->engine = engine;
        }

        ...
};

int main() {
    Engine engine = {"4-Cylinder", 2000};
    Car car = {"MAZDA CX-30", 1, engine};

    return 0;
}


方法二 - member initializer lists

在建構式參數括弧後加上:後接屬性的建構式初始化,每個屬性建構以逗號分隔。例如下面建構式Car(string model, int speed) : model(model), speed(speed)

main.cpp

#include <iostream>
#include <string>
using namespace std;

class Car {
    private:
        string model;
        int speed;

    public:
        Car(string model, int speed) : model(model), speed(speed) {}

        ...
};

int main() {
    Car car = {"MAZDA CX-30", 1};

    return 0;
}

也可用C++11支援的統一初始化(大括弧初始化)寫法。

main.cpp

#include <iostream>
#include <string>
using namespace std;

class Car {
    private:
        string model;
        int speed;

    public:
        Car(string model, int speed) : model{model}, speed{speed} {}

        ...
};

int main() {
    Car car = {"MAZDA CX-30", 1};

    return 0;
}

此方法的初始化屬性若為類別且無預設建構式則不會出錯。

main.cpp

#include <iostream>
#include <string>
using namespace std;

class Engine {
    private:
        string type;
        int cc;

    public:
        Engine(string type, int cc) : type(type), cc(cc) {}
        
        string GetType() { return type; }
        int GetCC() { return cc; }
};

class Car {
    private:
        string model;
        int speed;
        Engine engine;

    public:
        Car(string model, int speed, Engine engine)
            : model{model}, speed{speed}, engine{engine} {}

        string GetModel() { return model; }
        int GetSpeed() { return speed; }
        string GetEngine() {
            return engine.GetType() + "-" + to_string(engine.GetCC());
        }
        void SpeedUp() { speed++; }
};

int main() {
    Engine engine = {"4-Cylinder", 2000};
    Car car = {"MAZDA CX-30", 1, engine};
    cout << car.GetModel() << endl;  // MAZDA CX-30
    cout << car.GetSpeed() << endl;  // 1
    cout << car.GetEngine() << endl; // 4-Cylinder-2000

    return 0;
}


沒有留言:

張貼留言