Pointers. Part 6. Composite managed and native data types. Managed pointers (^) in the CLR. Memory allocation. The ref and value qualifiers. Managed pointers (^) to structures and classes
Contents
- 1. What features of the organization of composite data types in a CLR (Common Language Runtime) environment?
- 2. What are the features of using composite native data types?
- 3. What are the features of using managed composite data types?
- 4. What qualifiers are used to declare structures and classes in the CLR?
- 5. What is the difference between ref and value qualifiers when declaring structures or classes? Examples of accessing to ref structures and value structures using a pointer
- 6. What access do fields and members of the structure or class have by default?
- 7. An example of the declaration and use of a structure with a qualifier ref
- 8. How managed-arrays are declared in the CLR? Assignment of the keyword ‘array’
- 9. An example of declaring and using an array of managed structures that are declared with a ref qualifier using a managed pointer (^)
- 10. An example of declaring and using a managed-array on basic types (int, double) with a managed (^) pointer
- 11. An example of declaring and using an array of pointers (^) to a class that are declared as managed using the ref classifier and the keyword array
- Related topics
Search other websites:
1. What features of the organization of composite data types in a CLR (Common Language Runtime) environment?
In C++ (Visual C++), there are two types of composite data types:
- native data types. Pointers to these types of data are denoted by *;
- data types for working in the Common Language Runtime (CLR).
These types are also called managed data types. These types of data are stored in memory, which is allocated by the CLR environment.
Objects of these data types must be located in the dynamic memory, which is managed by the CLR. Pointers to such memory are indicated by the symbol ^.
2. What are the features of using composite native data types?
The composite native data types include:
- native structures;
- native classes.
To access these data types is used an unmanaged pointer *.
The work of unmanaged pointers is described in more detail in the following topics:
- Pointers. Part 2. Unmanaged pointers. Operation on pointers. Pointer to type void. Memory allocation. A null pointer. The operation of getting the address &
- Pointers. Part 3. Unmanaged pointers and arrays. Pointer to structure. Pointer to class
- Pointers. Part 5. Memory allocation for the pointer. Arrays of pointers to basic types, functions, structures, classes
3. What are the features of using managed composite data types?
Managed composite data types are:
- managed structures;
- managed classes.
Such structures and classes are designed to work in the CLR environment. They are placed in the memory that is allocated and managed by the CLR. If the programmer creates a project of the type “CLR Console Application” or “Windows Forms Application”, then this project meets the requirements of the CLR.
Objects that are managed by the CLR environment fall into managed dynamic memory. When declaring a pointer to a managed-structure or managed-class, the character ^ is used. The memory for this pointer is allocated by the gcnew utility.
4. What qualifiers are used to declare structures and classes in the CLR?
In a CLR environment, structures and classes can have two qualifiers:
- qualifier ref – means that the structure or class is a reference type;
- qualifier value – means that the structure or class is a value type.
In the CLR, you can also declare a structure or class without a qualifier. Working with such structures is used for compatibility with pointers to structures of older versions of C/C++.
5. What is the difference between ref and value qualifiers when declaring structures or classes? Examples of accessing to ref structures and value structures using a pointer
The difference between the ref and value qualifiers is the way the memory is allocated for a pointer to a structure or class.
With the ref modifier, the structure or class is placed in a managed heap and can not be placed in the native heap.
With the value modifier, a structure or class can be placed in a managed heap and in a native heap.
The following examples demonstrate the difference between the structures that are described with the ref and value qualifiers. The same applies to classes.
Let’s use a structure that describes the pixel on the monitor screen.
Example 1. Declaration of structure with qualifier ref.
// structure declared with qualifier ref ref struct MyPoint_ref { int x; int y; int color; };
Then, the use of a structure from another program code can be as follows:
// qualifier ref // 1. Declaring a pointer to a structure with a ref qualifier MyPoint_ref ^ pr; // 2. Memory allocation for the pointer // Memory is allocated in a managed heap pr = gcnew MyPoint_ref; // 3. Filling the structure fields pr->x = 28; pr->y = 35; pr->color = 2; // Error! // MyPoint_ref * p; - It is impossible to declare an unmanaged pointer to the ref-structure
Example 2. Declaring a structure with value qualifier.
// Structure declared with qualifier "value" value struct MyPoint_value { int x; int y; int color; };
Use of structure
// qualifier value // 1. Declaring pointers to a structure with a qualifier 'value' MyPoint_value ^ p1; // managed-pointer MyPoint_value * p2; // native-pointer // 2. Memory allocation for pointers p1 = gcnew MyPoint_value; p2 = new MyPoint_value; // 3. Demonstration of working with fields of structures through pointers p1->x = 33; p1->y = 200; p1->color = 3; p2->x = 10; p2->y = p1->y; p2->color = p1->color;
6. What access do fields and members of the structure or class have by default?
When a structure is declared, its fields (data members) and methods have a public access specifier.
When declaring a class, its data members and methods have a private access specifier.
7. An example of the declaration and use of a structure with a qualifier ref
Let the structure that is declared in the module “MyRefStruct.h” be given. The structure describes the coordinates of a point on a plane.
The structure is declared with the qualifier ref.
ref struct MyPointRef { int x; int y; };
An example of using a structure in a program using a managed pointer.
// declaration of structure with qualifier ref MyPointRef ^mp; // pointer to the structure mp = gcnew MyPointRef; // memory allocation for the structure // access to the structure fields mp->x = 25; mp->y = 30;
8. How managed-arrays are declared in the CLR? Assignment of the keyword ‘array’
In C++, native arrays are declared in the usual way for the language. More details about arrays in C++ are described in the following articles:
- Arrays. Part 1. Array definition. One-dimensional arrays. Initializing array;
- Arrays. Part 2. Two-dimensional arrays. Arrays of strings. Multidimensional arrays.
To declare the managed array, use the keyword ‘array’.
9. An example of declaring and using an array of managed structures that are declared with a ref qualifier using a managed pointer (^)
Let the structure MyPointRef is declared in the module “MyRefStruct.h”, which describes the point on the coordinate plane
ref struct MyPointRef { int x; int y; };
Working with an array of 10 managed-structures like MyPointRef is shown below. First you need to include the structure file:
#include "MyRefStruct.h"
Allocation of memory for an array and filling the fields of structure from other program code (for example, the event handler for a click event on a button):
// An array of m pointers to a structure // declared as managed with the keyword ref array <MyPointRef^> ^m; // memory allocation for 10 pointers m = gcnew array <MyPointRef^>(10); // creating 10 objects of the type "MyPointRef structure" for (int i=0; i<10; i++) m[i] = gcnew MyPointRef; // memory allocating for i-th structure // filling of fields x, y of array of structures for (int i=0; i<10; i++) { m[i]->x = i*5; m[i]->y = i*i; }
If you declare a MyPointRef structure with a value qualifier, then this example will also work.
10. An example of declaring and using a managed-array on basic types (int, double) with a managed (^) pointer
The following example declares an array of 20 integers of type ‘int’. To do this, you use a managed pointer (^).The allocation of memory for the array occurs in 2 stages:
- Allocation of memory for 20 pointers to type int.
- The allocation of memory for each element of type int, to which pointers should point.
To declare array you need use the ‘array’ word.
// managed-array to base types array <int ^> ^pi; // pi - Pointer to an array of types int pi = gcnew array <int ^>(20); // Allocating memory for an array of 20 pointers // allocating memory for each item of the array for (int i=0; i<20; i++) pi[i] = gcnew int; // allocating memory for the i-th element of the array // using an array for (int i=0; i<20; i++) pi[i] = i*5; int d; d = (int)pi[2]; // d = 10
11. An example of declaring and using an array of pointers (^) to a class that are declared as managed using the ref classifier and the keyword array
In the example, a class named MyClassRef is declared that describes the coordinates of the point on the plane. The class is declared as managed (has a ref qualifier). Class contains:
- private data members x, y;
- the constructor of class MyClassRef();
- methods GetX() and GetY() that return values of data members x, y;
- method SetXY(), which sets a new values of data members x, y;
The class is declared in two modules (files):
- module “MyClassRef.h” – it contains a declaration of a class member data and methods;
- module “MyClassRef.cpp” – it contains the implementation of class methods.
Text of module “MyClassRef.h”:
#pragma once // the class is declared as managed ref class MyClassRef { // members of the class data int x; // the coordinate x int y; // the coordinate y public: // class methods MyClassRef(void); int GetX(void); int GetY(void); void SetXY(int nx, int ny); };
Text of module “MyClassRef.cpp”:
#include "StdAfx.h" #include "MyClassRef.h" // the constructor of class MyClassRef::MyClassRef(void) { x = y = 0; } // class methods int MyClassRef::GetX(void) { return x; } int MyClassRef::GetY(void) { return y; } void MyClassRef::SetXY(int nx, int ny) { x = nx; y = ny; return; }
To use the class methods from another program code, you must first connect the “MyClassRef.h” module:
#include "MyClassRef.h"
After that, you can use the methods of the class. Below is the declaration and use of an array of managed pointers (^) to a class from another program code:
// array mp of managed-pointers to the class MyClassRef // first is allocated memory for 10 pointers array <MyClassRef ^> ^mp = gcnew array <MyClassRef ^>(10); // memory allocation for each pointer for (int i=0; i<10; i++) mp[i] = gcnew MyClassRef; // the use of class methods using an array of pointers mp[1]->SetXY(5, 6); mp[5]->SetXY(10, -200); int d; d = mp[1]->GetX(); // d = 5 d = mp[0]->GetY(); // d = 0 d = mp[5]->GetY(); // d = -200
Related topics
- Pointers. Part 1. General concepts. Pointer types. Managed and unmanaged pointers. Pointers to a function. Examples of the use of pointers
- Pointers. Part 2. Unmanaged pointers. Operation on pointers. Pointer to type void. Memory allocation. A null pointer. The operation of getting the address &
- Pointers. Part 3. Unmanaged pointers and arrays. Pointer to structure. Pointer to class
- Pointers. Part 4. Pointers and strings. Using pointers when converting strings
- Pointers. Part 5. Memory allocation for the pointer. Arrays of pointers to basic types, functions, structures, classes
- Arrays. Part 1. Array definition. One-dimensional arrays. Initializing array
- Structures. Part 1. Composite data types. The template of structure. Structural variable. Structures in the CLR. Declaring and initializing a structured variable
- Structures. Part 2. Memory allocation for the structure. Nested structures. Arrays of native structures
- Structures. Part 3. Working with managed-structures in CLR. Qualifiers ref and value. Declaring structural variables. Arrays of managed-structured variables. Initializing of managed-structures