2

在这个简化的示例中,我的问题是:我是否在 Action::setUser() 中进行了合法分配?

class User {
private:
   int age;
public:
   int getAge() { return age; }
};

class Action {
private:
   User user;
public:
   void setUser(User &u) {
      user = u;
   }
};

int main() {
   User u;
   Action a;
   a.setUser(u);
   return 0;
}

让我吵闹的是,

  • 调用 setUser 时,Action 的“用户”属性会发生什么变化?它被摧毁了吗?它曾经建造过吗?
  • 如果我第二次调用 setUser 会发生什么?
  • 如果我删除 setUser 中的“&”符号,一切都会好起来的,对吧?因为这就像传递参数的副本,对吗?

我担心我在用记忆做疯狂的事情,因为属性没有被正确地破坏......

谢谢


于 2013 年 2 月 18 日星期一编辑

非常感谢!我真的很感谢你所有的回应......

我不知道编译器提供了默认的重载赋值运算符。现在我知道一切都说得通了……

再次感谢。

4

4 回答 4

4

调用 setUser 时,Action 的“用户”属性会发生什么变化?

调用赋值运算符(由编译器提供,因为您尚未定义自定义运算符),它只是执行从uto的成员方式复制user

它被摧毁了吗?

不。

它曾经建造过吗?

是的。

如果我第二次调用 setUser 会发生什么?

一样的东西。

如果我删除 setUser 中的“&”符号,一切都会好起来的,对吧?

就分配到user而言,这没有什么区别。通过引用传递只是意味着在调用函数时不会复制参数。

于 2013-02-17T00:42:33.113 回答
1

是的,没关系。它只是将u您在 main 中定义的直接分配给a.user. 引用参数避免制作额外的副本以传递给a.setUser.

当您创建它时,Action它包含一个默认构造的User对象。然后,您将为其分配一个值User。这不是(IMO)最好的设计(我宁愿看到User具有正确值的构造),但它完全有效。

赋值不会创建或破坏现有值。当Action对象超出范围时将被销毁,这将销毁User它包含的对象。

于 2013-02-17T00:43:21.070 回答
1

答案:

  • 它没有被破坏,而是被覆盖(复制分配)。是的,它是以前建造的。
  • 和第一次一样。
  • 如果您删除了&,您将传递一个副本。它不会使事情变得错误或正确。

笔记:

  • 在成员函数和传递的参数上都使用 const。
  • 您至少需要考虑控制复制和分配。这应该在任何更好的 C++ 介绍或常见问题解答中解释。
于 2013-02-17T00:44:12.893 回答
1
class Action {
private:
   User user;
}

定义类型的私有成员User。它是一个具有自动存储持续时间的对象,它是在构造类型对象时Action构造的。它的生命周期与 type 对象的生命周期相关Action

现在在这个方法中:

void setUser(User &u) {
    user = u;
}

u是对其属性(成员)的对象的引用,该对象的属性(成员)将用于user通过赋值运算符设置 的属性。

如果你&在此处删除,你将通过引用传递更改为按值传递,这意味着传递给此方法的对象副本将在其调用时创建。

于 2013-02-17T00:44:51.583 回答