C++中运算符"<<"的重载出现意外行为

3

我编写了一个简单的程序,用于展示在 c++ 中重载运算符 << 的使用。根据这篇文章:https://learn.microsoft.com/en-us/cpp/standard-library/overloading-the-output-operator-for-your-own-classes?view=msvc-160,我尝试编写了自己的代码:

#include <iostream>
#include <string>

class Date
{
private:
    std::string str;
public:
    Date(int x) : str(5, 'x'){}
    friend std::ostream& operator<<(std::ostream& os, const Date& dt){
        os << dt.str;
        return os;
    }
};

int main()
{
    Date dt(6);
    std::cout << dt;
}

这段代码正确运行并在控制台中打印了 "xxxxx"。但是当我删除构造函数的参数时,问题出现了:
#include <iostream>
#include <string>

class Date
{
private:
    std::string str;
public:
    Date() : str(5, 'x'){}
    friend std::ostream& operator<<(std::ostream& os, const Date& dt){
        os << dt.str;
        return os;
    }
};


int main()
{
    Date dt();
    std::cout << dt;
}

我在控制台上看到了“1”这个输出,但我不知道为什么会有这个结果。


1
那是最令人痛苦的解析方式(加上不幸的重载决议)的恶劣实例。 - 463035818_is_not_a_number
4
Date dt(); 是一个名为 dt 的函数,不带参数并返回类型为 Date。可以使用以下任何一种方式创建默认构造的 DateDate dt;Date dt{}; 或者 auto dt = Date();。请注意,这些替代方式都将创建一个默认构造的 Date 对象。 - François Andrieux
在第二个例子中,显然你使用了默认构造函数Date(),而你并没有定义它,所以编译器会将其合成为创建一个空的Date对象。而在第一个例子中,无论你在main()中创建的dt对象传入什么参数,输出都将是xxxxx - Giogre
2
@Giogre,在第二个例子中有默认构造函数的定义,但是 Date dt(); 没有调用默认构造函数。 - 463035818_is_not_a_number
1
@Sao_Si很抱歉说这句话,但是Giogre的评论中的解释是完全错误的。 - 463035818_is_not_a_number
显示剩余5条评论
1个回答

2
尝试以下内容:

请试用以下方法:

    int main()
    {
        Date dt;
        std::cout << dt;
    }

你在使用哪个编译器?如果你的主函数没有参数,如Date dt();,Microsoft C++ 编译器会报告链接错误。

error LNK2001: unresolved external symbol "class Date __cdecl dt(void)" (?dt@@YA?AVDate@@XZ)


谢谢,终于成功了。我在Linux上使用gcc。再次感谢。 - Sao_Si
好的,如果有效请接受答案。 - mkag
1
@mkag为什么不解释一下Date dt();为什么是不正确的?回答应附带有关问题原因的说明。 - PaulMcKenzie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接