C++:最强大的.NET语言之可访问性

  CLR定义了一些用于访问存取的修饰成分,其作用超越了本地C++中类成员函数与变量的对等物(如:public、private、protected),不仅如此,甚至还能定义命名空间或嵌套类型的可访问性。为了让C++/CLI达到作为低级语言的目标,除访问性之外,它还提供了比其他CLR平台高级语言更多的控制。

  本地C++可访问性与CLR中定义的可访问性相比,其最大不同之处在于:本地C++访问指示符通常用于限制同一程序中从其他代码访问类成员;而CLR定义的类型和成员的可访问性,不只是针对同一程序集中的其他代码,还针对从其他程序集中引用它的代码。

  一个命名空间,或非嵌套类型,如class或delegate类型,可在类型定义之前,通过加上public或private关键字来指定程序集之外的可见度。

public ref class ReferenceType {};
   如果显式地指定了可见度,对程序集来说,类型会被假定为私有类型(private)。

  类成员的访问指示符同样也被扩展,以允许一起使用两个关键字来指定来自内部和外部的访问。在这两个关键字中,限制更多的一者定义了来自程序集外的访问性,而另外一个则定义了程序集内的访问性。如果只用了一个关键字,那它将同时作用于内部与外部的访问性。这种设计思想对定义类型与类成员的可访问性提供了巨大的弹性,以下是示例:

public ref class ReferenceType
{
public:
//程序集内部与外部均可见
private public:
//只对程序集内部可见
protected public:
//对程序集内所有代码可见;对外部继承类型可见
};
  属性

  除嵌套类型之外,CLR类型只能包含方法与字段。为了让程序员更清楚地表达代码内涵,可使用元数据来指明某特定的方法将被编程语言当作属性。严格来说,一个CLR属性是它的包含类的一个成员,然而,属性没有分配的存储空间,它只是实现属性的各自方法的一个命名引用,而不同的编译器,碰到源代码中有关属性的语法时,将会生成各自所需的元数据。这就是说,类型的使用者,可在它们的语言中使用属性语法,来访问实现属性的get和set方法。与本地C++相比,C#对属性支持最好。

public string Name
{
get
{
return m_name;
}
set
{
m_name = value;
}
}
  C#编译器会生成对应的get_Name与set_Name方法,并且也会包含必要的元数据以指明其联系。在托管C++中,引入了关键字__property来指明一个在语义上实现属性的方法。

__property String* get_Name()
{
return m_value;
}
__property String* set_Name(String* value)
{
m_value = value;
}
  很明显,这不是理想的情况,不但需要使用这个"难看"的__property关键字,而且此处没有任何东西清楚地指明这两个成员函数实际上的联系,这在维护期间,会导致难以捉摸的bug。C++/CLI在对属性的设计上,就显得简明多了,更接近于C#的设计,而且你还会发现,这更强大。

property String^ Name
{
String^ get()
{
return m_value;
}
void set(String^ value)
{
m_value = value;
}
}
  这是一个非常大的改进,由编译器负责生成get_Name与set_Name方法和在此属性中声明的必要的元数据。更好的是,此属性值可对程序集外部保持只读,而对程序集内部为可写,也可以在紧接着属性名的花括号中使用访问指示符来达到这一目的。

property String^ Name
{
public:
String^ get();
private public:
void set(String^);
}
  最后一点无关痛痒的事是,在那此不需要对属性中get和set作特殊处理的地方,也可以使用简略表示法。

property String^ Name;
  再次提醒,编译器会生成get_Name与set_Name方法,但是这个时候,也会提供一个由private String ^ 成员变量支持的默认实现。其好处是,你可在将来某个时刻,用其他某种实现,来替换掉此处的简易属性,并且不会破坏类的接口。

代理

   本地C++中的函数指针,提供了一种异步执行代码的机制,你可以存储一个函数指针,而在以后有需要的时候及时地调用,这通常用于把某算法与实现代码分开来,如在搜索中比较对象。另外,它也可在不同的线程中调用,以实现真实的异步编程。以下是一个ThreadPool类的简单示例,允许你排列一系列的函数指针,并在工作者线程中执行。

