`
hqs7636
  • 浏览: 220975 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

结构 & 联合 2.014

阅读更多
尽管类是引用类型,而结构是值类型。任何 C 结构都可以被准确的表示为 D 结构。按照 C
++ 说法,D 结构是一种 POD (普通旧数据) 类型,且带有无关紧要的构造函数和析构函数。

结构和联合 用于表示简单的 数据聚集,或者用作这样一种方式——在硬件上 的描绘数据结构 或者描绘一种 外部类型。

外部类型 可以被 操作系统的 API 定义,或者被文件格式定义。面向对象功能 提供有 类数据类型。

一个结构被定义成不带身份标识;即是说,它的实现是自由的,可以很方便进行结构的 位复
制。

                             
  结构、类比较表
=============================================================
 功  能          struct      class   C 结构   C++ 结构     C++ 类
值类型               X                  X        X          X
引用类型                          X
数据成员             X          X       X        X          X
隐藏成员                          X                X          X
静态成员             X          X                X          X

默认成员初始值       X          X
位域                                        X        X          X

非虚成员函数         X          X                 X          X
虚成员函数                        X                 X          X
构造函数                          X                 X          X

postblit/copy  2.014
constructors      X                            X          X 

析构函数                          X                 X          X

RAII              X 2.014     X                 X          X 
assign overload   X                             X         X 


literals          X

运算符重载           X          X                  X         X

继承                              X                  X         X
不变量               X          X
单元测试             X          X
同步                              X
可参数化             X          X                  X          X

对齐控制             X          X
成员保护             X          X                   X         X
默认公有             X          X         X         X
标记名字空间                                  X         X         X
匿名                 X                     X         X         X

2.014 新添3个
static constructor X         X       
static destructor  X         X       
const/invariant    X         X 


================================================================


聚集声明:
标记 标识符 结构体
标记 标识符 ;

标记:
struct
union

结构体:
{ }
{ 多个结构体声明 }

多个结构体声明:
单个结构体声明
单个结构体声明 多个结构体声明

单个结构体声明:
单个声明
静态构造函数
静态析构函数
不变量
单元测试
结构分配器
结构释放器

StructPostblit  2.014
StructDestructor




结构分配器:
类分配器

结构释放器:
类释放器

它们同在 C 中的结构基本一样,除了以下一些例外:
• 没有位域
• 可以显式指定对齐
• 没有单独的标记名字空间——标记名 并入当前的作用域
• 像下面的声明:
struct ABC x;  是不允许的,

正确方法是:
ABC x;

• 匿名结构/联合可以作为 其他结构/联合的 成员 存在
• 可以为成员提供 默认初始值
• 可以拥有 成员函数和静态成员


1 结构的静态初始化

如果不提供初始值,静态结构成员会被默认地初始化为 成员类型 的初始值。如果提供了静态
初始值,成员会按照这样的语法初始化:成员名,冒号,表达式。

成员可以按照任意顺序初始化。

没有出现在 初始化列表中 的成员会被 默认值初始化。

struct X { int a; int b; int c; int d = 7;}
static X x = { a:1, b:2}; // c 被设置为 0, d 为 7
static X z = { c:4, b:5, a:2 , d:5}; // z.a = 2, z.b = 5, z.c = 4, z.d = 5

C 风格的初始化,依赖于结构声明中的 成员的顺序,也是被支持的:
static X q = { 1, 2 }; // q.a = 1, q.b = 2, q.c = 0, q.d = 7


2 联合的静态初始化

联合需要 显式 地初始化。

union U { int a; double b; }
static U u = { b : 5.0 }; // u.b = 5.0

如果联合的其他 成员 占用的存储空间更大,剩下的部分被初始化为零。


3 结构的动态初始化

结构可以被来自于另一个 相同类型值 动态初始化:

struct S { int a; }
S t; // 默认初始化
t.a = 3;
S s = t; // s.a 被设置为 3

如果重写(override)了该结构的 opCall,同时使用一个不同类型的值来初始化此结构,那么 opCall 操作就会被调用:

struct S
{ int a;
static S opCall(int v)
{ S s;
s.a = v;
return s;
}

static S opCall(S v)
{ S s;
s.a = v.a + 1;
return s;
}
}
S s = 3; // 把 s.a 设置为 3
S t = s; // 把 t.a 设置成 3,而 S.opCall(s) 没有被调用  (同类型)


4 结构字法

结构字法由结构的 名字跟上带括号的 参数列表 组成:

struct S { int x; float y; }
int foo(S s) { return s.x; }
foo( S(1, 2) ); // set field x to 1, field y to 2

结构字法在句法等同于函数调用。

如果一个结构有一个名叫 opCall 的成员函数,那么此结构的结构文字就是可用的。
如果参数多于了结构里域的个数,那么这样就会产生错误。
如果参数个数比域个数更少,则多余的域则会使用它们各自的默认初始值进行初始化。
如果结构里有匿名联合,那么就只有匿名联合的第一个成员可以使用结构文字进行初始化,而且其余的非重迭域会被默认初始化。


5 结构特性

.sizeof      以字节为单位的结构大小
.alignof     需要对齐结构的大小边界
.tupleof     获得域(field)的 Tuple 类型


11.6 结构域特性

.offsetof     相对结构 开始处 的域 偏移字节数

  2.014

11.7 Const and Invariant Structs

A struct declaration can have a storage class of const or invariant. It has an equivalent effect as declaring each member of the struct as const or invariant. 

const struct S { int a; int b = 2; }

void main()
{
    S s = S(3);    // initializes s.a to 3
    S t;           // initializes t.a to 0
    t = s;         // ok, t.a is now 3
    t.a = 4;       // error, t.a is const
}
Struct Postblits
StructPostblit:
    this(this) FunctionBody
Copy construction is defined as initializing a struct instance from another struct of the same type. Copy construction is divided into two parts:

blitting the fields, i.e. copying the bits 
running postblit on the result 
The first part is done automatically by the language, the second part is done if a postblit function is defined for the struct. The postblit has access only to the destination struct object, not the source. Its job is to 'fix up' the destination as necessary, such as making copies of referenced data, incrementing reference counts, etc. For example: 

struct S
{
   int[] a;    // array is privately owned by this instance
   this(this)
   {
       a = a.dup;
   }
   ~this()
   {
       delete a;
   }
}
Struct Destructors
StructDestructor:
    ~this() FunctionBody
Destructors are called when an object goes out of scope. Their purpose is to free up resources owned by the struct object. 

Assignment Overload
While copy construction takes care of initializing an object from another object of the same type, assignment is defined as copying the contents of one object over another, already initialized, type: 

struct S { ... }
S s;      // default construction of s
S t = s;  // t is copy-constructed from s
t = s;    // t is assigned from s
Struct assignment t=s is defined to be semantically equivalent to: 

t = S.opAssign(s);
where opAssign is a member function of S:

S* opAssign(S s)
{   ... bitcopy *this into tmp ...
    ... bitcopy s into *this ...
    ... call destructor on tmp ...
    return this;
}
While the compiler will generate a default opAssign as needed, a user-defined one can be supplied. The user-defined one must still implement the equivalent semantics, but can be more efficient. 

One reason a custom opAssign might be more efficient is if the struct has a reference to a local buffer: 

struct S
{
    int[] buf;
    int a;

    S* opAssign(ref const S s)
    {
	a = s.a;
	return this;
    }

    this(this)
    {
	buf = buf.dup;
    }

    ~this()
    {
	delete buf;
    }
}
Here, S has a temporary workspace buf[]. The normal postblit will pointlessly free and reallocate it. The custom opAssign will reuse the existing storage. 




。。。。。
分享到:
评论

相关推荐

    C#程序开发范例宝典(第2版).part08

    实例014 OutLook界面 11 实例015 带导航菜单的主界面 12 实例016 图形化的导航界面 14 1.5 特色程序界面 15 实例017 隐藏式窗体 15 实例018 类似Windows XP的程序界面 18 实例019 软件启动界面 19 实例020 以...

    Visual C++程序开发范例宝典(PDF扫描版).part2

     cc实例014 具有提示功能的工具栏   1.4 状态栏应用实例   cc实例015 带进度条的状态栏   cc实例016 动画效果的状态栏   cc实例017 滚动字幕的状态栏   1.5 导航界面应用实例   cc实例018 ...

    125集专攻JAVA基础 JAVA零基础入门学习视频教程 动力节点JAVA视频教程.txt

    北京动力节点-Java编程零基础教程-089-Java基本语法-控制语句-if语句程序举例2.avi 北京动力节点-Java编程零基础教程-090-Java基本语法-控制语句-switch语句-基本语法.avi 北京动力节点-Java编程零基础教程-091-...

    C#程序开发范例宝典(第2版).part12

    实例014 OutLook界面 11 实例015 带导航菜单的主界面 12 实例016 图形化的导航界面 14 1.5 特色程序界面 15 实例017 隐藏式窗体 15 实例018 类似Windows XP的程序界面 18 实例019 软件启动界面 19 实例020 以...

    C#程序开发范例宝典(第2版).part13

    实例014 OutLook界面 11 实例015 带导航菜单的主界面 12 实例016 图形化的导航界面 14 1.5 特色程序界面 15 实例017 隐藏式窗体 15 实例018 类似Windows XP的程序界面 18 实例019 软件启动界面 19 实例020 以...

    C#程序开发范例宝典(第2版).part02

    实例014 OutLook界面 11 实例015 带导航菜单的主界面 12 实例016 图形化的导航界面 14 1.5 特色程序界面 15 实例017 隐藏式窗体 15 实例018 类似Windows XP的程序界面 18 实例019 软件启动界面 19 实例020 以...

    Visual C++程序开发范例宝典(PDF扫描版).part3

     cc实例014 具有提示功能的工具栏   1.4 状态栏应用实例   cc实例015 带进度条的状态栏   cc实例016 动画效果的状态栏   cc实例017 滚动字幕的状态栏   1.5 导航界面应用实例   cc实例018 ...

Global site tag (gtag.js) - Google Analytics