使用带参数的构造函数来初始化类的成员或使用setter函数间接地执行此操作是否更好?到目前为止,我对这个问题没有得到明确的答案。任何见解都将不胜感激。
答案 0 :(得分:7)
这几乎肯定是设计选择或有时风格的问题。我会考虑很多事情:
构建一个没有设置成员变量的对象会使该类处于无效状态吗?如果是这样,您将需要构造函数为这些成员获取有效值。否则,您应该能够提供有用的默认值。
设置变量的个别成员会违反类不变量吗?如果是这样,他们就不应该有自己的制定者。
此类用户是否可能想要修改个别成员?如果是这样,那么设置者可能是合适的。
能否改变对象的个别成员是否具有概念意义?我认为能够改变Person
的出生日期是没有意义的。但是,您可能会认为更改Person
的名称确实有意义。这取决于。您认为系统名称已更改为Person
的{{1}}是
您可以将setter组合在一起以便更有用吗? Person
取代Rectangle::setX(int)
和Rectangle::setY(int)
更有意义吗?甚至可能Rectangle::setPosition(int,int)
更好。
在任何情况下,通过个人制定者和吸气者暴露其全套成员的类通常都是代码味道。
答案 1 :(得分:2)
您要避免的一件事是拥有一个不完整的对象。如果你可以为每个参数提供合理的默认值,那么可以跳过在构造函数中设置它们,否则你真的应该把它们放在那里。
当然,没有理由你不能同时做到这两点。
答案 2 :(得分:2)
这取决于。当然使用构造函数参数,如果没有有效的类成员,对象没有意义 - 例如,作用域智能指针或ofstream的文件名。
explicit ofstream ( const char * filename, ios_base::openmode mode = ios_base::out );
谨慎使用其他参数,并尽可能提供默认值。
但是,不要添加太多的构造函数参数,以使订单无法记住,或者是否存在危险混淆的可能性,例如:
Person(std::string firstname, std::string lastname, std::string title, std::string occupation,
std::string address, std::string telephone, int age, std::string creditcard, time_t birthday)