C ++构造函数的默认参数

By simon at 2018-02-07 • 0人收藏 • 65人看过

有一个使用默认参数的类构造函数是一个好习惯, 或者我应该使用单独的重载构造函数?例如:

// Use this...
class foo  
{
private:
    std::string name_;
    unsigned int age_;
public:
    foo(const std::string& name = "", const unsigned int age = 0) :
        name_(name),
        age_(age)
    {
        ...
    }
};

// Or this?
class foo  
{
private:
    std::string name_;
    unsigned int age_;
public:
    foo() :
    name_(""),
    age_(0)
{
}

foo(const std::string& name, const unsigned int age) :
        name_(name),
        age_(age)
    {
        ...
    }
};
这两个版本似乎都起作用,例如:
foo f1;
foo f2("Name", 30);
你喜欢或推荐哪种风格,为什么?

7 个回复 | 最后更新于 2018-02-07
2018-02-07   #1

绝对是一个风格问题。我更喜欢默认参数的构造函数, 只要参数是有意义的。在th的类e标准使用它们 好吧,这对他们有利。 有一点要注意的是,如果你有一个默认的所有,但一个参数ameter, 您的类可以隐式地从该参数类型转换。查看 [这个线程](https://stackoverflow.com/quest离子/ 174349 /迫使-单 参数 - 构造函数将被显式在C)更多的信息。

2018-02-07   #2

绝对是一个风格问题。我更喜欢默认参数的构造函数, 只要参数是有意义的。在th的类e标准使用它们 好吧,这对他们有利。 有一点要注意的是,如果你有一个默认的所有,但一个参数ameter, 您的类可以隐式地从该参数类型转换。查看 [这个线程](https://stackoverflow.com/quest离子/ 174349 /迫使-单 参数 - 构造函数将被显式在C)更多的信息。

2018-02-07   #3

根据我的经验,当时的默认参数看起来很酷,使我的 懒惰的因素很高兴,但后来我在用t的路他和我一样 当默认启动时感到惊讶。所以我不认为这是一个好主意。 最好有一个className :: className(),然后是一个className :: init(arglist )。只是为了维护性的缘故。

2018-02-07   #4

我会去默认的参数,特别是因为C ++不让你连锁 构造函数(所以你最终不得不复制th初始化列表,和 可能更多,每个超载)。 也就是说,有一些缺省的参数,包括t他其实 常量可以内联(从而成为你的类的二进制文件的一部分 接口)。另一个值得注意的是tha添加默认参数可以转向 一个显式的多参数构造函数转化为一个隐式的单参数 构造函数:

class Vehicle {
public:
  Vehicle(int wheels, std::string name = "Mini");
};

Vehicle x = 5;  // this compiles just fine... did you really want it to?

2018-02-07   #5

我会去默认参数,因为这个原因:你的例子假设 该ctor参数直接对应于成员变量。但是,如果是这样 情况并非如此,您必须在对象之前处理参数 初始化。有一个常见的ctor将是最好的方式去。

2018-02-07   #6

使用默认参数困扰我的一件事是你不能指定 最后一个参数,但使用默认值第一个。例如,在 你的代码,你不能创建一个没有名字,但给定年龄的Foo(但是,如果我 记得没错,是可以在C ++ 0x,统一的 构造语法)。有时候,这是有道理的,但也可以是真的 awkwARD。 在我看来,没有经验法则。就个人而言,我倾向于使用多个 重载的构造函数(或方法),除了我f只有最后一个参数需要a 默认值。

2018-02-07   #7

如果用参数创建构造函数是不好的(如许多人会争辩的),那么 使他们与默认参数更糟糕。我心中已经e最近开始了 来看看ctor的论点是不好的,因为你的ctor 逻辑应该尽可能小ossible。你如何处理错误处理 在这种情况下,是否应该有人通过一个没有任何意义的论点? 您可以抛出一个异常,这是坏消息,除非你所有的 呼叫者准备在尝试b中包装任何“新”呼叫锁或设置 一些“被初始化”的成员变量,这是一种肮脏的黑客。 所以,唯一的方法就是确保that传入的参数 你的对象的初始化阶段是设置一个单独的initialize() 方法,你可以通道eck返回码。 默认参数的使用是不好的,原因有两个:首先,如果你想 给t添加另一个参数他,那么你被卡住了 开始和改变整个API。而且,大多数程序员都是 accustomed通过它在实践中使用的方式来计算API - 这尤其适用于在公共API中使用的非公开API一个组织 正式文件可能不存在。当其他程序员看到的时候 大部分的电话不包含ñ任何论点,他们也会这样做, 保持幸福的默认行为默认参数 强加于EM。 另外,值得注意的是[谷歌C + +风格 导(https://google.github.io/styleguide/cppguide.html#DoingWorkinConstructors) 避免ctor参数(除非绝对必要)和[default 参数的功能或 方法](HTTPS://咕gle.github.io/styleguide/cppguide.html#Default_Arguments).

登录后方可回帖

Loading...