Aggregate POD and initialize struct to 0
2016-03-02 12:01
260 查看
Aggregate class and POD
http://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-and-how-why-are-they-special/4178176#4178176
An aggregate is an array or a class (clause 9) with no user-declared constructors (12.1), no
private or protected non-static data members (clause 11), no base classes (clause 10), and no virtual functions (10.3).
Now let's see how aggregates are special. They, unlike non-aggregate classes, can be initialized with curly braces
This initialization syntax is commonly known for arrays, and we just learnt that these are aggregates
POD
An aggregate class is called a POD if it has no user-defined copy-assignment operator and destructor
and none of its nonstatic members is a non-POD class, array of non-POD, or a reference.
Initialize struct to 0
两种 http://stackoverflow.com/questions/1998752/memset-or-value-initialization-to-zero-out-a-struct
1.
or
2.STRUCT
theStruct ={};
具体的例子
In this case writing a
being set to zero-value in case of
Since you don't have access to those bytes normally, there's no difference for you.
On the other hand, since you've tagged your question as C++, let's try another example, with member types
different from POD:
In this case using an expression like
it will lead to crash. Here's what happens if you use
an object of type
created, thus creating an object of type
since it's a member of our structure. Next,
the memory where the object
located to certain value, say zero. Now, once our TestStruct object goes out of scope, it is going to be destroyed and when the turn comes to it's member
作者:一根筋的傻瓜
链接:https://www.zhihu.com/question/36379130/answer/69853366
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
POD,全称plain old data,plain代表它是一个普通类型,old代表它可以与c兼容,可以使用比如memcpy()这类c中最原始函数进行操作。C++11中把POD分为了两个基本概念的集合,即:平凡的(trival)和标准布局的(standard layout)。
首先是平凡的(trival)定义,通常一个平凡的类或者结构体需要满足以下定义:
拥有平凡的默认构造函数和析构函数。默认的意思就是由编译器为我们自动生成的,不许是我们自己定义的,但是由于c++11提供了default,也可以是自己定义的加=default,比如
struct Trival{
Trival(){}=default;
}
就是满足这个要求的,而
struct noTrival{
noTrival(){};
}
就不满足这个要求(哪怕我们定义的构造函数体里面啥都没有)。这个要求对于带参的构造函数没有束缚。你可以自定义带参的构造函数。只要不是默认的就好
拥有平凡的拷贝构造函数和移动构造函数。默认的意思同上,也可以使用=default。
拥有平凡的拷贝赋值操作符和移动赋值操作符。
不能包含虚函数和虚基类。
2.接下来是标准布局的定义:standard layout
所有非静态成员拥有相同的访问级别,(访问级别就是public,private,protected),
struct t1{
private :
int a;
public:
int b;
}就不满足标准布局,因为a,b访问级别不同。
在类和结构体继承时需要满足以下两个情况之一:
派生类中有非静态类,那么这个派生类只能有且只有一个仅包含了静态成员的基类。
基类有非静态成员,那么派生类中不允许有非静态成员。
(这两句话看着挺绕口,其实就是在说明一个事实,关于非静态数据的事实,派生类中有非 静态的数据那么它的基类只能是只有静态的,而且基类只能有一个。如果基类有非静态的, 那么派生类就不能有非静态的。有种跷跷板的感觉,非静态的对面坐着的是静态,父子类就 是坐在跷跷板的两端这种对应关系。)
类中第一个非静态类型与基类不是同一个类型。比如
struct A:B{
B b;
int c;
}就不符合这个条件。因为A中第一个成员是基类B类型的。
没有虚类和虚基类(与trival中重复)
所有非静态数据成员都符合标准布局的要求,这其实就是一个递归的定义。
所以在C++11中,POD就是满足平凡的(trival)和标准布局(standard layout)这两个方面。可以使用<type_traits>中的is_pod<T>::value判断T是不是POD类型的。
说了这么多,那么为什么我们需要POD这种条件满足的数据呢?
可以使用字节赋值,比如memset,memcpy操作
对C内存布局兼容。
保证了静态初始化的安全有效。
同时 我在自己的code里面也遇到
Don't
use malloc in C++ (unless you absolutely know what youre doing)
https://stackoverflow.com/questions/30579430/access-violation-writing-location-0xcdcdcdcd
The
contains an object of type
The
called before you can use the
If you allocate memory using the C++
then the constructor is automatically called, and the
properly initialized.
But if you allocate memory using the C
then the
is not called.
The
from an uninitialized pointer in the string object that should have been initialized by the constructor (but wasn't because the constructor was not called).
http://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-and-how-why-are-they-special/4178176#4178176
An aggregate is an array or a class (clause 9) with no user-declared constructors (12.1), no
private or protected non-static data members (clause 11), no base classes (clause 10), and no virtual functions (10.3).
Now let's see how aggregates are special. They, unlike non-aggregate classes, can be initialized with curly braces
{}.
This initialization syntax is commonly known for arrays, and we just learnt that these are aggregates
POD
An aggregate class is called a POD if it has no user-defined copy-assignment operator and destructor
and none of its nonstatic members is a non-POD class, array of non-POD, or a reference.
Initialize struct to 0
两种 http://stackoverflow.com/questions/1998752/memset-or-value-initialization-to-zero-out-a-struct
1.
STRUCT theStruct; memset( &theStruct, 0, sizeof( STRUCT ) );
or
2.STRUCT
theStruct ={};
具体的例子
struct POD_OnlyStruct { int a; char b; }; POD_OnlyStruct t = {}; // OK POD_OnlyStruct t; memset(&t, 0, sizeof t); // OK as well
In this case writing a
POD_OnlyStruct t = {}or
POD_OnlyStruct t; memset(&t, 0, sizeof t)doesn't make much difference, as the only difference we have here is the alignment bytes
being set to zero-value in case of
memsetused.
Since you don't have access to those bytes normally, there's no difference for you.
On the other hand, since you've tagged your question as C++, let's try another example, with member types
different from POD:
struct TestStruct { int a; std::string b; }; TestStruct t = {}; // OK { TestStruct t1; memset(&t1, 0, sizeof t1); // ruins member 'b' of our struct } // Application crashes here
In this case using an expression like
TestStruct t = {}is good, and using a
memseton
it will lead to crash. Here's what happens if you use
memset-
an object of type
TestStructis
created, thus creating an object of type
std::string,
since it's a member of our structure. Next,
memsetsets
the memory where the object
bwas
located to certain value, say zero. Now, once our TestStruct object goes out of scope, it is going to be destroyed and when the turn comes to it's member
std::string byou'll see a crash, as all of that object's internal structures were ruined by the
memset.
作者:一根筋的傻瓜
链接:https://www.zhihu.com/question/36379130/answer/69853366
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
POD,全称plain old data,plain代表它是一个普通类型,old代表它可以与c兼容,可以使用比如memcpy()这类c中最原始函数进行操作。C++11中把POD分为了两个基本概念的集合,即:平凡的(trival)和标准布局的(standard layout)。
首先是平凡的(trival)定义,通常一个平凡的类或者结构体需要满足以下定义:
拥有平凡的默认构造函数和析构函数。默认的意思就是由编译器为我们自动生成的,不许是我们自己定义的,但是由于c++11提供了default,也可以是自己定义的加=default,比如
struct Trival{
Trival(){}=default;
}
就是满足这个要求的,而
struct noTrival{
noTrival(){};
}
就不满足这个要求(哪怕我们定义的构造函数体里面啥都没有)。这个要求对于带参的构造函数没有束缚。你可以自定义带参的构造函数。只要不是默认的就好
拥有平凡的拷贝构造函数和移动构造函数。默认的意思同上,也可以使用=default。
拥有平凡的拷贝赋值操作符和移动赋值操作符。
不能包含虚函数和虚基类。
2.接下来是标准布局的定义:standard layout
所有非静态成员拥有相同的访问级别,(访问级别就是public,private,protected),
struct t1{
private :
int a;
public:
int b;
}就不满足标准布局,因为a,b访问级别不同。
在类和结构体继承时需要满足以下两个情况之一:
派生类中有非静态类,那么这个派生类只能有且只有一个仅包含了静态成员的基类。
基类有非静态成员,那么派生类中不允许有非静态成员。
(这两句话看着挺绕口,其实就是在说明一个事实,关于非静态数据的事实,派生类中有非 静态的数据那么它的基类只能是只有静态的,而且基类只能有一个。如果基类有非静态的, 那么派生类就不能有非静态的。有种跷跷板的感觉,非静态的对面坐着的是静态,父子类就 是坐在跷跷板的两端这种对应关系。)
类中第一个非静态类型与基类不是同一个类型。比如
struct A:B{
B b;
int c;
}就不符合这个条件。因为A中第一个成员是基类B类型的。
没有虚类和虚基类(与trival中重复)
所有非静态数据成员都符合标准布局的要求,这其实就是一个递归的定义。
所以在C++11中,POD就是满足平凡的(trival)和标准布局(standard layout)这两个方面。可以使用<type_traits>中的is_pod<T>::value判断T是不是POD类型的。
说了这么多,那么为什么我们需要POD这种条件满足的数据呢?
可以使用字节赋值,比如memset,memcpy操作
对C内存布局兼容。
保证了静态初始化的安全有效。
同时 我在自己的code里面也遇到
Don't
use malloc in C++ (unless you absolutely know what youre doing)
https://stackoverflow.com/questions/30579430/access-violation-writing-location-0xcdcdcdcd
ptrStack stack = (ptrStack)malloc(sizeof(Stack));
The
Stackstructure
contains an object of type
string.
The
stringconstructor must be
called before you can use the
string.
If you allocate memory using the C++
newoperator,
then the constructor is automatically called, and the
stringis
properly initialized.
But if you allocate memory using the C
mallocfunction,
then the
stringconstructor
is not called.
The
0xCDCDCDCDcomes
from an uninitialized pointer in the string object that should have been initialized by the constructor (but wasn't because the constructor was not called).
相关文章推荐
- 初窥Scrapy(Py3.x)
- 顶层 const 与底层 const
- 【python】scrapy安装
- PhPStorm 快捷键使用(转载)
- 初窥Scrapy(Py3.x)
- 迭代输出字典键值对
- 博客第一天
- 百度cdn静态文件缓存出现520
- 山重水复疑无路,柳暗花明又一村
- LeetCode OJ刷题历程——Add Two Numbers
- raywenderlich-iOS设计模式Part 1/2【译】
- 面向对象开发程序思路
- (转)几种开放源码的TCPIP协议栈概述
- PE结构解析;
- glibc中内存管理
- HDU 4978 A simple probability problem
- MySQL 常见的sql命令
- myeclipse10安装findbugs
- 算法笔记-0302
- JVM锁实现探究2:synchronized深探