首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用参数化构造函数时没有编译错误

使用参数化构造函数时没有编译错误
EN

Stack Overflow用户
提问于 2016-11-23 22:54:45
回答 2查看 816关注 0票数 18

今天在工作的时候,我在C++中遇到了一个我不理解的行为。我已经生成了以下示例代码来说明我的问题:

代码语言:javascript
复制
#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;
}

此代码段编译时没有任何错误,并生成以下输出:

代码语言:javascript
复制
 $ 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,我定义的构造函数没有被调用。接下来,如果我真的想抛出这个变量:

代码语言:javascript
复制
throw my_ex;

我得到一个编译错误:

代码语言:javascript
复制
 $ 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

如果我在转换前后添加大括号,如下所示:

代码语言:javascript
复制
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;

然后它就会像我预期的那样工作:

代码语言:javascript
复制
 $ 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. 为什么要编译我的第一个示例?当我尝试throw my_ex;
  2. Why时,为什么我没有得到编译错误?
  3. 为什么没有代码编译,大括号能解决问题吗?
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-11-23 23:01:57

根据most vexing parse的说法,MyException my_ex(std::string(text));是一个函数声明;该函数名为my_ex,接受类型为std::string的名为text的参数,返回MyException。它根本不是一个对象定义,因此不会调用任何构造函数。

注意throw my_ex;的错误消息undefined reference to 'my_ex(std::string)' (实际上您试图抛出一个函数指针),这意味着找不到函数my_ex的定义。

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

代码语言:javascript
复制
MyException my_ex1((std::string(text)));
MyException my_ex2{std::string(text)};
MyException my_ex3{std::string{text}};
票数 34
EN

Stack Overflow用户

发布于 2016-11-24 03:31:54

答案是尽可能多地使用{} (带括号的-init)。然而,有时可能会无意中错过它。幸运的是,编译器(如clang,没有额外的警告标志)可以提示:

代码语言:javascript
复制
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.

这将立即为您指出问题所在。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40767681

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档