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

特 性 Attributes 2.014

阅读更多
以下“属性”都应改为“特性”

属性指示器:
属性 :
属性 声明定义块
属性:
连接属性
对齐属性
Pragma
deprecated
ProtectionAttribute
static
final
override
abstract
const
auto
scope
单个声明块
单个声明定义
{ }
{ 多个声明定义 }


属性指的是用来修改一个或多个声明的方法。一般的形式有:

attribute declaration; 仅对该声明有效
attribute: 对所有声明都有效,直到
当前作用域的结尾
declaration;
declaration;
...
attribute              对语句块中所有的声明都有效
{
declaration;
declaration;
...
}

对于出现在可选的 else 子句中的声明:
attribute
declaration;
else
declaration;
attribute                对语句块中所有的声明都有效
{
declaration;
declaration;
...
}
else
{
declaration;
declaration;
...
}

6.1 连接属性(Linkage Attribute)
连接属性:
extern
extern ( 连接类型 )

连接类型:
C
C++
D
Windows
Pascal
System

D 提供了一种方便的调用 C 函数和操作系统 API 函数的方法,因为对这两者的兼容都是必
要的。链接类型 是大小写敏感的,并且可以由具体实现进行扩展(但它们不能是关键
字)。C 和 D 是必须要有的,其它的则取决于具体的实现。C++ 被保留以便将来使用。
System 在 Windows 平台里等同于 Windows;而对于其它平台,则等同于 C。实现注意:
对于 Win32 平台,Windows 和 Pascal 应该总是存在。

通过下面的方式指定 C 函数调用约定:
extern (C):
int foo(); // 使用 C 协定调用 foo()

D 调用协定是:
extern (D):
或者:
extern:
Windows API 调用协定是:
extern (Windows):
void *VirtualAlloc(
void *lpAddress,
uint dwSize,
uint flAllocationType,
uint flProtect
);


2 对齐属性(Align Attribute)
对齐属性:
align
align ( Integer )
指定结构成员如何对齐。如果只有align 则设为默认值,即使用同对应的 C 编译器相同的默
认对齐值。整数 指定了对齐的值,它的行为同对应的 C 编译器使用非默认的对齐值时相
同。

匹配其它 C 编译器的行为可能会产生一些令人惊讶的结果,例如下面的可用于 Digital Mars
C++:
struct S
{ align(4) byte a; // 被放置到了偏移 0 处
align(4) byte b; // 被放置到了偏移 1 处
}

“对齐属性”用于兼容 C ABI,这个跟跨平台的二进制兼容是不一样的。对于它,使用压缩
的结构:
align (1) struct S
{ byte a; // 被放置到了偏移 0 处
byte[3] filler1;
byte b; // 被放置到了偏移 4 处
byte[3] filler2;
}

值 1 表示不进行对齐;成员被压缩在一起。
不对使用“New表达式”在不是 size_t 的倍数的边界上分配的引用或指针进行对齐操
作。垃圾回收器假定 gc 所分配对象的指针和引用是在 size_t 字节边界上。如果不是那
些,就会导致未定义行为。

在被应用到那些不是结构或结构成员的声明时,“对齐属性”会被忽略掉。

3 废弃属性(Deprecated Attribute)
我们经常会将库中的某一属性标记为废弃,同时仍然保留它以保持向后兼容。这类声明可以
被标记为废弃,这意味着可以通过设置编译器选项,在遇到引用这类声明的代码时产生错
误:
deprecated
{
void oldFoo();
}

实现注意: 编译器应该有一个选项用来指定是否被废弃的属性可以通过编译。

4 保护属性(Protection Attribute)
ProtectionAttribute:
private
package
protected
public
export

可用的保护属性有:private、package、protected、public 或 export。

private(私有的)表示只有本类的成员,或者跟该类处于同一模块内的成员和函数,才可以
访问该成员。私有成员不能被重写。私有模块成员等价于 C 程序中的 static 声明。

package(包)扩展了 private 的访问权限,这样包中的成员就可以访问位于同一包内的其他的模块内的成员。如果一个模块位于嵌套的包,那么这条规则只对最里层的包有效。

protected(受保护的)表示只有本类的成员,或者所有自它派生的类的成员,或者跟该类处于同一模块内的成员和函数,才可以访问该成员。如果通过一个派生类成员函数访问一个被
保护的实例成员,则访成员仅能被那些是该成员函数调用的“this”对象实例访问。模块成员进行保护是非法的。

public(公有的)表示在可执行程序中的任何代码都可以访问这个成员。

export(导出)表示可执行程序外的任何代码都可以访问这个成员。导出的意思也就是从
DLL 中导出定义。

5 常量属性(Const Attribute)
const

const 属性声明可以在编译时进行求值的常量。例如:
const int foo = 7;
const
{
double bar = foo + 6;
}

这一段2.014里没有,其余一样。
没有初始值的 const 声明在构造函数里(对于类字段)或者在静态构造函数里(对于静态类
成员或模块变量声明)必须被初始化。

const int x;
const int y;
static this()
{
x = 3; // 正确
// 错误:y 未被初始化
}

void foo()
{
x = 4; // 错误,x 是 const 并且不在静态构造函数里
}

class C
{
const int a;
const int b;
static const int c;
static const int d;

this()
{ a = 3; // 正确
a = 4; // 正确,允许重复初始化
C p = this;
p.a = 4; // 错误,只能是 this 实例的成员
c = 5; // 错误,应该在静态构造函数里进行初始化
// 错误,b 未被初始化
}

this(int x)
{
this(); // 正确,传送构造函数
}

static this()
{
c = 3; // 正确
// 错误,d 未被初始化
}
}

如果没有构造函数,让 const 模块变量声明没有初始值并不是个错误。这个用于支持让模块
服务仅做为不被连接的声明,而其实现将会放置在另一个要链接模块里。



6 重写属性(Override Attribute)
override
override 属性用于虚函数。即表示该函数一定会重写(override)在基类里具有相同的名字和参数函数。当某个基类的成员函数的参数变化时,override 属性有助于捕获错误;而且,这也要求所有派生类都必须更新它们的重写函数。

class Foo
{
int bar();
int abc(int x);
}

class Foo2 : Foo
{
override
{
int bar(char c); // 错误,Foo 中没有 bar(char)
int abc(int x); // 正确
}
}


7 静态属性(Static Attribute)
static
static 属性用于函数和数据。即表示此声明不能应用于一个对象的特定实例,不过可以应用
于对象的类型。换句话说,就是不存在 this 引用。当用于其他声明时, static 会被忽略。

class Foo
{
static int bar() { return 6; }
int foobar() { return 7; }
}
...
Foo f = new Foo;
Foo.bar(); // 得到 6
Foo.foobar(); // 错误,没有 Foo 的实例
f.bar(); // 得到 6;
f.foobar(); // 得到 7;

静态函数决不能是虚的(vitual)。

在整个程序中,静态数据只有一个实例,而不能每个对象都有一个。

static 并没有 C 中那样局限于一个文件的功能。在 D 里,可以使用 private 属性来实现它。

例如:
module foo;
int x = 3; // x 是全局的
private int y = 4; // y 仅限于模块 foo 中有效

8 自动属性(Auto Attribute)
auto
auto 属性用于局部变量和类声明。
auto i = 6.8; // 声明 i 为 double

9 域属性(Scope Attribute)
scope
scope 属性用于局部变量和类声明。对于类声明,scope 属性会创建一个 scope 类。对于局部变量,scope 实现RAII(资源获得即初始化)协议。即表示对象的析构函数自动被调用,当对它的引用 超出作用域时。即使通过抛出异常退出了该作用域,析构函数还是会被调
用,这样 scope 就被用来保证清除工作。

如果有不只一个 scope 变量超出了同一个点的作用域,那么析构函数会依着跟创建这些变量
时相反的顺序被调用。

scope 不能用于全局变量、静态变量、数据成员,以用 ref 或 out 参数。scope 数组是不被允许的,并且 scope 函数返回值也是不允许的。分配一个 scope,而不是初始化,同样不被允许。

基本解释: 这些限制在将来可能被放松,如果理由充分的话。

10 抽象属性(Abstract Attribute)
如果一个类是抽象,那么它就不能被直接实例化。它只能被当作另一个非抽象类的基类进行
实例化。

如果类被定义时,内部有一个抽象属性(abstract attribute),或者在它内部的某些虚成员函数被声明成抽象的,那么这个类就是抽象的。

非虚函数不能被声明成抽象的。

函数声明成抽象的仍然可以拥有函数体。这就是为什么即使它们必须被重写(override),仍然能够提供“基类功能。”



。。。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics