Kelas parsial (C++/CX)
Kelas parsial adalah konstruksi yang mendukung skenario di mana Anda memodifikasi satu bagian dari definisi kelas, dan perangkat lunak pembuatan kode otomatis—misalnya, perancang XAML—juga memodifikasi kode di kelas yang sama. Dengan menggunakan kelas parsial, Anda dapat mencegah perancang menimpa kode Anda. Dalam proyek Visual Studio, pengubah partial
diterapkan secara otomatis ke file yang dihasilkan.
Sintaks
Untuk menentukan kelas parsial, gunakan partial
kata kunci segera sebelum kunci kelas dari apa yang akan menjadi definisi kelas normal. Kata kunci seperti partial ref class
adalah kata kunci kontekstual yang berisi karakter spasi kosong. Definisi parsial didukung dalam konstruksi berikut.
class
ataustruct
ref class
atauref struct
value class
atauvalue struct
enum
atauenum class
ref interface
,interface class
,interface struct
, atau__interface
union
Contoh ini menunjukkan sebagian ref class
:
partial ref class MyClass {/* ... */};
Konten
Definisi kelas parsial dapat berisi apa pun yang dapat dimuat oleh definisi kelas lengkap jika partial
kata kunci telah dihilangkan. Dengan satu pengecualian, ini termasuk konstruksi yang valid seperti kelas dasar, anggota data, fungsi anggota, enum, deklarasi teman, dan atribut. Dan definisi sebaris anggota data statis diizinkan.
Satu pengecualian adalah aksesibilitas kelas. Misalnya, pernyataan public partial class MyInvalidClass {/* ... */};
adalah kesalahan. Setiap penentu akses yang digunakan dalam definisi kelas parsial untuk MyInvalidClass tidak memengaruhi aksesibilitas default dalam definisi kelas parsial atau penuh berikutnya untuk MyInvalidClass.
Fragmen kode berikut menunjukkan aksesibilitas. Di kelas parsial pertama, Method1
bersifat publik karena aksesibilitasnya bersifat publik. Di kelas parsial kedua, Method2
bersifat privat karena aksesibilitas kelas default bersifat privat.
partial ref class N
{
public:
int Method1(); // Method1 is public.
};
ref class N
{
void Method2(); // Method2 is private.
};
Deklarasi
Definisi parsial dari kelas seperti MyClass
hanya deklarasi MyClass. Artinya, itu hanya memperkenalkan nama MyClass
. MyClass
tidak dapat digunakan dengan cara yang memerlukan definisi kelas, misalnya, mengetahui ukuran MyClass
atau menggunakan basis atau anggota MyClass
. MyClass
dianggap hanya ditentukan ketika pengkompilasi menemukan definisi non-parsial dari MyClass
.
Contoh berikut menunjukkan perilaku deklarasi kelas parsial. Setelah deklarasi #1, MyClass
dapat digunakan seolah-olah ditulis sebagai deklarasi maju, ref class MyClass;
. Deklarasi #2 setara dengan deklarasi #1. Deklarasi #3 valid karena merupakan deklarasi penerusan ke kelas. Tetapi deklarasi #4 tidak valid karena
MyClass
tidak sepenuhnya ditentukan.
Deklarasi #5 tidak menggunakan partial
kata kunci, dan deklarasi sepenuhnya mendefinisikan MyClass
. Akibatnya, deklarasi #6 valid.
// 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.
Nomor dan pengurutan
Mungkin ada nol atau lebih definisi kelas parsial untuk setiap definisi lengkap kelas.
Setiap definisi kelas parsial dari kelas harus secara leksikal mendahului satu definisi lengkap kelas tersebut, tetapi tidak harus mendahului deklarasi ke depan kelas. Jika tidak ada definisi lengkap kelas, maka deklarasi kelas parsial hanya dapat berupa deklarasi ke depan.
Semua kunci kelas seperti class
dan struct
harus cocok. Misalnya, ini adalah kesalahan untuk kode partial class X {}; struct X {};
.
Contoh berikut menunjukkan angka dan pengurutan. Deklarasi parsial terakhir gagal karena kelas sudah ditentukan.
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.
Definisi lengkap
Pada titik definisi lengkap kelas X, perilakunya sama seperti jika definisi X telah mendeklarasikan semua kelas dasar, anggota, dan sebagainya, dalam urutan di mana mereka ditemui dan didefinisikan dalam kelas parsial. Artinya, konten kelas parsial diperlakukan seolah-olah ditulis pada titik definisi lengkap kelas, dan pencarian nama dan aturan bahasa lainnya diterapkan pada titik definisi lengkap kelas seolah-olah isi kelas parsial ditulis di tempat
Dua contoh kode berikut memiliki arti dan efek yang identik. Contoh pertama menggunakan kelas parsial dan contoh kedua tidak.
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);
};
Templat
Kelas parsial tidak bisa menjadi templat.
Batasan
Kelas parsial tidak dapat melampaui satu unit terjemahan.
Kata partial
kunci hanya didukung dalam kombinasi dengan ref class
kata kunci atau value class
kata kunci.
Contoh
Contoh berikut mendefinisikan kelas di Address
dua file kode. Perancang memodifikasi Address.details.h
dan Anda memodifikasi Address.h
. Hanya definisi kelas dalam file pertama yang partial
menggunakan kata kunci.
// 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(); }
};