Pointers and Classes
|
Native References
|
As done for variables of primitive types, you can
create a reference to a class using a declared variable. The same rule
applies: the object that is used as a reference must have been previously
initialized.
- To start a new program, launch Microsoft Visual C++ 2005
- On the main menu, click File -> New -> Project...
- On the left side, make sure that Visual C++ is selected. In the Templates list, click CLR Empty Project
- In the Name box, replace the string with RealEstate5 and click OK
- To create a source file, on the main menu, click Project -> Add New Item...
- In the Templates list, click Source File (.cpp)
- In the New box, type Exercise and click Add
- In the empty file, type:
using namespace System; public value class CProperty { public: __wchar_t TypeOfHome; int Bedrooms; float Bathrooms; Byte Stories; int YearBuilt; double Value; }; int main() { CProperty townhouse; townhouse.YearBuilt = 1986; townhouse.Bathrooms = 1.5f; townhouse.Stories = 3; townhouse.Value = 348255; townhouse.Bedrooms = 3; townhouse.TypeOfHome = L'T'; CProperty &townhome = townhouse; Console::WriteLine("=//= Altair Realty =//="); Console::WriteLine("-=- Properties Inventory -=-"); Console::Write("Type of Home: "); Console::WriteLine(townhome.TypeOfHome); Console::Write("Number of Bedrooms: "); Console::WriteLine(townhome.Bedrooms); Console::Write("Number of Bathrooms: "); Console::WriteLine(townhome.Bathrooms); Console::Write("Number of Stories: "); Console::WriteLine(townhome.Stories); Console::Write("Year Built: "); Console::WriteLine(townhome.YearBuilt); Console::Write("Monetary Value: "); Console::WriteLine(townhome.Value); Console::WriteLine(); return 0; }
- To execute the application, on the main menu, click Debug -> Start Without Debugging
- Click Yes
=//= Altair Realty =//= -=- Properties Inventory -=- Type of Home: T Number of Bedrooms: 3 Number of Bathrooms: 1.5 Number of Stories: 3 Year Built: 1986 Monetary Value: 348255 Press any key to continue . . .
- After viewing the file, close the DOS window
As done with variables of the regular data types,
you can declare a pointer to a class. Here is an example:
using namespace System;
public value struct CSquare
{
double Side;
};
int main()
{
CSquare *square;
return 0;
}
After
declaring the pointer, you should let the compiler know what
variable the pointer is pointing to. This can easily be done by
assigning the address of an existing object as follows:
using namespace System;
public value struct CSquare
{
double Side;
};
int main()
{
CSquare sqr;
CSquare *square = &sqr;
Console::WriteLine();
return 0;
}
|
- To declare a pointer to class, change the main() function as follows:
using namespace System; public value class CProperty { public: __wchar_t TypeOfHome; int Bedrooms; float Bathrooms; Byte Stories; int YearBuilt; double Value; }; int main() { CProperty condominium; CProperty *apartment = &condominium; Console::WriteLine(); return 0; }
- Save the file
Accessing the Members of a Pointer to a Class
|
After declaring a pointer to a class, to use it, you can
access one, a few, or all of its members. You have a choice between two
operators: the period and the arrow.
We saw that the asterisk "*" on the
left side of a pointer represented the value of the variable. In the case of a
class, when writing *sqr, this represents a CSquare object and it holds the
values of the object to which it would have been initialized. To access its members, yon can
use the period operator that is used to
access the values of an object. Because the period has a higher precedence than
the asterisk, you must include the object and its asterisk between
parentheses. Here is an example:
using namespace System;
public value struct CSquare
{
double Side;
};
int main()
{
CSquare sqr;
sqr.Side = 24.48;
CSquare *square = &sqr;
Console::WriteLine("Square Characteristics");
Console::Write("Side: ");
Console::WriteLine((*square).Side);
Console::WriteLine();
return 0;
}
As an alternative, you can access the values using the pointer to the
class. In this case, you would use the name of the pointer and the arrow
operator. Here are examples:
using namespace System;
public value struct CSquare
{
double Side;
};
int main()
{
CSquare sqr;
sqr.Side = 24.48;
CSquare *square = &sqr;
Console::WriteLine("Square Characteristics");
Console::Write("Side: ");
Console::WriteLine(square->Side);
Console::WriteLine();
return 0;
}
Both notations produce the same result:
Square Characteristics Side: 24.48 Press any key to continue . . .
|
- To access the members of a pointer to class, change the main() function as
follows:
using namespace System; public value class CProperty { public: __wchar_t TypeOfHome; int Bedrooms; float Bathrooms; Byte Stories; int YearBuilt; double Value; }; int main() { CProperty apartment; CProperty *condominium = &apartment; condominium->YearBuilt = 1986; condominium->Bathrooms = 1.5f; condominium->Stories = 3; condominium->Value = 348255; condominium->Bedrooms = 3; condominium->TypeOfHome = L'T'; Console::WriteLine("=//= Altair Realty =//="); Console::WriteLine("-=- Properties Inventory -=-"); Console::Write("Type of Home: "); Console::WriteLine(condominium->TypeOfHome); Console::Write("Number of Bedrooms: "); Console::WriteLine(condominium->Bedrooms); Console::Write("Number of Bathrooms: "); Console::WriteLine(condominium->Bathrooms); Console::Write("Number of Stories: "); Console::WriteLine(condominium->Stories); Console::Write("Year Built: "); Console::WriteLine(condominium->YearBuilt); Console::Write("Monetary Value: "); Console::WriteLine(condominium->Value); Console::WriteLine(); return 0; }
- Execute the application to see the result
Using a pointer allows
you to use memory only as needed. This is done by using the asterisk
* and the new operators. The syntax of declaring a pointer to a class is:
ClassName* VariableName = new ClassName;
The ClassName is the class whose variable you want
to declare. It could be in the program or one that shipped with the compiler.
Once again, the asterisk lets the compiler know that the object is declared as a
pointer. The variable name follows the same rules we have applied to other
variables so far.
After declaring the pointer, you can access each of its
members and assign it an
appropriate value. Here are examples:
|
using namespace System; public value struct CSquare { double Side; }; int main() { CSquare *square = new CSquare; square->Side = 24.48; Console::WriteLine("Square Characteristics"); Console::Write("Side: "); Console::WriteLine(square->Side); Console::WriteLine(); return 0; }
|
- To allocate memory on the heap, change the main() function as follows:
using namespace System; public value class CProperty { public: __wchar_t TypeOfHome; int Bedrooms; float Bathrooms; Byte Stories; int YearBuilt; double Value; }; int main() { CProperty *condominium = new CProperty; condominium->YearBuilt = 2000; condominium->Bathrooms = 1.0f; condominium->Stories = 1; condominium->Value = 224825; condominium->Bedrooms = 1; condominium->TypeOfHome = L'C'; Console::WriteLine("=//= Altair Realty =//="); Console::WriteLine("-=- Properties Inventory -=-"); Console::Write("Type of Home: "); Console::WriteLine(condominium->TypeOfHome); Console::Write("Number of Bedrooms: "); Console::WriteLine(condominium->Bedrooms); Console::Write("Number of Bathrooms: "); Console::WriteLine(condominium->Bathrooms); Console::Write("Number of Stories: "); Console::WriteLine(condominium->Stories); Console::Write("Year Built: "); Console::WriteLine(condominium->YearBuilt); Console::Write("Monetary Value: "); Console::WriteLine(condominium->Value); Console::WriteLine(); return 0; }
- Execute the application to see the result
- Close the DOS window
After using a
variable that was declared using the new operator, you can reclaim the
memory space it was using. This is done with the delete operator.
Here is an example:
using namespace System;
public value struct CSquare
{
double Side;
};
int main()
{
CSquare *square = new CSquare;
square->Side = 24.48;
Console::WriteLine("Square Characteristics");
Console::Write("Side: ");
Console::WriteLine(square->Side);
delete square;
Console::WriteLine();
return 0;
}
|
- To de-allocate memory, change the main() function as follows:
using namespace System; public value class CProperty { public: __wchar_t TypeOfHome; int Bedrooms; float Bathrooms; Byte Stories; int YearBuilt; double Value; }; int main() { CProperty *condominium = new CProperty; . . . delete condominium; Console::WriteLine(); return 0; }
- Execute the application to see the result
- Close the DOS window
Declaring a Pointer to Pointer
|
In Lesson 3, we saw
how to declare a pointer to a pointer to a primitive type. In the same way, you
can declare a pointer to a pointer to a class. Here is an example:
using namespace System;
public value struct CSquare
{
double Side;
};
int main()
{
CSquare **square;
Console::WriteLine();
return 0;
}
|
One way you can use such a variable is to initialize it with
a reference to a pointer of the same type. This could be done as follows:
using namespace System;
public value struct CSquare
{
double Side;
};
int main()
{
CSquare *sqr = new CSquare;
CSquare **square;
square = &sqr;
Console::WriteLine();
return 0;
}
Remember that, for a double-pointer to a class, such as
**square,
the expression *square is a pointer to the class. This means that you can use
the single asterisk to access the (public) members of the object. To do this, you
can use the arrow -> operator. Because the -> operator has higher
precedence than the asterisk, you must isolate *square by including
it in parentheses. This would be done as follows:
using namespace System; public value struct CSquare { double Side; }; int main() { CSquare *sqr = new CSquare; CSquare **square; square = &sqr; (*square)->Side = 24.48; Console::WriteLine("Square Characteristics"); Console::Write("Side: "); Console::WriteLine((*square)->Side); delete sqr; Console::WriteLine(); return 0; }
You may remember that the name of a pointer variable
preceded with the asterisk represents the value held by the variable. When
applied to a class, for a single pointer, the name preceded with * is the value
of the variable. For a double-pointer, the name preceded with two asterisks is
the value held by the pointer to pointer. This allows you to access the members
of the class using the period operator. The above program can be written as:
using namespace System;
public value struct CSquare
{
double Side;
};
int main()
{
CSquare *sqr = new CSquare;
CSquare **square;
square = &sqr;
(**square).Side = 24.48;
Console::WriteLine("Square Characteristics");
Console::Write("Side: ");
Console::WriteLine((*square)->Side);
delete sqr;
Console::WriteLine();
return 0;
}
Just as demonstrated in Lesson 3, after initializing a
pointer, if you change the value of the variable it points to, the pointer would
be updated. If the variable was declared as a pointer to pointer and if you change
either the pointer it points to, the pointer to pointer would be updated.
Introduction
|
When studying pointers, we saw that the compiler reserved an
area in heap memory for the pointers of your application. We also saw that, when you
declared a pointer and allocated memory using the new operator, you
should remember to de-allocate the memory using the delete operator. Although
modern compilers are equipped to check this, if you are working with one that
would not empty the memory for you, your program could create a memory leak. The
error being human, this has been one of the regular concerns when programming
with C and C++. One of the improvements of C++/CLI was to assist you with this.
If you (decide to) use pointers in your program, the heap
memory is highly under your control. Notice that we use "if". This
means that, in C++, you can create a complete program that doesn't, or hardly, use
pointers. For a serious programmer, there is no way you can simply decide not to
use pointers at all. Since you are going to use them, as we mentioned, the
compiler reserves some heap memory for you. If you don't manage it right, you
can create a mess. To avoid this, no more "if", the common language
runtime (CLR) suggests and sometimes requires that you use another technique. This time, instead of your being in
control of that heap, the compiler sets aside its own portion of heap and
becomes in charge of it. To differentiate both portions of memory, the heap we
mentioned when studying pointers is referred to as native heap. The heap used by
the CLR is called the managed heap:
Computer Memory | |
- To start a new program, on the main menu, click File -> New -> Project...
- On the left side, make sure that Visual C++ is selected. In the Templates list, click CLR Empty Project
- In the Name box, replace the string with RealEstate6 and click OK
- To create a source file, on the main menu, click Project -> Add New Item...
- In the Templates list, click Source File (.cpp)
- In the New box, type Exercise and click Add
- In the empty file, type:
using namespace System; int main() { Console::WriteLine("=//= Altair Realty =//="); Console::WriteLine("-=- Properties Inventory -=-"); return 0; }
- To execute the application, on the main menu, click Debug -> Start Without Debugging
- Click Yes
- On the main menu, click Project -> Add New Item...
- In the Templates list, click Header File (.h)
- In the New box, type Property and click Add
- In the empty file, type the following:
#pragma once namespace RealEstate { public value class CProperty { public: long PropertyNumber; __wchar_t PropertyType; unsigned Stories; unsigned Bedrooms; float Bathrooms; unsigned YearBuilt; double PropertyValue; }; }
- Save the file
In our introduction to pointers, we saw that a
reference was a technique of declaring an additional
variable that references a primary variable. This was viewed as creating
a variable that simply referred to
another previously declared variable. Such a variable declared as a
reference is stored in the stack. The compiler is then in charge of
“cleaning” it, that is, in charge of reclaiming its memory when the
reference is not used anymore. C++/CLI allows you to declare a reference
that, if you want, would be stored in the CLR heap so the garbage
collector would be in charge of managing it. Such a variable is called a
tracking reference.
As done for a primitive type, you can also create a tracking
reference of a class. To start, declare and initialize a variable of the class.
Once the referenced variable is ready, to create a tracking reference, declare
the variable but type the % operator between the class name and the name of the
variable. To indicate the variable it is referencing, assign it the variable
that was previously defined. Here is an example:
|
int main() { CProperty victorian; victorian.Value = 485565; CProperty % single = victorian; return 0; }
You can then access the members of either the referenced or
the referencing variables. If you change the values of the members of the
variable, the values of the reference would be changed also. In the same way, if
you change the values of the reference, the values of the referenced variable
would be changed also.
To store a
variable in the managed heap, you must create it as a handle. To create a handle, as opposed to the
asterisk "*" of a pointer, you use the cap "^" operator. Here is an
example:
using namespace System; public value class CProperty { public: __wchar_t TypeOfHome; int NumberOfBedrooms; double NumberOfBathrooms; Byte Stories; int YearBuilt; double Value; }; int main() { CProperty ^ townhome; Console::WriteLine(); return 0; }
As mentioned for the ampersand & operator of the
reference and the asterisk operator of the pointer, there are three basic
positions the cap operator ^ can have:
CProperty^ townhome; CProperty ^ townhome; CProperty ^townhome;
The compiler will assume the same. In this case, townhome is
a handle to CProperty.
When studying pointers, we mentioned
that you could not initialize a newly created pointer with just any value. You
could initialize it with 0, which represented the null value. To initialize a
handle with a null value, you can assign it the nullptr value. Here is an
example:
int main()
{
CProperty ^ townhome = nullptr;
Console::WriteLine();
return 0;
}
After creating a handle, you should let the compiler know what
variable it handles. To do this, assign it a declared variable preceded
with the % operator, as we did for the & operator when referencing a
pointer. Here is an example:
using namespace System;
public value class CProperty
{
public:
__wchar_t TypeOfHome;
int NumberOfBedrooms;
double NumberOfBathrooms;
Byte Stories;
int YearBuilt;
double Value;
};
int main()
{
CProperty townhouse;
townhouse.YearBuilt = 1986;
townhouse.NumberOfBathrooms = 1.5;
townhouse.Stories = 3;
townhouse.Value = 348255;
townhouse.NumberOfBedrooms = 3;
townhouse.TypeOfHome = L'T';
CProperty ^ townhome = %townhouse;
Console::WriteLine();
return 0;
}
|
- Access the Exercise.cpp file
- To create a handle, declare a CProperty variable as follows:
#include "Property.h" using namespace System; using namespace RealEstate; int main() { CProperty ^ house; Console::WriteLine("=//= Altair Realty =//="); Console::WriteLine("-=- Properties Inventory -=-"); return 0; }
- Save the Exercise.cpp file
In Lesson 4, we saw that
you could create a class using the value keyword on the left of the struct
or class keyword. If you create a class using the value keyword,
when you declare a variable from that class, we have seen so far that you could
store it in the stack by declaring it as a value type. Here is an example:
using namespace System;
public value class CProperty
{
public:
__wchar_t TypeOfHome;
int NumberOfBedrooms;
double NumberOfBathrooms;
Byte Stories;
int YearBuilt;
double Value;
};
int main()
{
CProperty victorian;
victorian.Value = 485565;
Console::Write("Property Value: ");
Console::WriteLine(victorian.Value);
Console::WriteLine();
return 0;
}
Alternatively, you can store the variable in the native
heap. To do this, declare it as a pointer. Remember that if you declare the
variable as a pointer, it is stored in the native heap and you must remember to
reclaim its memory area when the program ends. This is done using the delete
operator:
using namespace System; public value class CProperty { public: __wchar_t TypeOfHome; int NumberOfBedrooms; double NumberOfBathrooms; Byte Stories; int YearBuilt; double Value; }; int main() { CProperty * victorian = new CProperty; victorian->Value = 485565; Console::Write("Property Value: "); Console::WriteLine(victorian->Value); delete victorian ; Console::WriteLine(); return 0; }
If you want, you can store the variable in the managed heap
by creating it as a handle:
using namespace System; public value class CProperty { public: __wchar_t TypeOfHome; int NumberOfBedrooms; double NumberOfBathrooms; Byte Stories; int YearBuilt; double Value; }; int main() { CProperty ^ victorian = gcnew CProperty; victorian->Value = 485565; Console::Write("Property Value: "); Console::WriteLine(victorian->Value); Console::WriteLine(); return 0; }
As seen already, you can also create a reference to a class
type. This means that you have a choice of storing the variable in the stack,
the native heap, or the managed heap. Besides the value keyword, you can
create a class using the ref keyword. Here is an example:
public ref class CProperty
{
public:
__wchar_t TypeOfHome;
int NumberOfBedrooms;
double NumberOfBathrooms;
Byte Stories;
int YearBuilt;
double Value;
};
In most cases, you can use a ref class as you would a
value class. There are still many differences between both types. One of
the rules you must observes is that you cannot create a native reference of ref
class. For example, the following program will compile:
using namespace System; public value class CProperty { public: __wchar_t TypeOfHome; int NumberOfBedrooms; double NumberOfBathrooms; Byte Stories; int YearBuilt; double Value; }; int main() { CProperty victorian; victorian.Value = 485565; CProperty & single = victorian; Console::Write("Property Value: "); Console::WriteLine(victorian.Value); Console::Write("Property Value: "); Console::WriteLine(single.Value); Console::WriteLine(); return 0; }
The following will not compile:
using namespace System; public ref class CProperty { public: __wchar_t TypeOfHome; int NumberOfBedrooms; double NumberOfBathrooms; Byte Stories; int YearBuilt; double Value; }; int main() { CProperty victorian; victorian.Value = 485565; CProperty & single = victorian; Console::Write("Property Value: "); Console::WriteLine(victorian.Value); Console::Write("Property Value: "); Console::WriteLine(single.Value); Console::WriteLine(); return 0; }
When compiling it in Microsoft Visual C++ 2005, this program would produce
a C3699, a C2440, and a C2228 errors:
error C3699: '&' : cannot use this indirection on type 'CProperty' compiler replacing '&' with '^' to continue parsing error C2440: 'initializing' : cannot convert from 'CProperty' to 'CProperty ^' No user-defined-conversion operator available, or No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called .\Exercise.cpp(26) : error C2228: left of '.Value' must have class/struct/union type is 'CProperty ^' did you intend to use '->' instead?
The reason this will not compile is that, if you create a
class as ref or if you use a class that was created as ref, you cannot create a
native reference of it. If you want to create a reference and if you are the one
creating a class, make it a value type. If you created the class as ref,
or if you are using a ref class that was created by someone else, you can create
a tracking reference of it. Based on this, the following instead will work:
using namespace System; public ref class CProperty { public: __wchar_t TypeOfHome; int NumberOfBedrooms; double NumberOfBathrooms; Byte Stories; int YearBuilt; double Value; }; int main() { CProperty victorian; victorian.Value = 485565; CProperty % single = victorian; Console::Write("Property Value: "); Console::WriteLine(victorian.Value); Console::Write("Property Value: "); Console::WriteLine(single.Value); Console::WriteLine(); return 0; }
Remember that you can also create a handle to use it.
|
- Access the Property.h file
- To make the class a reference type, change it as follows:
#pragma once namespace RealEstate { public ref class CProperty { public: long PropertyNumber; __wchar_t PropertyType; unsigned Stories; unsigned Bedrooms; float Bathrooms; unsigned YearBuilt; double PropertyValue; }; }
- Save the Property.h file
Accessing the Members of a Handle
|
After creating a handle, you can
access its members. As done for the pointer, you have two alternatives. You can
use the asterisk "*" on the
left side of a handle. After including the asterisk and the handle between
parentheses, you can use the period operator to access each member. This allows
you either to initialize the member or to retrieve its current value. Here are examples:
using namespace System; public value class CProperty { public: __wchar_t TypeOfHome; int NumberOfBedrooms; double NumberOfBathrooms; Byte Stories; int YearBuilt; double Value; }; int main() { CProperty apartment; apartment.YearBuilt = 2002; apartment.NumberOfBathrooms = 1; apartment.Stories = 18; apartment.Value = 155825; apartment.NumberOfBedrooms = 2; apartment.TypeOfHome = L'C'; CProperty ^ condo = %apartment; Console::Write("Type of Home: "); Console::WriteLine((*condo).TypeOfHome); Console::Write("Number of Bedrooms: "); Console::WriteLine((*condo).NumberOfBedrooms); Console::Write("Number of Bathrooms: "); Console::WriteLine((*condo).NumberOfBathrooms); Console::Write("Number of Stories: "); Console::WriteLine((*condo).Stories); Console::Write("Year Built: "); Console::WriteLine((*condo).YearBuilt); Console::Write("Monetary Value: "); Console::WriteLine((*condo).Value); Console::WriteLine(); return 0; }
Instead of the asterisk, you can use the arrow, as done for
the pointer, to access the members of a handle. The above program can produce
the same results with:
using namespace System; public value class CProperty { public: __wchar_t TypeOfHome; int NumberOfBedrooms; double NumberOfBathrooms; Byte Stories; int YearBuilt; double Value; }; int main() { CProperty apartment; apartment.YearBuilt = 2002; apartment.NumberOfBathrooms = 1; apartment.Stories = 18; apartment.Value = 155825; apartment.NumberOfBedrooms = 2; apartment.TypeOfHome = L'C'; CProperty ^ condo = %apartment; Console::Write("Type of Home: "); Console::WriteLine(condo->TypeOfHome); Console::Write("Number of Bedrooms: "); Console::WriteLine(condo->NumberOfBedrooms); Console::Write("Number of Bathrooms: "); Console::WriteLine(condo->NumberOfBathrooms); Console::Write("Number of Stories: "); Console::WriteLine(condo->Stories); Console::Write("Year Built: "); Console::WriteLine(condo->YearBuilt); Console::Write("Monetary Value: "); Console::WriteLine(condo->Value); Console::WriteLine(); return 0; }
Both notations produce the same result:
Type of Home: C Number of Bedrooms: 2 Number of Bathrooms: 1 Number of Stories: 18 Year Built: 2002 Monetary Value: 155825 Press any key to continue . . .
We saw that there were some details related to using the
native heap: you could hesitate to use or not to use pointers, you could forget
to delete pointers, you could even misuse it. To solve these and some other
problems, the common language runtime reserves its own portion of the garbage
collected heap to make available when you use handles. Based on this, when
creating a handle, to allocate memory for it, you can instantiate it using the gcnew
operator. The formula to use it
is:
ClassName ^ HandleName = gcnew ClassName;
The ClassName is the class whose handle you want
to create.
The ^, =, and gcnew operators are required.
The HandleName is the name of the handle that will be
created.
After creating the handle, you can assign the desired value
to each of its members. Here are examples:
using namespace System;
public value class CProperty
{
public:
__wchar_t TypeOfHome;
int NumberOfBedrooms;
double NumberOfBathrooms;
Byte Stories;
int YearBuilt;
double Value;
};
int main()
{
CProperty ^condominium = gcnew CProperty;
condominium->YearBuilt = 2002;
condominium->NumberOfBathrooms = 1;
condominium->Stories = 18;
condominium->Value = 155825;
condominium->NumberOfBedrooms = 2;
condominium->TypeOfHome = L'C';
Console::Write("Type of Home: ");
Console::WriteLine(condominium->TypeOfHome);
Console::Write("Number of Bedrooms: ");
Console::WriteLine(condominium->NumberOfBedrooms);
Console::Write("Number of Bathrooms: ");
Console::WriteLine(condominium->NumberOfBathrooms);
Console::Write("Number of Stories: ");
Console::WriteLine(condominium->Stories);
Console::Write("Year Built: ");
Console::WriteLine(condominium->YearBuilt);
Console::Write("Monetary Value: ");
Console::WriteLine(condominium->Value);
Console::WriteLine();
return 0;
}
Unlike a pointer whose memory was allocated with the new operator,
when a handle is not used anymore, you don't need to de-allocate its memory. The
garbage collector would take care of it. If you insist, you can still use the delete
operator to remove the handle from memory. You use the delete operator
the exact same way we did for the pointer.
|
- Access the Exercise.cpp file
- To initialize the declared handle, change it as follows:
#include "Property.h" using namespace System; using namespace RealEstate; int main() { CProperty ^ house = gcnew CProperty; house->PropertyNumber = 792749; house->PropertyType = 'S'; house->Stories = 2; house->Bedrooms = 4; house->Bathrooms = 2.0f; house->YearBuilt = 1956; house->PropertyValue = 412650; Console::WriteLine("=//= Altair Realty =//="); Console::WriteLine("-=- Properties Inventory -=-"); Console::Write("Property #: "); Console::WriteLine(house->PropertyNumber); Console::Write("Type: "); Console::WriteLine(house->PropertyType); Console::Write("Bedrooms: "); Console::WriteLine(house->Bedrooms); Console::Write("Bathrooms: "); Console::WriteLine(house->Bathrooms); Console::Write("Stories: "); Console::WriteLine(house->Stories); Console::Write("Year Built: "); Console::WriteLine(house->YearBuilt); Console::Write("Market Value: "); Console::WriteLine(house->PropertyValue); return 0; }
- Execute the application to see the result:
=//= Altair Realty =//= -=- Properties Inventory -=- Property #: 792749 Type: S Bedrooms: 4 Bathrooms: 2 Stories: 2 Year Built: 1956 Market Value: 412650 Press any key to continue . . .
- Close the DOS window
No comments:
Post a Comment