部分類別 (C++/CX)
部分類別是支援下列案例的建構:您要修改一部分的類別定義,而自動產生程式碼軟體 (例如 XAML 設計工具) 也在相同的類別中修改程式碼。 使用部分類別可防止設計工具覆寫您的程式碼。 在 Visual Studio 專案中,會對產生的檔案自動套用 partial
修飾詞。
語法
若要定義部分類別,請在原本是一般類別定義之項目的類別識別碼之前使用 partial
關鍵字。 partial ref class
之類的關鍵字是包含空白字元的內容關鍵字。 支援部分定義的建構如下。
class
或struct
ref class
或ref struct
value class
或value struct
enum
或enum class
ref interface
、interface class
、interface struct
或__interface
union
下列範例說明部分 ref class
:
partial ref class MyClass {/* ... */};
目錄
如果省略 partial
關鍵字,部分類別定義即可包含完整類別定義所能包含的任何項目。 除了一項例外狀況,這包括任何有效的建構,例如基底類別、資料成員、成員函式、列舉、friend 宣告和屬性。 此外也允許靜態資料成員的內嵌定義。
這項例外狀況是類別存取範圍。 例如,陳述式 public partial class MyInvalidClass {/* ... */};
是錯誤。 MyInvalidClass 的部分類別定義中所使用的任何存取規範,對於 MyInvalidClass 後續的部分或完整類別定義中的預設存取範圍都不會有影響。
下列程式碼片段示範存取範圍。 在第一個部分類別中, Method1
是公用的,因為其存取範圍是公用的。 在第二部分類別中, Method2
是私用的,因為預設的類別存取範圍是私用的。
partial ref class N
{
public:
int Method1(); // Method1 is public.
};
ref class N
{
void Method2(); // Method2 is private.
};
宣告
這類 MyClass
類別的部分定義只是 MyClass 的宣告。 也就是說,它只會引進名稱 MyClass
。 MyClass
無法以需要類別定義的方式使用,例如,知道 的大小 MyClass
或使用 的基底或成員 MyClass
。 MyClass
只有在編譯器遇到 非部分定義的 時,才會被視為已定義 MyClass
。
下列範例示範部分類別的宣告行為。 宣告 #1 之後, MyClass
可以使用它,就像是撰寫為正向宣告 。 ref class MyClass;
宣告 #2 相當於宣告 #1。 宣告 #3 有效,因為它是類別的正向宣告。 然而,宣告 #4 則無效,因為
MyClass
未完全定義。
宣告 #5 不會使用 partial
關鍵字,而且宣告會 MyClass
完整定義 。 最後,宣告 #6 是有效的。
// Declaration #1
partial ref class MyClass {};
// Declaration #2
partial ref class MyClass;
// Declaration #3
MyClass^ pMc; // OK, forward declaration.
// Declaration #4
MyClass mc; // Error, MyClass is not defined.
// Declaration #5
ref class MyClass { };
// Declaration #6
MyClass mc; // OK, now MyClass is defined.
數目與順序
類別的每個完整定義都可以有零個或多個部分類別定義。
類別的每個部分類別定義在語彙上皆必須位於該類別的一個完整定義之前,但不一定要位於該類別的向前宣告之前。 如果類別沒有完整定義,部分類別宣告就只能是向前宣告。
所有的類別識別碼 (如 class
和 struct
) 都必須相符。 例如,下列程式碼是錯誤的: partial class X {}; struct X {};
這個名稱而已。
下列範例示範數目與順序。 最後一個部分宣告會失敗,因為類別已定義。
ref class MyClass; // OK
partial ref class MyClass{}; //OK
partial ref class MyClass{}; // OK
partial ref class MyClass{}; // OK
ref class MyClass{}; // OK
partial ref class MyClass{}; // C3971, partial definition cannot appear after full definition.
完整定義
在進行類別 X 的完整定義時,運作方式會如同 X 的定義已宣告所有的基底類別、成員等項目 (宣告順序取決於在部分類別中發現及定義這些項目的順序)。 也就是說,部分類別的內容會如同已在進行類別的完整定義時撰寫,而在進行類別的完整定義時會套用名稱查閱與其他語言規則,如同部分類別的內容已撰寫。
下列兩個程式碼範例具有相同的意義和效用。 第一個範例會使用部分類別,第二個範例則否。
ref class Base1 { public: property int m_num; int GetNumBase();};
interface class Base2 { int GetNum(); };
interface class Base3{ int GetNum2();};
partial ref class N : public Base1
{
public:
/*...*/
};
partial ref class N : public Base2
{
public:
virtual int GetNum();
// OK, as long as OtherClass is
//declared before the full definition of N
void Method2( OtherClass^ oc );
};
ref class OtherClass;
ref class N : public Base3
{
public:
virtual int GetNum2();
};
ref class OtherClass;
ref class N : public Base1, public Base2, public Base3
{
public:
virtual int GetNum();
virtual int GetNum2();
private:
void Method2(OtherClass^ oc);
};
範本
部分類別不可做為樣板。
限制
部分類別不可延伸到其他轉譯單位。
partial
關鍵字必須與 ref class
關鍵字或 value class
關鍵字一起使用才有效用。
範例
下列範例會定義跨兩個程式碼檔案的 Address
類別。 設計工具可修改 Address.details.h
,而您可以修改 Address.h
。 只有第一個檔案中的類別定義會使用 partial
關鍵字。
// Address.Details.h
partial ref class Address
{
private:
Platform::String^ street_;
Platform::String^ city_;
Platform::String^ state_;
Platform::String^ zip_;
Platform::String^ country_;
void ValidateAddress(bool normalize = true);
};
// Address.h
#include "Address.details.h"
ref class Address
{
public:
Address(Platform::String^ street, Platform::String^ city, Platform::String^ state,
Platform::String^ zip, Platform::String^ country);
property Platform::String^ Street { Platform::String^ get(); }
property Platform::String^ City { Platform::String^ get(); }
property Platform::String^ State { Platform::String^ get(); }
property Platform::String^ Zip { Platform::String^ get(); }
property Platform::String^ Country { Platform::String^ get(); }
};