簡體   English   中英

使用參數化構造函數時沒有編譯錯誤

[英]Absence of compilation error when using parametrized constructor

今天在工作中我遇到了一個我不懂的C ++行為。 我已經生成了以下示例代碼來說明我的問題:

#include <string>
#include <iostream>

class MyException
{
    public:
        MyException(std::string s1) {std::cout << "MyException constructor, s1: " << s1 << std::endl;}
};

int main(){
    const char * text = "exception text";
    std::cout << "Creating MyException object using std::string(const char *)." << std::endl;
    MyException my_ex(std::string(text));
    std::cout << "MyException object created." << std::endl;
    //throw my_ex;

    std::string string_text("exception text");
    std::cout << "Creating MyException object using std::string." << std::endl;
    MyException my_ex2(string_text);
    std::cout << "MyException object created." << std::endl;
    // throw my_ex2;

    return 0;
}

此代碼段編譯時沒有任何錯誤,並產生以下輸出:

 $ g++ main.cpp
 $ ./a.out
Creating MyException object using std::string(const char *).
MyException object created.
Creating MyException object using std::string.
MyException constructor, s1: exception text
MyException object created.

請注意,對於my_ex ,我沒有調用我定義的構造函數。 接下來,如果我想實際拋出這個變量:

throw my_ex;

我收到編譯錯誤:

 $ g++ main.cpp
/tmp/ccpWitl8.o: In function `main':
main.cpp:(.text+0x55): undefined reference to `my_ex(std::string)'
collect2: error: ld returned 1 exit status

如果我在轉換周圍添加大括號,就像這樣:

const char * text = "exception text";
std::cout << "Creating MyException object using std::string(const char *)." << std::endl;
MyException my_ex((std::string(text)));
std::cout << "MyException object created." << std::endl;
throw my_ex;

然后它按照我的預期工作:

 $ g++ main.cpp
 $ ./a.out
Creating MyException object using std::string(const char *).
MyException constructor, s1: exception text
MyException object created.
terminate called after throwing an instance of 'MyException'
Aborted (core dumped)

我有以下問題:

  1. 為什么我的第一個例子編譯? 為什么我沒有收到編譯錯誤?
  2. 當我嘗試throw my_ex;時,為什么代碼不能編譯throw my_ex;
  3. 為什么大括號可以解決問題?

根據最煩惱的解析MyException my_ex(std::string(text)); 是一個功能聲明; 該函數名為my_ex ,使用類型為std::string名為text的參數,返回MyException 它根本不是對象定義,因此不會調用構造函數。

注意錯誤消息undefined reference to 'my_ex(std::string)'throw my_ex; (你試圖拋出一個函數指針),這意味着找不到函數my_ex的定義。

要修復它,您可以添加其他括號(如您所示)或使用C ++ 11支持的大括號

MyException my_ex1((std::string(text)));
MyException my_ex2{std::string(text)};
MyException my_ex3{std::string{text}};

答案是盡可能使用{} (braced-init)。 但有時候,它可能會無意中錯過。 幸運的是,編譯器(如clang,沒有額外的警告標志)可以提示:

warning: parentheses were disambiguated as a function declaration [-Wvexing-parse]
    MyException my_ex(std::string(text));
                     ^~~~~~~~~~~~~~~~~~~
test.cpp:13:23: note: add a pair of parentheses to declare a variable
    MyException my_ex(std::string(text));
                      ^
                      (                )
1 warning generated.

這將立即指出你的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM