今天在工作中,我遇到了一个我不明白的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;
? - 为什么大括号可以解决问题?
这可能是C++最令人生气的怪癖。 –
@GillBates特别是在这样一个复杂的场景中。 – songyuanyao
谢谢,我不知道这种语法,因此我对这种情况感到困惑。 –