在类构造函数中初始化结构的正确方法
所以我想将c头文件中的结构体作为类成员添加到c++类中.但是我收到 cpp
文件的编译器错误:bar was not Declaration inn this scope
.这就是我所拥有的:
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};
}
推荐答案
C++03 Style
#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 following 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
myClass garbage_obj; // warning: when left uninitialized, every member without a constructor will end up with garbage value
}
C++11 风格
class myClass
{
public:
// default member initializations
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) : val{}, bar{_foo1, 0.f}
{
}
// since we've a non-default constructor, we've to re-introduce the default constructor
// if we need the above in-class 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.
相关文章