【问题标题】:Automatic constructor generation in C++?C++中的自动构造函数生成?
【发布时间】:2016-12-07 19:47:04
【问题描述】:

想象一下我有

struct Foo
{
   int a;
   string s;
   float f;
}

所以现在当我需要创建新的 Foo 时,我需要添加一个构造函数:

struct Foo
    {
       int a;
       string s;
       float f;
       Foo(int a, string s, float f)
       {
          this->a = a;
          this->s = s;
          this->f = f;
       }
    }

然而,这种手动编写构造函数的方法非常耗时,尤其是对于具有 10 多个属性的结构/类。我的问题是:有没有办法自动生成这样的构造函数?

【问题讨论】:

  • IDE 代码自动生成? en.wikipedia.org/wiki/Builder_pattern ?程序代码生成? stackoverflow.com/questions/6273437/…(即聚合初始化)?反射库? ...我感觉到你在那里尝试做的事情有一种反模式,顺便说一句。
  • So now when I need to create new Foo I need to add a constructor 不,你没有。不用一个,使用聚合初始化
  • 这称为“聚合初始化”。去谷歌,查一下。您将需要一个支持当前 C++ 标准的编译器。
  • @SamVarshavchik 好吧,thing = {other, things} 语法对于 C 兼容性始终有效,对吧?只有 thing{uniform, initialisation} 是 C++11 中的新选项。
  • 另外,正如 Humam 所指出的,在初始化列表中分配可以初始化的内容是一个巨大的nope。有很多原因导致前者不适用于特定类型/资格的成员......即使它可以工作,它也是低效的(导致您的成员被默认初始化然后分配)和草率的风格。跨度>

标签: c++ class struct constructor code-generation


【解决方案1】:
struct Foo
{
  int a;
  std::string s;
  float f;
};

Foo f{42,"Foo",0.0};

工作得很好,但是构造函数给了你更多的控制权,例如检查初始值。

【讨论】:

    【解决方案2】:

    首先,如果你想自己写构造函数,最好是这样:

    struct Foo
    {
       int a;
       string s;
       float f;
       Foo()=default;// this is needed if Foo needs to be default constructable (Thanks to @ NathanOliver)
       Foo(int a, string s, float f):a(a),s(s),f(f){
       }
    };
    

    如果你不想手动做(手动选项肯定更好,更可控),你可以这样:

    struct Foo
    {
      int a;
      std::string s;
      float f;
      //The default constructor is exist by default here
    };
    Foo obj{0,"",0.0f};
    

    【讨论】:

    • 可能需要注意的是,与第一种情况不同,第二种情况也是默认可构造的。
    • 好点:在正文中分配可以在初始化列表中初始化的内容是一个巨大的nope
    • 您可能希望为af 添加一个类内初始化程序,以便显式默认的ctor 获取。也许也适用于聚合初始化示例 (>=C++14),但这取决于。
    【解决方案3】:

    如果您的结构是 POD,您可以使用 {} 来初始化它们。

    struct A {
      int a;
      int b;
    } foo = {2,3};
    

    在更现代的 C++ 中,对这种语法的限制已经放宽了。它叫list initialization

    【讨论】:

    • 澄清一下,thing = {other, things} 语法对于 C 兼容性始终有效,只有 thing{uniform, initialisation} 是 C++11 中的新语法。
    • 不是 PODS,而是 聚合
    【解决方案4】:

    虽然我个人建议使用构造函数,因为构造函数具有检查其类型参数的优势,对于错误,有一种初始化数据成员的方法,在 C++11 中引入,称为 list-initialization,它使用由用户编写的自动连续分配数据成员的列表。这是一个示例结构的示例foo

    struct Foo
    {
        int a;
        int b;
    };
    int main()
    {
        Foo bar {27,86}; // Note the use of curly braces here to initialize the list. There is
                         // no range or error checking, but a and b are consecutively initialized
        return 0;
    }
    

    如果您没有阅读我在代码中的注释,这里是: 注意这里使用花括号来初始化列表。没有范围或错误检查,但 a 和 b 连续初始化

    如果我的编译器不支持 C++11 怎么办?

    如果编译器不支持 C++11,Uniform Initialization(C++ 中一直存在的功能)会派上用场。下面是相同结构 Foo 的示例:

    Foo baz = {22,33}; //Note the '=' sign here, that separates it from list-initialization.
    

    【讨论】:

      猜你喜欢
      • 2012-03-08
      • 1970-01-01
      • 2011-08-21
      • 2013-01-23
      • 1970-01-01
      • 2016-12-16
      • 2012-01-07
      • 2019-09-25
      • 2016-05-16
      相关资源
      最近更新 更多