class ThreadPool
{
public:

template <typename T>
static void QueueUserWorkItem(void (T::*function)(), T* object)
{
typedef std::pair<void (T::*)(), T*> CallbackType;
std::auto_ptr<CallbackType> p(new CallbackType(function, object));

if (::QueueUserWorkItem(ThreadProc<T>,
p.get(),
WT_EXECUTEDEFAULT))
{
//ThreadProc负责删除pair.
p.release();
}
else
{
AtlThrowLastWin32();
}
}

private:

template <typename T>
static DWORD WINAPI ThreadProc(PVOID context)
{
typedef std::pair<void (T::*)(), T*> CallbackType;
std::auto_ptr<CallbackType> p(static_cast<CallbackType*>(context));
(p->second->*p->first)();
return 0;
}

ThreadPool();
};
  在C++中使用线程池是简单兼自然的。

class Service
{
public:

void AsyncRun()
{
ThreadPool::QueueUserWorkItem(Run, this);
}

void Run()
{
//其他代码
}
}
  很明显,ThreadPool类是非常受限的,它只能接受特定的函数指针,这只是示例本身而不是C++本身的局限性。

  当C++程序员想要实现或得到用于异步编程的丰富库函数时,带着有此内置支持的CLR来了。"代理"与函数指针非常类似,除了针对的目标及方法属于的类型(其不能决定是否一个代理可以绑定于一个给定的方法);只要类型匹配,方法就能被代理,并在以后调用,与上面使用C++模板来实现允许接受任何类成员函数的例子比较,这在思想上是相似的。当然,代理还提供了更多且极其有用的间接函数调用的机制,以下是在C++/CLI中定义一个代理类型的示例:

delegate void Function();
  使用代理也非常直截了当。

ref struct ReferenceType
{
void InstanceMethod() {}
static void StaticMethod() {}
};

//创建代理并绑定到成员函数的实例
Function^ f = gcnew Function(gcnew ReferenceType, ReferenceType::InstanceMethod);

//也可绑定到静态成员函数,并结合几个代理形成代理链
f += gcnew Function(ReferenceType::StaticMethod);

//调用函数
f();
  结束语

  关于C++/CLI,真是说上几天也说不完,新的语言设计提供了空前的威力和绝无仅有的"优雅"语法,并且可在不牺牲简洁性、编程效率、执行效率的情况下,完全地使用C++来编写丰富的 .NET应用程序。

时间: 2025-01-31 06:03:33

C++:最强大的.NET语言之可访问性的相关文章

go语言通过odbc访问Sql Server数据库的方法_Golang

本文实例讲述了go语言通过odbc访问Sql Server数据库的方法.分享给大家供大家参考.具体如下: 这里需要用到go-odbc库,开源地址为:https://github.com/weigj/go-odbc 复制代码 代码如下: package main; import (     "fmt"     "database/sql"     _"odbc/driver" ) func main(){     conn,err := sql.O

增强网站的可访问性

访问 大多的互连网站都至少支持两个主要的浏览器的访问:Internet Explorer和网景浏览器.为什么呢?因为,如果你选择不支持这些浏览器中的任意一个,你就有可能失去一部分网站的访问者.当然,你希望确保你的网站通过合理的开销能够被尽可能多的人访问到.   保持着这种观点,你是否曾经考虑过你的网站对于有视力障碍的人而言有多大的可访问性?通过使用特殊的网页浏览器,这些有视力障碍的人们就可以自由地浏览网页了.但是,即使是使用最强大的技术支持,它还是不能够给视力障碍的人提供等同于那些非视力障碍人的

用户体验设计优化:内容可访问性

绝大多数同行接触可访问性可能都从W3C的WAI组织制定的WCAG1.0WCAG1.0(这几个英文缩写的关系很重要)开始,而国内设计师大多参考了Junchen在06年翻译的Web内容可访问性指南1.0(2008年12月11日已经发布WCAG2.0英文版)中文版,其中提到了保证页面设计良好呈现的几个关键因素,以及14条指南: 为视听的内容提供同等的文字替代: 不要仅依靠色彩来提供信息: 适当使用标记语言和样式表: 阐明自然语言的使用: 创建编排良好的表格: 确保页面能够在新技术下良好呈现: 确保使用

