2013-02-17 111 views
2

在这个简化的例子中,我的问题是:我是否在Action :: setUser()内部进行合法赋值?此C++参考分配是否正确?

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被称为发生了什么行动的 “用户” 属性?它被摧毁了吗?它有史以来建造?
  • 如果我第二次调用setUser会发生什么?
  • 如果我删除setUser中的“&”符号,一切都会好的,对不对?因为这就像传递参数的副本一样,对吧?

我很担心,我做内存疯狂的事情,因为属性没有被正确地摧毁...

谢谢


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

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

我不知道编译器提供了一个默认的重载赋值操作符。现在我知道一切都非常有意义...

再次感谢。

+0

除了可能更好,如果这是'const User&u',那么分配就很好。它将复制用户而不需要中间副本到by-val参数。 Action的现有用户不会被销毁'setUser(u)',而是会通过赋值操作符“覆盖”。如果你想要,你可以通过自己编写一个'User :: operator =(const User&u)'来控制它是如何完成的。关于第二个电话,与第一个电话相同。最后,删除&*将会*引入至少一个额外的副本。 – WhozCraig 2013-02-17 00:47:01

+0

我想知道你写的最后一句话:*“我担心我在记忆中做了疯狂的事情,因为属性没有被正确销毁”* - 你是什么意思?*“被正确销毁”*?你如何看待这个问题? – LihO 2013-02-17 00:53:32

回答

4

当setUser被调用时,Action的“user”属性会发生什么?

赋值运算符(由编译器提供,如还没有定义的自定义一个)被调用时,它简单地执行构件明智拷贝从uuser

它被摧毁了吗?

是它有史以来建造?

是的。

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

同样的事情。

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

user的任务而言,这没有什么区别。按引用传递仅仅意味着在调用该函数时不会创建参数副本。

+0

+1,简单直接的答案。 – LihO 2013-02-17 00:51:25

1

是的,没关系。它只是从u中指定您直接定义为a.user。参考参数避免了将额外的副本传递给a.setUser

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

该分配不会创建或破坏现有值。 Action对象在超出范围时将被销毁,并且会破坏它包含的User对象。

1

答案:

  • 它不被破坏,但覆盖(拷贝赋值)。是的,它是以前建造的。
  • 与第一次相同。
  • 如果您删除了&,则会传递副本。它并没有让事情错误或正确。

注:

  • 使用const的,无论在memberfunctions和传递的参数。
  • 您至少需要考虑控制复制和分配。这应该在任何更好的C++介绍或FAQ中解释。
1
class Action { 
private: 
    User user; 
} 

定义User类型的私有成员。这是一个具有自动存储持续时间的对象,它在Action类型的对象正在构建时构建。它的使用寿命与Action类型的对象的使用期限有关。

现在,在该方法中:

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

u是参照其属性(成员)的对象将被用于通过使用所述赋值运算符设置的user属性。

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