DEV Community

Cover image for C++ 中呼叫不具參數的建構函式為什麼不能加圓括號?
codemee
codemee

Posted on

C++ 中呼叫不具參數的建構函式為什麼不能加圓括號?

在 C++ 中建立物件時, 如果是要使用預設的建構函式或是不具參數的建構函式時, 不能在變數名稱後面加上圓括號, 例如:

class MyClass {
public:
    int i;

    MyClass() {
        // 預設 (不含參數) 的建構函式
    }
};

int main() {
    MyClass obj; // 正確
    obj.i = 10;
    return 0;
}
Enter fullscreen mode Exit fullscreen mode

如果寫成以下這樣:

class MyClass {
public:
    int i;

    MyClass() {
        // 預設 (不含參數) 的建構函式
    }
};

int main() {
    MyClass obj(); // 語法正確
    obj.i = 10;    // 這裡會出錯
    return 0;
}
Enter fullscreen mode Exit fullscreen mode

就會出現編譯錯誤:

C:\Users\meebo\code\cpp\test.cpp: In function 'int main()':
C:\Users\meebo\code\cpp\test.cpp:12:9: error: request for member 'i' in 'obj', which is of non-class type 'MyClass()'
   12 |     obj.i = 10;
      |         ^
Enter fullscreen mode Exit fullscreen mode

它的意思是 obj 並不是類別型態的變數, 所以無法讀取成員。你可能會覺得很奇怪, 但這是因為以下這一行:

    MyClass obj(); // 語法正確
Enter fullscreen mode Exit fullscreen mode

被編譯器解釋為宣告一個名稱為 obj、沒有參數, 且傳回值是 MyClass 類別物件的函式, 因此錯誤訊息中可以看到它認為 objMyClass() 型別, 也就是傳回 MyClass 類別物件, 沒有引數的函式, 函式當然就無法讀取成員。

對於 C++ 編譯器來說, 雖然同一行程式也可看成是要透過沒有參數的建構函式建立物件, 但它只能選擇其中一種解譯方式。如果把這一行當成是透過沒有引數的建構函式建立物件, 那實際上是要宣告一個沒有引數的函式時, 編譯器就無法正確判斷出來了。為了解決這個問題, 因此 C++ 的語法規定在呼叫沒有引數的建構函式時, 不能加上呼叫語法的圓括號, 否則就會視為是要宣告一個沒有引數的函式。

Top comments (0)