网站界面设计可访问性(Accessibility)

常见到网上博文有错误理论,包括身边很多朋友都曾认同"可访问性(Accessibility)是为残障人士准备"的观点.其实在互联网技术领域远不止这么简单,总结起来有三个方面: 应付极端环境下的正常浏览需求: 结构.表现.行为跨平台兼容支撑. 保障残障人士无障碍信息获取: web1.0网站以内容为主:web2.0网站以功能为主,有"纯内容.内容+功能.纯功能"三类互联网产品界面形态,格局基本已定型.虽然以内容为主的网站更突出Accessibility,以功能为主的网站更

《C++覆辙录》——1.8:未能区分可访问性和可见性

1.8:未能区分可访问性和可见性 C++语言压根儿没有实现什么数据隐藏,它实现了的是访问层级.在class中具有protected和private访问层级并非不可见,只是不能访问罢了.如同一切可见而不可及的事物一样(经理的形象跃入脑海),他们总是惹出各种麻烦. 最显而易见的问题就是即使是class的实现仅仅更改了一些貌似不可见的部分,也会带来必须重新编译代码的苦果.考虑一个简单的class,我们为其添加一个新的数据成员: class C { public: C( int val ) : a_(

利用CSS样式表改善网站可访问性

最近,我不得不对我的一个客户的旧网站进行更新,使得它能够达到可访问性的标准.对三四年前的旧代码进行挖掘的想法根本没有吸引力,主要是因为我曾经使用的很多编程惯例已经不再适用,特别是从可访问性上来讲.我曾经使用绝对的字体大小,固定的页面宽度和表格来做版面设计和空间分配. 像那时建构的很多网站一样,我的客户的网站使用了Cascading Style Sheets (CSS)来格式化文本.它没有使用任何CSS的更加强有力的版面设计功能,也没有允许HTML设备独立,而这是CSS可访问性的主要优点之一. 问

妙用CSS来改善网站可访问性

css|访问 最近,我不得不对我的一个客户的旧网站进行更新,使得它能够达到可访问性的标准.对三四年前的旧代码进行挖掘的想法根本没有吸引力,主要是因为我曾经使用的很多编程惯例已经不再适用,特别是从可访问性上来讲.我曾经使用绝对的字体大小,固定的页面宽度和表格来做版面设计和空间分配.   像那时建构的很多网站一样,我的客户的网站使用了Cascading Style Sheets (CSS)来格式化文本.它没有使用任何CSS的更加强有力的版面设计功能,也没有允许HTML设备独立,而这是CSS可访问性的

网站重构:利用CSS改善网站可访问性

css|访问|网站重构   最近,我不得不对我的一个客户的旧网站进行更新,使得它能够达到可访问性的标准.对三四年前的旧代码进行挖掘的想法根本没有吸引力,主要是因为我曾经使用的很多编程惯例已经不再适用,特别是从可访问性上来讲.我曾经使用绝对的字体大小,固定的页面宽度和表格来做版面设计和空间分配.   像那时建构的很多网站一样,我的客户的网站使用了Cascading Style Sheets (CSS)来格式化文本.它没有使用任何CSS的更加强有力的版面设计功能,也没有允许HTML设备独立,而这是C

改善网站可访问性,通过修改及利用CSS实现

css|访问 一个客户的旧网站需要更新,使得它能够达到可访问性的标准.对三四年前的旧代码进行挖掘的想法根本没有吸引力,主要是因为我曾经使用的很多编程惯例已经不再适用,特别是从可访问性上来讲.我曾经使用绝对的字体大小,固定的页面宽度和表格来做版面设计和空间分配.   像那时建构的很多网站一样,我的客户的网站使用了Cascading Style Sheets (CSS)来格式化文本.它没有使用任何CSS的更加强有力的版面设计功能,也没有允许HTML设备独立,而这是CSS可访问性的主要优点之一. 问题