C++:最強大的.NET語言之可訪問性
C LR 定義了一些用于訪問存取的修飾成分,其作用超越了本地C++中類成員函數與變量的對等物(如:public、private、protected),不僅如此,甚至還能定義命名空間或嵌套類型的可訪問性。為了讓C++/CLI達到作為低級語言的目標,除訪問性之外,它還提供了比其他
C
LR定義了一些用于訪問存取的修飾成分,其作用超越了本地
C++中類成員函數與變量的對等物(如:public、private、protected),不僅如此,甚至還能定義命名空間或嵌套類型的可訪問性。為了讓
C++/CLI達到作為低級語言的目標,除訪問性之外,它還提供了比其他CLR平臺高級語言更多的控制。
本地C++可訪問性與CLR中定義的可訪問性相比,其最大不同之處在于:本地C++訪問指示符通常用于限制同一程序中從其他代碼訪問類成員;而CLR定義的類型和成員的可訪問性,不只是針對同一程序集中的其他代碼,還針對從其他程序集中引用它的代碼。
一個命名空間,或非嵌套類型,如class或delegate類型,可在類型定義之前,通過加上public或private關鍵字來指定程序集之外的可見度。
clearcase/" target="_blank" >cccccc" width="90%" align="center" bgcolor="#e3e3e3" border="1">
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作特殊處理的地方,也可以使用簡略表示法。
再次提醒,編譯器會生成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應用程序。
原文轉自:http://www.kjueaiud.com
- 評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)
-
老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月
|