使用参数化构造函数时缺少编译错误 [英] Absence of compilation error when using parametrized constructor

查看:72
本文介绍了使用参数化构造函数时缺少编译错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

今天在工作中,我遇到了我不理解的C ++行为.我产生了以下示例代码来说明我的问题:

Today at work I came across a behavior in C++ which I don't understand. I have produced the following example code to illustrate my problem:

#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;
}

此代码段编译无任何错误,并产生以下输出:

This code snippet compiles without any errors and produces the following output:

 $ 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 ,未调用我定义的构造函数.接下来,如果我想实际抛出该变量:

Note that for my_ex the constructor I have defined was not called. Next, if I want to actually throw this variable:

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

如果我在转换前后加上括号,就像这样:

If I add braces around the conversion, like this:

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;

然后它按我预期的那样工作:

Then it works as I would have expected:

 $ 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. 当我尝试抛出my_ex; 时,为什么不能编译代码?
  3. 括号为什么能解决问题?

推荐答案

根据最令人讨厌的解析 MyException my_ex(std :: string(text)); 是一个函数声明;该函数名为 my_ex ,并使用类型为 std :: string 的名为 text 的参数,返回 MyException .根本不是对象定义,因此不会调用任何构造函数.

According to most vexing parse, MyException my_ex(std::string(text)); is a function declaration; the function is named my_ex, taking a parameter named text with type std::string, returns MyException. It's not an object definition at all, then no constructor will be called.

请注意错误消息未定义对'my_ex(std :: string)'的引用,用于 throw my_ex; (实际上您正在尝试抛出函数指针),这意味着找不到函数 my_ex 的定义.

Note the error message undefined reference to 'my_ex(std::string)' for throw my_ex; (you're trying to throw a function pointer in fact), which means that can't find the definition of the function my_ex.

要解决此问题,您可以添加其他括号(如所示)或使用大括号受C ++ 11支持:

To fix it you can add additional parentheses (as you has shown) or use braces which supported from C++11:

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

这篇关于使用参数化构造函数时缺少编译错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