Oop 使用构造函数与设置函数

Oop 使用构造函数与设置函数,oop,Oop,使用带参数的构造函数来初始化类的成员更好,还是使用setter函数间接地初始化?到目前为止,我还没有得到这个问题的明确答案。如果您有任何见解,我们将不胜感激。您希望避免的一件事是拥有一个不完整的对象。如果您可以为每个参数提供合理的默认值,那么可以跳过在构造函数中设置它们,否则您真的应该将它们放在那里 当然,没有理由你不能两者兼得。你要避免的一件事是拥有一个不完整的对象。如果您可以为每个参数提供合理的默认值,那么可以跳过在构造函数中设置它们,否则您真的应该将它们放在那里 当然,没有理由不能两者兼而

使用带参数的构造函数来初始化类的成员更好,还是使用setter函数间接地初始化?到目前为止,我还没有得到这个问题的明确答案。如果您有任何见解,我们将不胜感激。

您希望避免的一件事是拥有一个不完整的对象。如果您可以为每个参数提供合理的默认值,那么可以跳过在构造函数中设置它们,否则您真的应该将它们放在那里


当然,没有理由你不能两者兼得。

你要避免的一件事是拥有一个不完整的对象。如果您可以为每个参数提供合理的默认值,那么可以跳过在构造函数中设置它们,否则您真的应该将它们放在那里


当然,没有理由不能两者兼而有之。

这几乎可以肯定是设计选择的问题,有时是风格的问题。我会考虑一些事情:

  • 在不设置成员变量的情况下构造对象会使类处于无效状态吗?如果是这样,您将需要构造函数为这些成员获取有效值。否则,您应该能够提供有用的默认值

  • 设置变量的单个成员会违反类不变量吗?如果是这样,他们不应该有自己的二传手

  • 此类的用户是否可能要修改单个成员?如果是这样,那么setter可能是合适的

  • 能够更改对象的单个成员在概念上有意义吗?我认为改变一个人的出生日期是没有意义的。然而,你可以说改变一个人的名字是有意义的。视情况而定。在系统中,您是否考虑了<代码>人>代码>,其名称已更改为不同的<代码>人< /代码>?

  • 你能把setter组合在一起使其更有用吗?与
    Rectangle::setX(int)
    Rectangle::setY(int)
    相比,
    Rectangle::setPosition(int,int)
    更有意义吗?甚至
    Rectangle::setPosition(Point)
    也可能更好


  • 在任何情况下,通过单独的setter和getter公开其完整成员集的类通常是一种代码气味。

    这几乎肯定是设计选择的问题,有时是风格的问题。我会考虑一些事情:

  • 在不设置成员变量的情况下构造对象会使类处于无效状态吗?如果是这样,您将需要构造函数为这些成员获取有效值。否则,您应该能够提供有用的默认值

  • 设置变量的单个成员会违反类不变量吗?如果是这样,他们不应该有自己的二传手

  • 此类的用户是否可能要修改单个成员?如果是这样,那么setter可能是合适的

  • 能够更改对象的单个成员在概念上有意义吗?我认为改变一个人的出生日期是没有意义的。然而,你可以说改变一个人的名字是有意义的。视情况而定。在系统中,您是否考虑了<代码>人>代码>,其名称已更改为不同的<代码>人< /代码>?

  • 你能把setter组合在一起使其更有用吗?与
    Rectangle::setX(int)
    Rectangle::setY(int)
    相比,
    Rectangle::setPosition(int,int)
    更有意义吗?甚至
    Rectangle::setPosition(Point)
    也可能更好


  • 在任何情况下,其全部成员集通过单独的setter和getter公开的类通常是一种代码气味。

    这取决于具体情况。当然,如果没有有效的类成员,对象就没有意义,请使用构造函数参数,例如,作用域智能指针或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)
    

    视情况而定。当然,如果没有有效的类成员,对象就没有意义,请使用构造函数参数,例如,作用域智能指针或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)
    

    你没有得到一个明确的答案?你还问了什么问题?虽然有一个小的C++特殊性,但是我删除了C++标签来支持更一般的“OOP”标签。我不认为有一个合适的答案(所以我投了不具建设性的票),尽管有很多建议/倡导者支持这两种选择。定义“更好”。您想如何测量它?从谁的角度来看?是类的开发人员还是用户?(提示:您最好从用户的角度出发。当您对类进行单元测试时,您可以发现这是什么。)有时构造函数参数是唯一的选项,例如,如果成员不是默认可构造的,或者成员是引用。否则,这实际上取决于用例。目标应该是在构建时使对象保持有效状态。通过setter设置可选参数是可以的,不过我个人更喜欢使用默认参数的构造函数。我建议使用多个构造函数,并将适当的默认值传递给this(),或者使用生成器模式。我宁愿两者都保留空引用。你没有得到一个明确的答案吗?你还问了什么问题?虽然有一个小的C++特殊性,但是我删除了C++标签来支持更一般的“OOP”标签。我认为没有合适的答案(所以我