C ++ Equal运算符由编译器自动重新定义

时间:2014-02-08 10:49:20

标签: c++ compiler-construction operator-overloading

我认为这个问题非常简单,可以用“运算符自动过载哪个运算符?”这几个词来缩小。 我已经知道发生了什么,但我现在错过了一些能够解释我的详细信息为什么它正在发挥作用。

不幸的是我没有在Stroustrup的C ++参考资料中找到任何有用的东西,我很确定你们中的某些人可以帮我弄清楚发生了什么。 让我们打开讨论:这里有一个类似我正在看的代码的快照:

class MyPair : public pair<string,string>
{
    public:
    MyPair()
    {
        pair<string,string>();
    }
};

到目前为止,没有任何奇怪的内容,正如线程中广泛讨论的那样 What are all the member-functions created by compiler for a class? Does that happen all the time? 编译器将自动生成默认版本的复制构造函数 复制赋值运算符析构函数,但不会生成默认构造函数只是因为我重新定义了自己的。 感谢编译器,我将能够在创建时使用默认的复制构造函数分配一个新对象,并在创建对象后立即使用赋值运算符,如下所示:

//default copy constructor
MyPair mypair1 = mypair;
MyPair mypair2;
//default assignment operator
mypair2 = mypair1

到目前为止,一切都按设计工作。 想象一下,由于某种未知的原因,我希望将一个字符串对象分配给MyPair对象,如下所示:

int main()
{
    pair<string,string> aPair;
    MyPair mypair;
    string mystring("test");
    //ERROR
    mypair = mystring;
    return 0;
}

在我测试这行代码之前,我曾期待编译器会抱怨(因为我没有向它提供 operator = 的任何显式重载,所以本身就是无法为创建的对象分配字符串),实际上它给我一个非常自我解释的错误,如:

test.cpp:36:13: error: no match for ‘operator=’ in ‘mypair = mystring’
test.cpp:36:13: note: candidate is:
test.cpp:7:7: note: MyPair& MyPair::operator=(const MyPair&)

现在,想象一下通过添加以下方法来完成MyPair类:

MyPair(const string& astring)
{
    pair<string,string>(astring,string());
}

突然,代码开始编译,不再给出任何类型的错误。 在我看来,上面的方法似乎为编译器提供了某种聪明之处;它开始产生缺失的 MyPair&amp; MyPair :: operator =(const string&amp; s)

我不得不承认这听起来真的很棒,但我无法理解它究竟发生的原因。 这意味着对于我在MyPair中使用的每个额外构造函数,复制器将生成一个额外的重载 operator = ,这使得我的类可复制可分配到指定的引用只是因为那个?

2 个答案:

答案 0 :(得分:2)

MyPair(const string& astring)是一个隐式转换构造函数。您的string首先用于创建新的MyPair,然后将其分配给您的对象。您可以通过将其标记为显式来禁止此行为:

explicit MyPair(const string& astring)

这可以防止隐式转换,所以

mypair = mystring; 

是非法的,而

mypair = MyPair(mystring);

仍然有效。

答案 1 :(得分:1)

告诉您初始化基类成员的方式不正确。

MyPair()
{
    pair<string,string>();
}

应改为:

MyPair() : pair<string, string>()
{
}

MyPair(const string& astring)
{
    pair<string,string>(astring,string());
}

应改为:

MyPair(const string& astring) : pair<string, string>(astring, string())
{
}

至于分配工作的原因,使用构造函数创建临时的MyPair,并将其用作赋值运算符的参数。