description | title | ms.date | helpviewer_keywords | ms.assetid | ||
---|---|---|---|---|---|---|
Learn more about: How to: Use Properties in C++/CLI | How to: Use Properties in C++/CLI | 07/21/2017 |
| f5d82547-e214-4f05-9e1b-ddb6d0dc5e4c |
This article shows how to use properties in C++/CLI.
For basic properties—those that merely assign and retrieve a private data member—you don't have to explicitly define the get and set accessor functions because the compiler automatically provides them when given just the data type of the property. This code demonstrates a basic property:
// SimpleProperties.cpp// compile with: /clrusingnamespaceSystem; ref classC { public: property intSize; }; intmain() { C^ c = gcnew C; c->Size = 111; Console::WriteLine("c->Size = {0}", c->Size); }
c->Size = 111
This code sample shows how to declare and use a static property. A static property can only access static members of its class.
// mcppv2_property_3.cpp// compile with: /clrusingnamespaceSystem; ref classStaticProperties { staticint MyInt; staticint MyInt2; public:static property int Static_Data_Member_Property; static property int Static_Block_Property { intget() { return MyInt; } voidset(int value) { MyInt = value; } } }; intmain() { StaticProperties::Static_Data_Member_Property = 96; Console::WriteLine(StaticProperties::Static_Data_Member_Property); StaticProperties::Static_Block_Property = 47; Console::WriteLine(StaticProperties::Static_Block_Property); }
96 47
An indexed property typically exposes a data structure that's accessed by using a subscript operator.
If you use a default indexed property, you can access the data structure just by referring to the class name, but if you use a user-defined indexed property, you must to specify the property name to access the data structure.
For information about how to consume an indexer that's written in C#, see How to: Consume a C# Indexer (C++/CLI).
This code sample shows how to use default and user-defined indexed properties:
// mcppv2_property_2.cpp// compile with: /clrusingnamespaceSystem; public ref classC { array<int>^ MyArr; public:C() { MyArr = gcnew array<int>(5); } // default indexer property intdefault[int] { intget(intindex) { return MyArr[index]; } voidset(intindex, int value) { MyArr[index] = value; } } // user-defined indexer property int indexer1[int] { intget(intindex) { return MyArr[index]; } voidset(intindex, int value) { MyArr[index] = value; } } }; intmain() { C ^ MyC = gcnew C(); // use the default indexerConsole::Write("[ "); for (int i = 0 ; i < 5 ; i++) { MyC[i] = i; Console::Write("{0} ", MyC[i]); } Console::WriteLine("]"); // use the user-defined indexerConsole::Write("[ "); for (int i = 0 ; i < 5 ; i++) { MyC->indexer1[i] = i * 2; Console::Write("{0} ", MyC->indexer1[i]); } Console::WriteLine("]"); }
[ 0 1 2 3 4 ] [ 0 2 4 6 8 ]
The next sample shows how to call the default indexer by using the this
pointer.
// call_default_indexer_through_this_pointer.cpp// compile with: /clr /c value classPosition { public:Position(int x, int y) : position(gcnew array<int, 2>(100, 100)) { this->default[x, y] = 1; } property intdefault[int, int] { intget(int x, int y) { return position[x, y]; } voidset(int x, int y, int value) {} } private: array<int, 2> ^ position; };
This sample shows how to use xref:System.Reflection.DefaultMemberAttribute to specify the default indexer:
// specify_default_indexer.cpp// compile with: /LD /clrusingnamespaceSystem; [Reflection::DefaultMember("XXX")] public ref structSquares { property Double XXX[Double] { Double get(Double data) { return data*data; } } };
The next sample consumes the metadata that's created in the previous example.
// consume_default_indexer.cpp// compile with: /clr #using"specify_default_indexer.dll"intmain() { Squares ^ square = gcnew Squares(); System::Console::WriteLine("{0}", square[3]); }
9
This code sample shows how to declare and use virtual properties:
// mcppv2_property_4.cpp// compile with: /clrusingnamespaceSystem; interface structIEFace { public: property int VirtualProperty1; property int VirtualProperty2 { intget(); voidset(int i); } }; // implement virtual events ref classPropImpl : publicIEFace { int MyInt; public:virtual property int VirtualProperty1; virtual property int VirtualProperty2 { intget() { return MyInt; } voidset(int i) { MyInt = i; } } }; intmain() { PropImpl ^ MyPI = gcnew PropImpl(); MyPI->VirtualProperty1 = 93; Console::WriteLine(MyPI->VirtualProperty1); MyPI->VirtualProperty2 = 43; Console::WriteLine(MyPI->VirtualProperty2); }
93 43
Although the abstract and sealed keywords are specified as valid in the ECMA C++/CLI specification, for the Microsoft C++ compiler, you cannot specify them on trivial properties, nor on the property declaration of a non-trivial property.
To declare a sealed or abstract property, you must define a non-trivial property and then specify the abstract
or sealed
keyword on the get and set accessor functions.
// properties_abstract_sealed.cpp// compile with: /clr ref structA { protected:int m_i; public:A() { m_i = 87; } // define abstract property property int Prop_1 { virtualintget() abstract; virtualvoidset(int i) abstract; } }; ref structB : A { private:int m_i; public:B() { m_i = 86; } // implement abstract property property int Prop_1 { virtualintget() override { return m_i; } virtualvoidset(int i) override { m_i = i; } } }; ref structC { private:int m_i; public:C() { m_i = 87; } // define sealed property property int Prop_2 { virtualintget() sealed { return m_i; } virtualvoidset(int i) sealed { m_i = i; }; } }; intmain() { B b1; // call implementation of abstract propertySystem::Console::WriteLine(b1.Prop_1); C c1; // call sealed propertySystem::Console::WriteLine(c1.Prop_2); }
86 87
You can use multidimensional properties to define property accessor methods that take a non-standard number of parameters.
// mcppv2_property_5.cpp// compile with: /clr ref classX { double d; public:X() : d(0) {} property double MultiDimProp[int, int, int] { doubleget(int, int, int) { return d; } voidset(int i, int j, int k, double l) { // do something with those ints d = l; } } property double MultiDimProp2[int] { doubleget(int) { return d; } voidset(int i, double l) { // do something with those ints d = l; } } }; intmain() { X ^ MyX = gcnew X(); MyX->MultiDimProp[0,0,0] = 1.1; System::Console::WriteLine(MyX->MultiDimProp[0, 0, 0]); }
1.1
The following example shows how to overload indexed properties.
// mcppv2_property_6.cpp// compile with: /clr ref classX { double d; public:X() : d(0.0) {} property double MyProp[int] { doubleget(int i) { return d; } doubleget(System::String ^ i) { return2*d; } voidset(int i, double l) { d = i * l; } } // end MyProp definition }; intmain() { X ^ MyX = gcnew X(); MyX->MyProp[2] = 1.7; System::Console::WriteLine(MyX->MyProp[1]); System::Console::WriteLine(MyX->MyProp["test"]); }
3.4 6.8