Сегодня на работе я столкнулся с поведением в 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
Спасибо, я не знал этого синтаксиса, отсюда мое недоумение в ситуации. –