0

我有以下代码:

#include <iostream>
    #include <string>
    using namespace std;
    class Uno {
    public: Uno() { cout << "X"; }
    };



    int main()
    {
            Uno u;
            Uno k=u;

            return 0;
    }

因此,据我了解,该代码Uno k=u;将创建 u.xml 的副本。似乎构造函数被调用了两次。我期待“XX”,但程序只输出“X”。你能解释一下发生了什么吗?

谢谢你

4

5 回答 5

3

发生了什么是这样的:

Uno k = u;

是一个(复制)初始化,它从对象复制构造Uno对象。复制构造意味着调用复制构造函数(在这种情况下由编译器隐式生成),而不是默认构造函数。kUnou

这就是为什么您输出的消息在初始化期间没有被打印出来的原因k:您的构造函数没有被调用;相反,调用另一个(隐式生成的)构造函数。

另请注意,上述声明通常等同于此:

Uno k;
k = u;

在最后一个片段中,表达式k = u是一个赋值,而不是一个初始化。尽管这两种结构都使用了=符号,但您不应该让这让您感到困惑。

于 2013-06-29T00:46:08.657 回答
1

k正在使用不输出X.

尝试添加这个:

Uno(const Uno&) { cout << "Y"; }

你应该看到XY输出。

于 2013-06-29T00:45:09.570 回答
1

在这种情况下,我相信构造函数没有被调用,因为你没有创建一个新对象;相反,您正在将旧对象复制到不同的位置。

但是,由于您不使用指针,它们应该是独立的;对其中一个的更改不会影响另一个。

代码不会第二次运行构造函数,因为它没有构建新的东西。想象一下,您在创建 u 的字段后对其进行了一些更改。再次调用构造函数不会复制 u,因此 C++ 不会这样做。这有点像复制照片——这样做不会让你的相机熄火两次,因为这可能会产生不同的照片;相反,你通过复印机运行它,这是不同的。

编辑:据我所知,它确实运行了一个构造函数,而不是你写的那个。假设我比喻中的相机有一个内置的复印机,它当然不会触发闪光灯。

于 2013-06-29T00:45:10.120 回答
1

这是因为您的类没有复制构造函数。如果没有创建复制构造函数,则 C++ 调用默认构造函数。这显然没有 cout<<"X" 行。

Uno u;     // your constructor called, --> X to output
Uno k = u; // default copy constructor called

但是,如果您没有成员变量,则复制​​构造函数没有意义。

所以让我们说这就是你想要的:

#include <iostream>
#include <string>

using namespace std;

class Uno
{
  public:

    string text;

    // constructor
    Uno()
    {
        text = "X";
        cout << text;
    }

    // copy constructor
    Uno(const Uno &o)
    {
        text = o.text;
        cout << text;
    }
};

int main()
{
        Uno u;        // call constructor -> X
        u.text = "Y"; // change text in constructed object
        Uno k=u;      // create new object via calling copy constructor --> Y
                      // so u.text copied to k.text

        return 0;
}

我推荐learncpp.com 的文章,它们非常有用并且让事情变得简单。

有关复制构造函数和赋值运算符的更多信息:http: //www.learncpp.com/cpp-tutorial/911-the-copy-constructor-and-overloading-the-assignment-operator/

于 2013-06-29T01:10:00.917 回答
0

戴上我的学究帽片刻......除非你明确告诉编译器,否则默认情况下你总是有复制构造函数:

Uno(const Uno & other);

和赋值运算符:

Uno & operator=(const Uno & other);

无论你是否要求他们。如果您不定义任何其他构造函数,您还将获得默认构造函数:

Uno();

由于您已经定义了无参数构造函数,因此将使用您的构造函数而不是最后一个默认值。

定义变量时:

Uno u;

您的构造函数用于初始化对象实例。当你做任务时:

Uno k=u;

使用赋值运算符。

您可能会问,我如何防止复制或分配对象?将它们声明为私有的,并且不要实现它们:

class Uno
{
private:
    Uno(const Uno &);
    Uno & operator=(const Uno &);
        ...
};
于 2013-06-29T01:28:38.880 回答