复制C+中的构造函数和赋值运算符+; 当我在C++中学习构造函数时,我遇到了一些难以完全理解的事情。一个是当我们创建一个类的对象时(比如说类点),如果我们没有为自己编写构造函数,就会调用默认构造函数。(我想复制构造函数也是如此)

复制C+中的构造函数和赋值运算符+; 当我在C++中学习构造函数时,我遇到了一些难以完全理解的事情。一个是当我们创建一个类的对象时(比如说类点),如果我们没有为自己编写构造函数,就会调用默认构造函数。(我想复制构造函数也是如此),c++,copy-constructor,default-constructor,C++,Copy Constructor,Default Constructor,在这种情况下,我会调用默认的复制构造函数,但如果我这样做会怎么样: Point p1; p1.setX(3); p2.setY(2); Point p2; p2 = p1; 这仍然有效,但我想这里不会调用默认的复制构造函数,因为我认为在创建对象时会调用构造函数。那么,在第二种情况下,该任务是如何工作的呢 除此之外,我想知道我们何时编写自己的副本构造函数(ClassName(const ClassName&old_obj);等等)。下面的两个例子有什么不同,还是仅仅是句法上的差异 Point

在这种情况下,我会调用默认的复制构造函数,但如果我这样做会怎么样:

Point p1;
p1.setX(3);
p2.setY(2);

Point p2;

p2 = p1;
这仍然有效,但我想这里不会调用默认的复制构造函数,因为我认为在创建对象时会调用构造函数。那么,在第二种情况下,该任务是如何工作的呢

除此之外,我想知道我们何时编写自己的副本构造函数(
ClassName(const ClassName&old_obj);
等等)。下面的两个例子有什么不同,还是仅仅是句法上的差异

Point p3(p1);

在第二个例子中,为什么程序推断我们将
p1
作为参数传递给复制构造函数,而我们没有在parantises中的
p3
之后编写它

此外,当我们创建一个类的对象并将参数作为其构造函数时,我们使用括号将数据作为参数传递。但是,对于默认构造函数(即使我们编写了自己的),我们根本不使用括号,而是这样创建对象:

Point p1;
Point p1(); // even if we defined our default constructor like "Point() {}"
不是这样的:

Point p1;
Point p1(); // even if we defined our default constructor like "Point() {}"

原因是什么?程序是否知道不为我们创建默认构造函数?

我在这里假设一个默认点实现

当我在C++中学习构造函数时,我遇到了一些难以完全理解的事情。一个是当我们创建一个类的对象(比如说类点)时,如果我们没有为自己编写构造函数,就会调用默认构造函数。(我想复制构造函数也是如此)

点p2=p1

在这种情况下,我会调用默认的复制构造函数,但如果我这样做会怎么样:

Point p1;
p1.setX(3);
p2.setY(2);

Point p2;

p2 = p1;
真的

p1点; p1.setX(3); p2.setY(2)

p2点

p2=p1; 这仍然有效,但我想这里不会调用默认的复制构造函数,因为我认为在创建对象时会调用构造函数。那么,在第二种情况下,该任务是如何工作的呢

对。使用赋值运算符。复制构造函数仅在创建新的点对象时使用。实际上,如果您有一个复制构造函数,那么应该有一个带有 加工实现

除此之外,我想知道我们何时编写自己的副本构造函数(ClassName(const ClassName&old_obj);等等)。下面的两个例子有什么不同,还是仅仅是句法上的差异

Point p3(p1);
如果拷贝构造函数有什么特别之处,您可以编写自己的拷贝构造函数。也许出于某种原因,不应该复制成员。可能无法使用复制构造函数/赋值构造函数复制成员,您必须调用非标准CloneThis方法。 如果所有成员都是可复制的,并且应该复制所有成员,则只需使用=默认值

(我将把搬家任务/搬家建筑排除在外)

p3点(p1); 及

点p3=p1; 在第二个例子中,为什么程序推断我们将p1作为参数传递给copy构造函数,而我们没有在p3之后在parantesses中编写它

从C++11开始,它就保证是语法糖。它们都保证调用复制构造函数。另一种解释是,首先调用p3的默认构造函数,然后调用赋值运算符将p1的值赋值给p3。这显然是浪费,如果p3不是默认可构造的,甚至可能不可能

此外,当我们创建一个类的对象并将参数作为其构造函数时,我们使用括号将数据作为参数传递。但是当涉及到默认构造函数时(即使我们编写了自己的构造函数),我们根本不使用括号,而是像这样创建对象:

Point p1;
Point p1(); // even if we defined our default constructor like "Point() {}"
p1点; 不是这样的:

Point p1;
Point p1(); // even if we defined our default constructor like "Point() {}"
点p1();//即使我们定义了像“Point(){}”这样的默认构造函数 原因是什么?程序是否知道不为我们创建默认构造函数

你可以写点p1;或者你可以写点p1{}

您可以编写Point p1(),但这意味着声明一个不带参数的函数p1,该函数返回一个点。 然而,现代编译器会对第三个变体发出警告,因为这是一个常见的错误

现代的建议是使用{},因为它更统一。 点p1{}; 点p2{1,1}


希望这有帮助。

最后一个示例不是默认构造函数,它是一个名为
p1
的函数的函数声明,该函数不带参数,并返回一个
点。因此,这就是为什么不能使用它创建名为
p1
点的原因。这叫做。看看和。不,材料所呈现的技术性质对新程序员来说并不总是最容易理解的(别担心,它会变得更容易)。最后一点(没有双关语),
第p1点
声明
类点的实例,而
点pi()创建一个函数。哦,好的,最后一个声明了一个返回类型
点的函数。我也会看一下这些链接。@alexmoran还知道,定义一个构造函数可能会自动删除其他构造函数的自动存在。这很有帮助,但我想了解的一件事是:当我们试图分配之前创建的两个类对象时,CPP能够理解我们告诉它从一个变量值复制到另一个变量值吗?(如果已经创建了对象,并且没有调用复制构造函数?)我不确定我是否理解:默认情况下生成的复制构造函数/复制赋值将逐个复制成员。我的问题是,赋值运算符不仅仅用于基本数据类型。如果它与obje类一起使用