在类构造函数中初始化结构体的正确方法 [英] Correct way of initializing a struct in a class constructor

查看:1065
本文介绍了在类构造函数中初始化结构体的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我想添加一个结构从c头文件作为类成员到c ++类。
但是对于 cpp 文件,我收到一个编译器错误: bar未在此范围中声明
这是我有:

So I want to add a struct from a c header file as a class member to a c++ class. But I get a compiler error for the cpp file: bar was not declared inn this scope. This is what I have:

//    myClass.hpp
#include fileWithStruct.h

class myClass
{
    public:
        struct foo bar;
};


//myClass.cpp

#include "myClass.hpp"

//Initialize structure in Constrcutor
myClass::myClass(  )
{
    bar = {1, 0, "someString", 0x4};
}


推荐答案

03样式

#include "fileWithStruct.h"
/* say the contents were
struct foo
{
   int foo1;
   float foo2;
};
*/

class myClass
{
    public:
        int val;
        foo bar;
        // since foo is a POD-struct (a.k.a C struct), no constructor would be present
        // however bar() will zero-initialize everything in the struct
        myClass() : val(), bar()
        {
        }
};

括号后的bar 事项。请参阅值和零初始化,了解为什么这样做。要注意的是,通过在 myClass 中添加一个构造函数,我们将其设置为非POD类型。要解决这个问题,可以保留myClass作为一个聚合,并写下:

The parentheses after bar matters. Refer value and zero-initialization to understand why this works. It is to be noted that by adding a constructor to myClass, we've made it a non-POD type. To work around this, one can retain myClass as an aggregate and write:

class myClass
{
    public:
        int val;
        foo bar;
};

int main()
{
   myClass zeroed_obj = { };
   myClass inited_obj = { 2, {0, 1.0f} };
   myClass partially_inited_obj = { 2 };    // equivalent to {2, {}}; which would zero all of myClass::bar
}

C ++ 11样式

class myClass
{
public:
   int val = { };         // zero-initialization
   foo bar = { 0, 0.0f }; // aggregate-initializing foo here, just giving { } will zero all of myClass::bar

   // should you want to receive an element from the constructor, this can be done too
   // aggregate initializing a struct in constructor initialization list is allowed from C++11 onwards
   // in C++03, we would've resorted to just setting the member of bar inside the constructor body
   myClass(int _foo1) : bar{_foo1, 0.f}, val{}
   {
   }

   // since we've a non-default constructor, we've to re-introduce the default constructor
   // if we need the above direct member initialization to work
   myClass() = default;
};

这里我们使用C ++ 11的统一初始化语法。然而,通过这样做 myClass 成为非POD类型;成员初始化类似于添加一个构造函数到类,从而使 myClass 一个非平凡但标准布局类。根据C ++ 11一个类是POD,它应该是微不足道和标准布局。而是

Here we use C++11's uniform initialization syntax. However, by doing this myClass becomes a non-POD type; member initialization is akin to adding a constructor to the class, thereby rendering myClass a non-trivial but standard-layout class. As per C++11 for a class to be POD it should be both trivial and standard-layout. Instead doing

#include "fileWithStruct.h"
#include <type_traits>
#include <iostream>

class myClass
{
public:
   int val;
   foo bar;
};

int main()
{
    myClass obj { }; // initializes val, bar.foo1 and bar.foo2 to 0
    myClass m { 0, {1, 2.0f} }; // initilizes each member separately
    std::cout << std::is_pod<myClass>::value << std::endl; // will return 1
}

将保留 myClass 作为POD。

will retain myClass as a POD.

请参阅这个优秀的帖子以了解有关聚合和POD的更多信息。

Refer to this excellent post to know more about aggregates and PODs.

这篇关于在类构造函数中初始化结构体的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