C ++:为什么代码正在编译

时间:2012-09-16 12:14:07

标签: c++ compilation

我不明白这段代码是如何编译的。有人可以解释一下那里发生了什么。

#include <iostream>

using namespace std;

class B
{
public:    
    B(const char* str = "\0") //default constructor
    {
        cout << "Constructor called" << endl;
    }    

    B(const B &b)  //copy constructor
    {
        cout << "Copy constructor called" << endl;
    } 
};

int main()
{ 
    B ob = "copy me";    //why no compilation error.
    return 0;
}

输入是: 构造函数叫

P.S。:我想不出一个比这更贴切的标题,任何能想到更好标题的人,请修改它。

7 个答案:

答案 0 :(得分:10)

"copy me"的类型为char const[8],其衰减为char const *。由于默认构造函数不是explicit,因此"copy me"可以隐式转换为B,因此可以从隐式转换的临时ob复制构造B } -object。

如果默认构造函数已声明为explicit,则必须编写以下内容之一:

B ob1 = B("copy me");
B ob2("copy me");

如果复制构造函数被声明为explicit,那么你不得不说其中一个:

B ob3(B("copy me"));
B ob4("copy me");

在实践中,所有副本都将被任何半合半的编译器省略,并且您总是以一个默认的构造函数调用结束。

答案 1 :(得分:7)

因为这个

B ob = "copy me";

调用复制构造函数,它接受参数const B &b 你的类B有一个构造函数

B(const char* str = "\0")

定义为explicit

允许编译器进行一次隐式转换。


那么,这里会发生什么:

B ob = "copy me";

是:

  1. 使用提供的B创建临时的,未命名的对象const char* str - 这是允许的,因为class B具有构造函数,该构造函数接受一个参数并且未定义为{{1} }。换句话说,所有类型为explicit的对象都可以从B
  2. 构建
  3. 使用在const char*
  4. 中创建的临时对象创建对象ob

答案 2 :(得分:7)

如果您将关键字显式添加到默认构造函数中以防止隐式转换。然后它将无法编译。你的答案是隐式转换。

答案 3 :(得分:4)

这是因为将赋值语句隐式转换为

B ob("copy me");

尝试此操作以使编译失败(查看explicit关键字):

#include <iostream>

using namespace std;

class B
{
public:    
    explicit B(const char* str = "\0") //default constructor
    {
        cout << "Constructor called" << endl;
    }    

    B(const B &b)  //copy constructor
    {
        cout << "Copy constructor called" << endl;
    } 
};

int main()
{ 
    B ob = "copy me";    //why no compilation error.
    return 0;
}

答案 4 :(得分:3)

  

[它不应该编译,因为]指定的行在数据类型中不匹配

没有编译错误,因为存在B的构造函数,它将const char*作为参数,允许在const char*B之间进行转换。

答案 5 :(得分:0)

这是因为隐式转换。将一个Explicit添加到您的默认构造函数并尝试。它将无法编译。

答案 6 :(得分:-1)

编辑:在与Kerrek SB讨论后,我得到了C ++ 11标准的副本。我错了,这是暂时的。我正在编辑此回复以反映我新获得的理解。

15年前,我非常了解C ++(大约是第一个标准发布的时候)。我从1998年末开始没有使用它,所以我已经忘记了很多,而且我对最近的标准几乎一无所知。

代码是正确的。

 B ob = "copy me";    //why no compilation error.

没有错误。这被解析为初始化变量的声明。 B是类型,ob变量的名称,"copy me"初始化程序。

初始化程序的类型为const char*,在类B中,有一个构造函数,它接受一个const char*类型的单个参数。该构造函数未被explicit声明限制,因此可以在此上下文中使用。

创建临时对象然后复制(您看到两行都打印出来)或者删除了副本,只调用转换构造函数直接在目标构造(您只看到一行打印)。即使拷贝构造函数有副作用,标准也明确允许这样做。

程序执行会将名为的构造函数打印到stdout。它可能会也可能不会打印复制构造函数。没有错误。