[英]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)
我有以下問題:
throw my_ex;
時,為什么代碼不能編譯throw my_ex;
? 根據最煩惱的解析 , 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.