Passing a Class Type |
|
Like a regular data type, a class can be passed to a function as argument. You can pass an argument as a tracking reference. To do this, in the parentheses of the function, type the name of the class, followed by the % operator, followed by a name for the argument. This would be done as follows: void DescribeProperty(CHouse % home); In the body of the function, you can either ignore the argument and not use it at all, or you can process or use the argument as you see fit. At a minimum, you can retrieve the values of its member variables, using the period operator. As mentioned for the regular types, when (only) declaring a function that takes a class type as argument, you can omit the name of the argument. When calling the function, pass the argument with the * operator. Here is an example: using namespace System; public value class CCar { public: String ^ Make; String ^ Model; int Doors; int Year; double Price; }; CCar % Build(); void Show(CCar % car); int main() { Console::WriteLine(L"Enter Car Information"); CCar ^ vehicle = Build(); Console::WriteLine(L"\nCar Characteristics"); Show(*vehicle); Console::WriteLine(); return 0; } CCar % Build() { CCar car; Console::Write(L"Enter Make: "); car.Make = Console::ReadLine(); Console::Write(L"Enter Model: "); car.Model = Console::ReadLine(); Console::Write(L"# of Doors: "); car.Doors = int::Parse(Console::ReadLine()); Console::Write(L"Year Made: "); car.Year = int::Parse(Console::ReadLine()); Console::Write(L"Enter Price: "); car.Price = double::Parse(Console::ReadLine()); CCar % veh = car; return veh; } void Show(CCar % car) { Console::WriteLine(L"Make: {0}", car.Make); Console::WriteLine(L"Model: {0}", car.Model); Console::WriteLine(L"Doors: {0}", car.Doors); Console::WriteLine(L"Year: {0}", car.Year); Console::WriteLine(L"Value: {0:C}", car.Price); } In the same way, you can pass as many tracking references as you want to a function. If a function doesn't modify an argument, you can pass it as a constant. This also applies to tracking references. Here is an example: using namespace System; public value class CCar { public: String ^ Make; String ^ Model; int Doors; int Year; double Price; }; CCar % Build(); void Show(const CCar % car); int main() { Console::WriteLine(L"Enter Car Information"); CCar ^ vehicle = Build(); Console::WriteLine(L"\nCar Characteristics"); Show(*vehicle); Console::WriteLine(); return 0; } CCar % Build() { CCar car; . . . CCar % veh = car; return veh; } void Show(const CCar % car) { . . . }
Another technique you can use to pass a class by reference is to pass it as a handle. To start with the formula we reviewed, use the ^ operator instead of %. In the body of the function, you can access each member variable using the -> operator. As mentioned for a tracking reference, if the function doesn't modify the argument, the handle can be passed as a constant. Using handles as arguments, you can overload a function by creating functions with the same name with either different types of argument(s) or different numbers of arguments.
When programming in C++/CLI, most of the time, you use classes as managed types and you pass them to functions as tracking references or as handles. Passing a function as a tracking reference or as a handle has the same effect as passing the argument as a native reference: when the function ends, if it modified the argument, the object would retain its value:
int main() { Console::WriteLine(L"Enter Car Information"); CCar ^ vehicle = gcnew CCar; Build(vehicle); Console::WriteLine(L"\nCar Characteristics"); Show(vehicle); Console::WriteLine(); return 0; } void Build(CCar ^ car) { Console::Write(L"Enter Make: "); car->Make = Console::ReadLine(); Console::Write(L"Enter Model: "); car->Model = Console::ReadLine(); Console::Write(L"# of Doors: "); car->Doors = int::Parse(Console::ReadLine()); Console::Write(L"Year Made: "); car->Year = int::Parse(Console::ReadLine()); Console::Write(L"Enter Price: "); car->Price = double::Parse(Console::ReadLine()); } void Show(const CCar ^ car) { Console::WriteLine(L"Make: {0}", car->Make); Console::WriteLine(L"Model: {0}", car->Model); Console::WriteLine(L"Doors: {0}", car->Doors); Console::WriteLine(L"Year: {0}", car->Year); Console::WriteLine(L"Value: {0:C}", car->Price); } Here is an example of running the program: Enter Car Information Enter Make: Toyota Enter Model: Corolla # of Doors: 4 Year Made: 2000 Enter Price: 12650 Car Characteristics Make: Toyota Model: Corolla Doors: 4 Year: 2000 Value: $12,650.00 Press any key to continue . . . This also means that you can pass a class type as a tracking reference or as a handle with the goal of updating it. Again, this also means that you can pass different handles to a function and have that function return more than one value. Remember that if a function modifies the handle, you must not pass it as a constant.
We saw that, when a function receives a handle as argument, if it modifies the value of that handle, the argument would keep the changes when the function terminates. You can reinforce this by passing the argument as a tracking reference. To do this, enter the % operator between the ^ and the name of the argument. Here is an example: void Show(CCar ^ %car); Notice that the space, or lack of it, between both operators, is not important. The compiler will reconcile it when running the application. When using the argument, you can access its member variables using either the period or the arrow operator. Here are both functions implemented: using namespace System; public value class CCar { public: String ^ Make; String ^ Model; int Doors; int Year; double Price; }; void Build(CCar ^ %car); void Show(const CCar ^ car); int main() { Console::WriteLine(L"Enter Car Information"); CCar ^ vehicle = gcnew CCar; Build(vehicle); Console::WriteLine(L"\nCar Characteristics"); Show(vehicle); Console::WriteLine(); return 0; } void Build(CCar ^ %car) { Console::Write(L"Enter Make: "); car->Make = Console::ReadLine(); Console::Write(L"Enter Model: "); car->Model = Console::ReadLine(); Console::Write(L"# of Doors: "); car->Doors = int::Parse(Console::ReadLine()); Console::Write(L"Year Made: "); car->Year = int::Parse(Console::ReadLine()); Console::Write(L"Enter Price: "); car->Price = double::Parse(Console::ReadLine()); } void Show(const CCar ^ car) { . . . } You can also pass a handle as a native reference by using & instead of %. This can be done as follows: using namespace System; public value class CCar { public: String ^ Make; String ^ Model; int Doors; int Year; double Price; }; void Build(CCar ^ &car); void Show(const CCar ^ car); int main() { . . . Console::WriteLine(); return 0; } void Build(CCar ^ &car) { . . . } void Show(const CCar ^ car) { . . . } |
|
||
Previous | Copyright © 2006-2016, FunctionX, Inc. | Next |
|