- •1.3.1 Введение 13
- •1.5.1 Введение 37
- •2. Introduction to Variables 69
- •3. Data Types 72
- •4. Techniques of Using Variables 90
- •5. Introduction to Classes 115
- •5.4.1 Introduction 129
- •6. Classes and Memory Management 131
- •6.1.1 Native References 131
- •6.5.1 Introduction 140
- •7. Classes Combinations and Inheritance 152
- •7.2.1 Introduction 165
- •7.3.1 Introduction 171
- •8. Data Input/Output, Reading, and Formatting 173
- •8.1.1 Introduction 173
- •8.5.1 Introduction 189
- •8.6.1 Introduction 195
- •9. Introduction to Functions 201
- •10. Details on Passing Arguments 225
- •10.3.1 Introduction 237
- •11. Classes and Functions 242
- •11.1.2 Practical Learning: Introducing Data Reading 243
- •11.5.1 Introduction 264
- •12. Classes and their Methods 268
- •12.1.2 Practical Learning: Introducing Data Reading 268
- •12.4.1 Introduction 284
- •13. Class Construction and Destruction 290
- •13.3.1 Introduction 311
- •14. The Properties of a Class 315
- •14.1.1 Introduction 315
- •15. Function Pointers and Delegates 337
- •15.1.1 Introduction 337
- •15.3.1 Introduction 346
- •16. Introduction to Conditions 359
- •16.1.1 Introduction 359
- •16.2.1 Introduction 369
- •25.3.1 Introduction 543
- •26. Multi-Dimensional Arrays 556
- •26.1.1 Introduction 556
- •26.2.1 Introduction 566
- •27.1.1 Introduction 595
- •34. Введение в коллекции 743
- •35. Основы коллекций платформы .Net (Fundamentals of .Net Support For Collections) 779
- •36. Встроенные интерфейсы коллекций 797
- •37. Встроенные классы коллекций 841
- •1.1Основы
- •1.1.1Введение в с
- •1.1.2Библиотека Win32
- •1.1.4Библиотека mfc
- •1.1.6Microsoft Visual Basic
- •1.2The Microsoft .Net Framework
- •1.2.1 Введение
- •1.2.2 Помощь сом
- •1.3.1Введение
- •1.3.2Компилятор
- •1.3.3Компилятор cl
- •1.4.1Функция main()
- •Int main()
- •1.4.2Консольный ввод и вывод
- •Void main()
- •Int X; // Целочисленная переменная X
- •1.4.3Директива препроцессора #pragma region
- •1.4.4Использование дескрипторов
- •Void Handles()
- •1.4.5Одномерные массивы
- •Void SingleDimensional()
- •1.4.6Многомерные массивы
- •Void CreateArr2()
- •Void CreateJaggedArray()
- •1.4.7Передача массивов функциями
- •1.4.8Классы значения
- •1.4.9Классы ссылки
- •1.4.10Интерфейсы
- •1.4.11Абстрактные классы
- •Void Foo2(){} // и так тоже можно
- •Virtual int Foo()override {return 1024;}
- •Void Abstract()
- •1.4.12Запечатанные классы и виртуальные функции
- •Void Sealed()
- •1.4.13 Видимость компонентов классов и структур
- •1.4.14Свойства
- •Void SimpleIndexProp()
- •Value class p4
- •Int Value;
- •Void set(int X, int value)
- •Void DifficultIndexedProperty()
- •Int Value;
- •Void set(int X, int value)
- •Void DefaultIndexedProperty()
- •1.4.15Деструкторы классов
- •Value class DestructorValue
- •Void SimpleDestructorDemo()
- •Void DerivedClassDestructorDemo()
- •Void Destructors()
- •1.4.16 Приведение типов
- •Void DynamicCast()
- •If(icomp)
- •Void SafeCast()
- •Void ExplicitTypeConversion()
- •Void Casting()
- •1.4.17 Класс Array
- •IStructuralComparable, iStructuralEquatable
- •Void DemoArray()
- •1.4.18 Введение в коллекции
- •Void DemoArrayList()
- •1.5.1Введение
- •Include file.H
- •1.5.3Создание консольного приложения
- •1.5.4Открытие проекта
- •1.5.7Start Without Debugging
- •1.5.8Code Comments
- •Int main()
- •Int main()
- •I can write anything I want in it */
- •1.5.9Indentation
- •Int main()
- •I can write anything I want in it */
- •1.5.10Escape Sequences
- •1.6Введение в классы
- •Int protect()
- •Int main()
- •1.7.1Source Files
- •1.7.2Practical Learning: Creating a Source File
- •1.7.3Header Files
- •1.7.4Practical Learning: Creating a Header File
- •Int ShowWelcome();
- •Int cProperty::ShowWelcome()
- •1.7.5Assemblies
- •1.7.6Applications
- •1.7.7The Public and Private Objects of an Assembly
- •1.7.8Practical Learning: Controlling the Assembly Access of a Class
- •1.7.9Creating a Class
- •1.7.10Practical Learning: Creating a Class
- •1.8The Code Editor
- •1.8.1 Description
- •1.8.2The Tabs Bar
- •1.8.3The Scopes Combo Box
- •1.8.4The Functions Combo Box
- •1.8.5Code Colors
- •1.9The Solution Explorer
- •1.9.1 Introduction
- •1.9.2 Using the Solution Explorer
- •1.10The Class View
- •1.10.1Introduction
- •1.10.2Using the Class View
- •1.11Namespaces and Code Directives
- •1.11.1Introduction
- •1.11.2Practical Learning: Including a Class in a Namespace
- •1.11.3Using a Namespace
- •Int drive()
- •Int main()
- •Int main()
- •1.11.4Using Various Namespaces
- •Int drive()
- •Int showroof()
- •Int drive()
- •Int main()
- •Int drive()
- •Int main()
- •Int drive()
- •Int main()
- •1.11.5Nesting Namespaces
- •Int main()
- •Int main()
- •1.11.6Built-In Namespaces
- •1.11.6.1 The System Namespace
- •Int main()
- •1.11.6.2The std Namespace
- •Int main()
- •Int main()
- •Int main()
- •Int main()
- •1.12C Routines
- •Int main()
- •1.13Primary Details of Program Structure
- •1.13.1Preprocessors: #include
- •1.13.2Preprocessors: #define
- •Int main()
- •1.14Pragma Directives
- •1.14.1 Introduction
- •1.14.2Open Once
- •2. Introduction to Variables
- •2.1Introduction
- •2.2The Stack
- •2.3Variable Declaration
- •2.5Keywords
- •Internal initonly interface literal long
- •Value virtual void volatile wchar_t
- •3.Data Types
- •3.1Variable Initialization
- •3.2Introduction to Data Types
- •3.3Practical Learning: Introducing Data Types Applications
- •Int main()
- •3.4Integers
- •3.4.1Signed and Unsigned Numbers
- •3.4.2Bytes
- •Int main()
- •Int main()
- •3.4.3Practical Learning: Declaring a Byte Variable
- •Int main()
- •3.4.4Short Variables
- •Int main()
- •Int main()
- •Int main()
- •Int main()
- •Int main()
- •Int main()
- •3.4.5Integral Variables
- •Int main()
- •3.4.6Practical Learning: Declaring Unsigned Variables
- •3.4.7Long Integers
- •Int main()
- •3.4.8Practical Learning: Declaring Long Integers
- •Int main()
- •3.4.9Initializing an Integral Variable
- •3.5Characters
- •3.5.1 Symbolic Characters
- •Int main()
- •Int main()
- •3.5.2Unicode Characters
- •Int main()
- •Int main()
- •3.5.3Practical Learning: Using Character Variables
- •Int main()
- •3.6The String: a List of Characters
- •Int main()
- •3.7Decimal Numbers
- •3.7.1Floating-Point Variables
- •Int main()
- •3.7.2Practical Learning: Using a Single-Precision Variables
- •Int main()
- •3.7.3Double-Precision Variables
- •Int main()
- •3.7.4Practical Learning: Using a Single-Precision Variables
- •Int main()
- •3.7.5Initializing a Double-Precision Variable
- •Int main()
- •Int main()
- •3.8Variable Reference
- •3.8.1 The typedef Type Definition
- •Int main()
- •Int main()
- •3.9Native References
- •Int &Mine;
- •Int main()
- •Int main()
- •Its reference: 228
- •Int main()
- •Its reference: 228
- •Its reference: -15008
- •Its reference: 28114
- •Int main()
- •Int main()
- •3.10A Tracking Reference (отслеживаемая ссылка)
- •Int main()
- •Int % PropertyValue;
- •Int main()
- •4. Techniques of Using Variables
- •4.1 Constant Values
- •4.1.1 Introduction
- •Int main()
- •Int main()
- •4.1.2Custom Constants
- •Int main()
- •Int main()
- •4.1.3Language Constants
- •Int main()
- •4.1.4Using #define
- •Int main()
- •Int main()
- •4.2Pointer Types
- •4.2.1 Introduction
- •Int main()
- •4.2.2Pointer Declaration
- •Int main()
- •Int *Number;
- •4.2.3Pointer Initialization
- •Int main()
- •Int main()
- •Int main()
- •Int main()
- •Int *Number;
- •Int main()
- •Int *Number;
- •4.2.4A Pointer to a Pointer
- •Int main()
- •Int *pointer;
- •Int main()
- •Int *pointer;
- •Int **pointerToPointer;
- •Int main()
- •Int *pointer;
- •Int **pointerToPointer;
- •Int main()
- •Int *pointer;
- •Int **pointerToPointer;
- •4.2.5Type Defining a Pointer
- •Int *pAge;
- •4.3Pointers and Memory Management
- •4.3.1 Introduction
- •Int main()
- •Int main()
- •Int main()
- •4.3.2The new Operator
- •Int main()
- •4.3.3Practical Learning: Introducing Pointers
- •Int main()
- •4.3.4The delete Operator
- •Int main()
- •4.3.5Practical Learning: Deleting Pointers
- •Int main()
- •4.4Handle Types
- •4.4.1 Introduction
- •4.4.2A Tracking Reference
- •Int main()
- •Int main()
- •4.4.3Creating a Handle (дескриптор)
- •Int main()
- •Int main()
- •Item Price:
- •4.5Using the Garbage Collector
- •Int main()
- •Int main()
- •Item Price: 148.95
- •Int main()
- •Int main()
- •Item Price: 148.95
- •Int main()
- •Int main()
- •Int main()
- •4.5.1Practical Learning: Using Handles
- •Int main()
- •5. Introduction to Classes
- •5.1 A Review of Classes
- •5.1.1 Introduction
- •Int main()
- •Int Bedrooms;
- •Int YearBuilt;
- •5.1.2Practical Learning: Introducing Classes
- •Int main()
- •5.2Creating a Class
- •5.2.1Practical Learning: Creating a Class
- •5.3Value Types
- •5.3.1 Introduction
- •5.3.2Practical Learning: Creating a Value Class
- •5.3.3Creating a Value Type
- •5.3.4Techniques of Initializing an Object
- •Int Bedrooms;
- •Int YearBuilt;
- •Int main()
- •Int Bedrooms;
- •Int YearBuilt;
- •Int main()
- •Int Bedrooms;
- •Int YearBuilt;
- •5.3.5Practical Learning: Initializing an Object
- •Int main()
- •5.3.6Class Members Levels of Access
- •Int Bedrooms;
- •Int YearBuilt;
- •Int Bedrooms;
- •Int YearBuilt;
- •Int main()
- •Int Bedrooms;
- •Int YearBuilt;
- •Int main()
- •5.3.7Practical Learning: Controlling the Access to a Class
- •5.3.8Type-Defining a Class
- •Int Bedrooms;
- •Int YearBuilt;
- •Int main()
- •5.3.9Constant Objects
- •Int Bedrooms;
- •Int YearBuilt;
- •Int main()
- •5.4Union
- •5.4.1Introduction
- •Int YearBuilt;
- •Int YearBuilt;
- •Int main()
- •5.4.2Using a Union
- •Int Bedrooms;
- •Int YearBuilt;
- •Int main()
- •6.2Introduction to Pointers to Classes
- •6.2.1Practical Learning: Introducing Pointers to Classes
- •6.2.2Accessing the Members of a Pointer to a Class
- •Int main()
- •Int main()
- •6.2.3Practical Learning: Accessing the Members of a Pointer to a Class
- •Int Bedrooms;
- •Int YearBuilt;
- •Int main()
- •6.3Allocating Memory on the Native Heap
- •Int main()
- •6.3.1Practical Learning: Allocating Memory on the Native Heap
- •Int Bedrooms;
- •Int YearBuilt;
- •Int main()
- •Int main()
- •6.3.3Practical Learning: De-Allocating Memory from the Native Heap
- •Int Bedrooms;
- •Int YearBuilt;
- •Int main()
- •6.4Classes and Pointers to Pointers
- •6.4.1Declaring a Pointer to Pointer
- •Int main()
- •Int main()
- •Int main()
- •Int main()
- •6.5Handle Types
- •6.5.1 Introduction
- •6.5.2Practical Learning: Introducing Handles
- •Int main()
- •6.5.3A Tracking Reference
- •Int main()
- •6.5.4Creating a Handle
- •Int NumberOfBedrooms;
- •Int YearBuilt;
- •Int main()
- •Int main()
- •Int NumberOfBedrooms;
- •Int YearBuilt;
- •Int main()
- •6.5.5Practical Learning: Creating a Handle
- •Int main()
- •6.6Reference Types
- •Int NumberOfBedrooms;
- •Int YearBuilt;
- •Int main()
- •Int NumberOfBedrooms;
- •Int YearBuilt;
- •Int main()
- •Int NumberOfBedrooms;
- •Int YearBuilt;
- •Int main()
- •Int NumberOfBedrooms;
- •Int YearBuilt;
- •Int main()
- •Int NumberOfBedrooms;
- •Int YearBuilt;
- •Int main()
- •6.6.1Practical Learning: Creating a Reference Class
- •6.6.2Accessing the Members of a Handle
- •Int NumberOfBedrooms;
- •Int YearBuilt;
- •Int main()
- •Int NumberOfBedrooms;
- •Int YearBuilt;
- •Int main()
- •6.6.3Using the Garbage Collector
- •Int NumberOfBedrooms;
- •Int YearBuilt;
- •Int main()
- •6.6.4Practical Learning: Initializing a Handle
- •Int main()
- •7.Classes Combinations and Inheritance
- •7.1Class Combinations (агрегирование классов)
- •7.1.1 A Class as a Member Variable
- •Int Bedrooms;
- •Int YearBuilt;
- •Int main()
- •Int main()
- •7.1.2Practical Learning: Using an Object as a Field
- •7.1.3Introduction to Strings
- •Int main()
- •Int main()
- •7.1.4Practical Learning: Using String Variables
- •7.1.5A String as a Member Variable of a Class
- •7.1.6Practical Learning: Using Strings as Fields
- •7.2Inheritance
- •7.2.1 Introduction
- •7.2.2Practical Learning: Introducing Inheritance
- •7.2.3Inheriting From a Class
- •Int Bedrooms;
- •Int YearBuilt;
- •Int Bedrooms;
- •Int YearBuilt;
- •Int Condition;
- •7.2.4Practical Learning: Inheriting From a Class
- •7.2.5The protected Access Level
- •Int Bedrooms;
- •Int YearBuilt;
- •7.2.6Namespaces and Inheritance
- •7.3The Object Class
- •7.3.1 Introduction
- •7.3.2An Object as a Handle
- •Int main()
- •Int main()
- •7.3.3Inheriting from the Object Class
- •7.3.4Practical Learning: Inheriting From the Object Class
- •8.Data Input/Output, Reading, and Formatting
- •8.1 Displaying Data
- •8.1.1 Introduction
- •8.1.2General Display With cout, Write(), and WriteLine()
- •Int main()
- •Int main()
- •8.1.3Data Display With puts()
- •Int main()
- •Int main()
- •Int main()
- •Int main()
- •Int main()
- •Int main()
- •8.2.2Filling the Empty Space
- •Int main()
- •Int main()
- •8.2.3The dec, hex, and oct Operators
- •Int main()
- •Int main()
- •8.2.4The uppercase Attribute
- •8.2.5Setting the I/o Flag
- •Int main()
- •Int main()
- •Int main()
- •Int main()
- •8.2.7C How to Display Data
- •Int main()
- •Int main()
- •8.3Data Input
- •8.3.1Using cin
- •Int main()
- •Int Natural;
- •8.3.2C How to Input Data
- •8.4Accessories
- •8.4.1Exiting a Program
- •Int main()
- •8.4.2Aborting a Program
- •8.4.3Terminating a Program
- •8.4.4Clearing the Screen
- •Int NumberOfBedrooms;
- •Int YearBuilt;
- •Int main()
- •8.5.1 Introduction
- •8.5.2Practical Learning: Introducing Data Reading
- •Int Bedrooms;
- •Int YearBuilt;
- •Int Condition;
- •Int main()
- •8.5.3String Value Request
- •Int main()
- •8.5.4Character and Number Request
- •Int main()
- •Int Number;
- •8.5.5Practical Learning: Requesting Data
- •8.6Formatting Data Display
- •8.6.1 Introduction
- •Int main()
- •8.6.2Conversion To String
- •Int main()
- •8.6.3Number Formatting
- •Int main()
- •8.6.4Line Formatting
- •Int main()
- •8.6.5Practical Learning: Formatting Data
- •Int main()
- •9. Introduction to Functions
- •9.1 Functions
- •9.1.1 Definition
- •9.1.2Fundamentals of Creating a Function
- •Void Introduction() { Console::WriteLine(l"The Wonderful World of
- •Void Introduction()
- •Int main()
- •9.1.3Calling a Function
- •Void Introduction()
- •Int main()
- •Introduction();
- •Int main()
- •Void IdentifyHouse();
- •Void IdentifyHouse()
- •9.1.4Practical Learning: Introducing Functions
- •Void CreateAndShowProperty()
- •Int condition;
- •9.1.5Inline Functions
- •9.2Techniques of Returning a Value
- •9.2.1 Returning a Primitive Type
- •Int main()
- •9.2.2Practical Learning: Returning a Primitive Type
- •Int GetPropertyCondition()
- •Int condition;
- •Void CreateAndShowProperty()
- •Int condition;
- •Int main()
- •9.2.3Returning a Native Reference
- •Int main()
- •9.2.4Returning a Tracking Reference
- •Int main()
- •9.2.5Returning a Pointer
- •Int main()
- •9.2.6Returning a Handle
- •9.2.7Practical Learning: Returning a Handle
- •Void CreateAndShowProperty()
- •Int main()
- •9.3Introduction to Functions Parameters
- •9.3.1 Overview of Parameters
- •Int main()
- •9.3.2Arguments to a Function
- •Void SetGender(__wchar_t a);
- •Void CalculateRateAmount(double price, double rate)
- •9.3.3Practical Learning: Introducing Functions
- •Void ShowProperty(long propNbr, int cond, Byte levels,
- •9.3.4Static Variables
- •Void Starter(int y)
- •Int main()
- •Void Starter(int y)
- •Int main()
- •Void Starter(int y)
- •Int main()
- •10.Details on Passing Arguments
- •10.1 Common Techniques of Using Parameters
- •10.1.1 Function Overloading
- •Int main()
- •10.1.2Default Arguments
- •Int main()
- •Int main()
- •Int main()
- •Int main()
- •Int main()
- •10.1.3Constant Arguments
- •Int main()
- •10.2Passing Arguments by Reference
- •10.2.1 Passing by Native Reference
- •Void Area(double &Side); // The argument is passed by reference
- •Void Area(double &);
- •10.2.2Passing by Constant Reference
- •Void DisplayResult(const double OrigPrice, const double DiscAmt,
- •10.2.3Passing by Tracking Reference
- •10.3Passing a Pointer as Argument
- •10.3.1 Introduction
- •Int main()
- •Int main()
- •Int main()
- •10.3.2Constant Pointers as Arguments
- •Int main()
- •10.3.3Passing a Pointer to a Pointer
- •10.3.4Passing an Argument as a Reference to a Pointer
- •Int main()
- •10.3.5Passing an Argument as a Handle
- •Int main()
- •11.Classes and Functions
- •11.1 Returning a Class Type
- •11.1.1 Returning a Tracking Reference
- •Int Doors;
- •Int Year;
- •Int main()
- •11.1.2Practical Learning: Introducing Data Reading
- •Int Bedrooms;
- •Int YearBuilt;
- •Int Condition;
- •Int main()
- •11.1.3Returning a Handle
- •11.1.4Practical Learning: Returning a Handle
- •Int main()
- •11.2Passing a Class Type
- •11.2.1 Passing a Tracking Reference
- •Void DescribeProperty(cHouse % home);
- •Void Show(cCar % car)
- •11.2.2Passing a Handle
- •11.2.3Practical Learning: Passing a Handle
- •Int main()
- •11.2.4The Effect of Passing a Class as a Tracking Reference or as a Handle
- •Int Doors;
- •Int Year;
- •Int main()
- •11.2.5Passing a Handle as a Reference
- •Int Doors;
- •Int Year;
- •Int main()
- •Int Doors;
- •Int Year;
- •Int main()
- •11.3Using the String Class
- •11.3.1 Returning a String
- •Int main()
- •11.3.2Passing a String
- •Int main()
- •11.4Introduction to the Methods of a Class
- •11.4.1 Methods Fundamentals
- •11.4.2Practical Learning: Introducing Methods
- •Int main()
- •11.4.3Method Local Definition
- •Int Doors;
- •Int Year;
- •Void Build()
- •Int main()
- •11.4.4Practical Learning: Implementing a Method Locally
- •Void CreateStoreItem()
- •11.4.5Method Global Definition
- •Int Doors;
- •Int Year;
- •Void Build()
- •Void Show();
- •Void cCar::Show()
- •Int main()
- •11.4.6Practical Learning: Implementing Methods Globally
- •Void CreateStoreItem();
- •Void ItemDescription();
- •Void cStoreItem::CreateStoreItem()
- •Void cStoreItem::ItemDescription()
- •Int main()
- •Item Number: 624406
- •Item Number: 624406
- •11.4.7Inline Methods
- •11.5Class and Self Return
- •11.5.1 Introduction
- •Int NumberOfBedrooms;
- •Int YearBuilt;
- •11.5.2This Pointer
- •Void cHouse::Show()
- •11.5.3Practical Learning: Using the this Pointer
- •Void cStoreItem::CreateStoreItem()
- •0 If no discount): ");
- •Void cStoreItem::ItemDescription()
- •12.1.3Constant Arguments
- •Int main()
- •12.1.4Practical Learning: Passing Constant Arguments
- •0 If no discount): ");
- •Item Number: 204066
- •Item Number: 204066
- •12.1.5Private Methods
- •Void Show();
- •Void cBox::Show()
- •Int main()
- •12.1.6Protected Methods
- •12.2Static Members of a Class
- •12.2.1 Static Member Variables
- •Void cCar::Show()
- •Int main()
- •12.2.2Static Methods
- •Int Doors;
- •Int Year;
- •Void Build();
- •Int Doors;
- •Int Year;
- •Int main()
- •Int Doors;
- •Int Year;
- •Int main()
- •12.3Classes and Constants
- •12.3.1 Static Constants
- •Inside a ref class or value type
- •12.3.2Literal Constants
- •12.4Class Nesting
- •12.4.1 Introduction
- •12.4.2Implementing Methods of a Nested Class
- •13. Class Construction and Destruction
- •13.1 Class Construction
- •13.1.1 Method Initializer
- •Int Type;
- •Int Color;
- •Int main()
- •Int Type;
- •Int Color;
- •Void Initializer(int type, int color, __wchar_t arrange,
- •Void cFlower::Initializer(int tp, int clr,
- •13.1.2Practical Learning: Introducing Constructors
- •Int main()
- •13.1.3Default Constructor
- •Int Type;
- •Int Color;
- •Int Type;
- •Int Color;
- •Int main()
- •Int main()
- •Int Type;
- •Int Color;
- •13.1.4Practical Learning: Using the Default Constructor
- •13.1.5The Constructor Initializer
- •Int main()
- •13.1.6Practical Learning: Initializing Using the Default Constructor
- •Int main()
- •Item Number: 0
- •13.1.7Constructor Overloading
- •Int main()
- •13.1.8Practical Learning: Overloading the Constructor
- •Inline long cStoreItem::GetItemNumber()
- •Inline void cStoreItem::SetItemNumber(const long number)
- •13.1.9Techniques of Initializing With a Constructor
- •Int main()
- •13.1.10Practical Learning: Initializing With the Constructors
- •13.2The Copy Constructor
- •13.2.1 Copying an Object
- •Int main()
- •13.2.2Using a Copy Constructor
- •13.3Destructors
- •13.3.1Introduction
- •13.3.2Practical Learning: Creating a Destructor
- •13.3.3Object Destruction in the Native Heap
- •13.3.4Object Destruction and the Managed Heap
- •14. The Properties of a Class
- •14.1Properties Fundamentals
- •14.1.1Introduction
- •14.1.2Practical Learning: Introducing the Properties of a Class
- •Int main()
- •14.1.3Reference Methods
- •Int main()
- •Int main()
- •14.1.4A Property
- •14.2Types of Properties
- •14.2.1 Simple Properties
- •Void ShowCharacteristics(cRectangle %recto)
- •Int main()
- •Int main()
- •14.2.2Practical Learning: Creating Simple Properties
- •Int main()
- •Item Number: 0
- •Item Number: 513497
- •14.2.3Read-Only Properties
- •Int main()
- •14.2.4Practical Learning: Using Read-Only Properties of a Class
- •Int main()
- •14.2.5Write-Only Properties
- •Void set(double h) { }
- •Int main()
- •14.2.6Read/Write Properties
- •14.2.7Practical Learning: Using Read/Write Properties of a Class
- •Int main()
- •Information");
- •Item Number: 666802
- •Item Number: 666802
- •14.3Other Techniques of Implementing Properties
- •14.3.1 Static Properties
- •Int main()
- •Int main()
- •Int main()
- •Int main()
- •15.1.2Declaring a Pointer to Function
- •Int main()
- •Void (*SomethingToSay)(void);
- •Void MovieQuote()
- •Void MovieQuote()
- •Int main()
- •Void (*SomethingToSay)();
- •15.1.3A Function Pointer that Returns a Value
- •Int Addition()
- •Int main()
- •Int (*SomeNumber)();
- •15.1.4A Function Pointer With Arguments
- •15.1.5Type-Defining a Function Pointer
- •Int Addition(int a, int b)
- •Int main()
- •15.1.6A Pointer to a Function as Argument
- •Int main()
- •15.2Classes and Pointers to Functions
- •15.2.1A Pointer to Function as a Member Variable
- •Int main()
- •Int main()
- •15.3Delegates
- •15.3.1 Introduction
- •15.3.2Practical Learning: Introducing Delegates
- •Void Show();
- •Void cFlower::Show()
- •Int main()
- •15.3.3Delegate Declaration
- •15.3.4Practical Learning: Creating a Delegate
- •Int main()
- •15.3.5Techniques of Using a Delegate
- •Int main()
- •Int main()
- •Int main()
- •Void ShowResult()
- •Int main()
- •15.3.6Practical Learning: Creating a Delegate
- •Int main()
- •15.3.7Delegates Compositions
- •15.3.8A Delegate With One of More Arguments
- •Void ShowResult()
- •Int main()
- •15.3.9Practical Learning: Using an Argumentative Delegate
- •Void Show(const int qty);
- •Void cFlower::Show(const int qty)
- •Int main()
- •15.3.10A Delegate Passed as Argument
- •Void CircleCharacteristics()
- •Int main()
- •16. Introduction to Conditions
- •16.1Boolean Variables
- •16.1.1 Introduction
- •16.1.2Practical Learning: Introducing Conditions
- •Int get() { return _tp; }
- •Int get() { return _clr; }
- •Int get() { return _qty; }
- •Int type, color, qty;
- •16.1.3Declaring a Boolean Variable
- •Int main()
- •Int main()
- •Int main()
- •Int main()
- •Int main()
- •16.1.4Retrieving the Value of a Boolean Variable
- •Int main()
- •If Yes, enter True. Otherwise enter False: true
- •16.1.5Creating a Boolean Member Variable
- •16.1.6 Boolean Arguments
- •16.1.7A Boolean Property
- •16.1.8 Practical Learning: Creating a Boolean Property
- •16.2Enumerations
- •16.2.1 Introduction
- •Int main()
- •Int main()
- •16.2.2 Indexing the Members of an Enumeration
- •Int main()
- •Int main()
- •Int main()
- •Int main()
- •16.2.3Declaring an Enumeration Variable
- •16.2.4Global Enumerations
- •16.2.5Enumerations and Assemblies
- •16.3Enumerations and Classes
- •16.3.1 An Enumeration as a Member Variable
- •16.3.2An Enumeration as a Class
- •16.3.4Practical Learning: Creating Enumerations
- •17. Conditional Operators
- •18. Conditional Statements
- •19. Counting and Looping
- •20. Strings
- •21. Techniques on Using Inheritance
- •22. Variable Scope and Casting
- •23. Templates
- •24. Generics
- •25.Введение в массивы
- •25.1 Описание
- •25.1.1 Определение
- •25.1.2Создание массива
- •Int main()
- •Int Numbers[5];
- •25.1.3Initializing an Array
- •Int main()
- •Int main()
- •25.1.4 Type Defining an Array
- •Int main()
- •25.2Arrays and Memory Management
- •25.2.1 Creating a Dynamic Array
- •Int main()
- •Int main()
- •25.2.2 Cleaning After an Array
- •Int main()
- •25.3Managed Arrays
- •25.3.1 Introduction
- •Int main()
- •Int main()
- •25.3.2Practical Learning: Introducing Arrays
- •Int main()
- •25.3.3An Array of Handles
- •Int main()
- •Int main()
- •Int main()
- •Int main()
- •Int main()
- •25.3.4Practical Learning: Using an Array of Handles
- •Int main()
- •25.4Arrays and Functions
- •25.4.1 Returning an Array
- •Int main()
- •25.4.2Practical Learning: Returning Arrays
- •25.4.3Passing an Array as Argument
- •25.4.4Practical Learning: Passing an Array as Argument
- •26. Multi-Dimensional Arrays
- •26.1 Single and Two-Dimensional Arrays
- •26.1.1 Introduction
- •26.1.2Practical Learning: Introducing Multi-Dimensional Arrays
- •26.1.4Multi-Dimensional Arrays
- •26.2Introduction to Jagged Arrays
- •26.2.1 Introduction
- •26.2.2 Creating a Jagged Array
- •26.2.3 Initializing a Jagged Array
- •26.3Jagged Arrays and Functions
- •26.3.1Returning a Jagged Array
- •26.3.2Passing a Jagged Array as Argument
- •26.4Multi-Dimensional Jagged Arrays
- •26.4.1Two-Dimensional Jagged Arrays
- •26.4.2Multi-Dimensional Jagged Arrays
- •27.Arrays and Classes
- •27.1The Array Class
- •27.1.1 Introduction
- •27.1.2 The Length of an Array
- •Int main()
- •28.Introduction to File Processing
- •29.Details on File Processing
- •30.Files Operations
- •31.Serialization
- •32.Introduction to Indexed Properties
- •33.Classes and Indexed Properties
- •34.Введение в коллекции
- •34.1Коллекции на основе массива
- •34.1.1Вступление
- •34.1.2Объявление коллекции
- •Int main()
- •34.1.3 Количество элементов в коллекции
- •34.2Операции над коллекцией, основанной на массиве
- •34.2.1 Добавление элемента
- •Int size;
- •Int get() { return size; }
- •Int main()
- •34.2.2 Извлечение элемента из коллекции
- •Int size;
- •Int get() { return size; }
- •Int main()
- •34.2.3 Вставка элемента в коллекцию
- •Int size;
- •Int get() { return size; }
- •1. Список не заполнен до конца
- •2. Указанная позиция находится в допустимом диапазоне
- •Int main()
- •34.2.4 Удаление элемента из коллекции
- •Int size;
- •Int get() { return size; }
- •Int main()
- •34.3Коллекция элементов (заказ букета цветов)
- •34.3.1 Вступление
- •34.3.2Practical Learning: Introducing Collections
- •34.3.3 Implementing a Collection
- •34.3.4 Practical Learning: Creating a cCollection Class
- •34.3.5The Beginning of a Collection
- •34.3.6 Linking the Items of a Collection
- •34.3.7 Practical Learning: Creating a List's Monitor
- •34.4 Коллекции на основе списка (Operations on a Collection)
- •34.4.1 Adding an Item
- •34.4.2 Practical Learning: Adding Items to a Collection
- •34.4.3Retrieving an Item
- •34.4.4 Practical Learning: Retrieving the Items of a Collection
- •34.4.5 Removing an Item
- •34.4.6 Practical Learning: Retrieving the Items of a Collection
- •34.4.7 Locating an Item
- •35.Основы коллекций платформы .Net (Fundamentals of .Net Support For Collections)
- •35.1 Перечисление элементов коллекции (Enumerating the Members of a Collection)
- •35.1.1 Введение в коллекции System
- •35.1.2Практический пример
- •Int Mileage;
- •Int items;
- •Int get() { return items; }
- •Virtual bool Delete() override;
- •Items--;
- •35.1.3Introduction to the iEnumerator Interface
- •35.1.4 Упражнение
- •35.1.5 Текущий элемент перечисления
- •35.1.6Упражнение
- •Int curPosition;
- •35.1.7Сброс метки текущего элемента
- •Void Reset();
- •Virtual void Reset();
- •Void cEnumerator::Reset()
- •35.1.8 Упражнение
- •Int curPosition;
- •Virtual void Reset();
- •Void cCarIdentifier::Reset()
- •35.1.9Перемещение к следующему элементу в iEnumerator
- •Virtual void Reset();
- •Virtual bool MoveNext();
- •Void cEnumerator::Reset()
- •35.1.10Упражнение
- •Int curPosition;
- •Virtual void Reset();
- •Virtual bool MoveNext();
- •Void cCarIdentifier::Reset()
- •35.2Перечислимая коллекция (An Enumerable Collection)
- •35.2.1 Вступление
- •35.2.2 Получение Enumerator (Getting the Enumerator)
- •35.2.3Упражнение
- •36.Встроенные интерфейсы коллекций
- •36.1 Обзор интерфейсов коллекций
- •36.1.1 Вступление
- •36.1.2Choosing a Class or an Interface
- •36.2Интерфейс iCollection
- •36.2.1 Вступление
- •36.2.2Реализация iCollection
- •Int nbrOfStudents;
- •Virtual property int Count
- •Int get() { return nbrOfStudents; }
- •Int nbrOfItems;
- •Virtual property int Count
- •Int get() { return nbrOfItems; }
- •Int nbrOfItems;
- •Int nbrOfItems;
- •Virtual property bool IsSynchronized
- •Int nbrOfItems;
- •36.3Интерфейс iList
- •36.3.1Вступление
- •36.3.2Упражнение
- •Int main()
- •36.3.3Implementing iList
- •36.3.4 Упражнение
- •36.4Размер коллекции
- •36.4.1 Коллекция фиксированного размера
- •Int items;
- •Virtual property bool IsFixedSize
- •36.4.2 Упражнение
- •Int counter;
- •Virtual property bool IsFixedSize
- •36.4.3Коллекция только для чтения
- •36.4.4Упражнение
- •Int counter;
- •Virtual void RemoveAt(int index);
- •Virtual void Clear(void);
- •36.5Наполнение коллекции
- •36.5.1 Добавление элементов
- •Int items;
- •36.5.2Упражнение
- •Int main()
- •36.5.3Вставка элемента
- •36.5.4Упражнение
- •Int main()
- •36.6Размещение элемента в коллекции
- •36.6.1 Значение по умолчанию в коллекции
- •Int items;
- •36.6.2Упражнение
- •Int counter;
- •Int main()
- •36.6.3Проверка существования элемента в коллекции
- •Int items;
- •36.6.4 Упражнение: проверка наличия элемента в коллекции
- •Int main()
- •36.6.5Получение индекса элемента
- •Int items;
- •36.6.6Упражнение: получение индекса элемента
- •Int main()
- •36.7Удаление элементов коллекции
- •36.7.1 Удаление элемента по его индексу
- •37.Встроенные классы коллекций
- •37.1 Класс ArrayList
- •37.1.1 Вступление
- •37.1.2 Емкость списка (The Capacity of a List)
- •37.1.3Список только для чтения
- •37.1.4Добавление элементов
- •37.1.5 Число элементов в списке
- •37.1.6 Получение элементов списка
- •37.1.7Доступ к элементу списка
- •37.1.8Удаление элемента
- •37.2Хеш-таблицы
- •37.2.1Вступление
- •37.2.2Создание хеш-таблицы
- •37.2.3Доступ к элементам хеш-таблицы
- •If (!diGcs.Exists)
- •If (!File.Exists(strFilename))
- •If (!File.Exists(strFilename))
- •If (File.Exists(strFilename))
- •If (File.Exists(strFilename))
- •If (File.Exists(strFilename))
- •37.2.4Доступ к элементу хеш-таблицы
- •37.2.5Удаление элементов хеш-таблицы
- •37.3Стек
- •37.3.1 Вступление
- •37.3.2Создание стека
- •37.3.3Добавление элементов в стек
- •37.3.4Доступ к элементам стека
- •37.3.5Удаление элементов из стека
- •37.4Очередь
- •37.4.1Вступление
- •37.4.2Создание очереди
- •37.4.3Построение очереди (Building a Queue)
- •37.4.4Получение элементов очереди
- •37.4.5Удаление элементов из очереди
31.Serialization
|
Object Serialization and De-Serialization |
|
Introduction |
|
Consider the following program:
using namespace System;
using namespace System::IO;
int main()
{
String ^ Make = L"Ford";
String ^ Model = L"Escort";
int Year = 1998;
int Color = 1;
FileStream ^ stmCar = gcnew FileStream(L"FordEscort.car",
FileMode::Create);
BinaryWriter ^ bnwCar = gcnew BinaryWriter(stmCar);
try {
bnwCar->Write(Make);
bnwCar->Write(Model);
bnwCar->Write(Year);
bnwCar->Write(Color);
}
finally
{
bnwCar->Close();
stmCar->Close();
}
return 0;
}
This is an example of the techniques we have used in previous lessons to save individual data of primitive types:
The values can be retrieved with the following code:
using namespace System;
using namespace System::IO;
int main()
{
String ^Make, ^Model;
int Year, Color;
FileStream ^ stmCar = gcnew FileStream(L"FordEscort.car",
FileMode::Open);
BinaryReader ^ bnrCar = gcnew BinaryReader(stmCar);
try {
Console::WriteLine(L"Make: {0}", bnrCar->ReadString());
Console::WriteLine(L"Model: {0}", bnrCar->ReadString());
Console::WriteLine(L"Year: {0}", bnrCar->ReadInt32());
Console::Write(L"Color: ");
int clr = bnrCar->ReadInt32();
switch(clr)
{
case 1:
Console::WriteLine(L"Black");
break;
case 2:
Console::WriteLine(L"Gray");
break;
case 3:
Console::WriteLine(L"White");
break;
case 4:
Console::WriteLine(L"Red");
break;
case 5:
Console::WriteLine(L"Blue");
break;
}
}
finally
{
bnrCar->Close();
stmCar->Close();
}
return 0;
}
This would produce:
Make: Ford
Model: Escort
Year: 1998
Color: Black
Press any key to continue . . .
In the same way, we learned to save the individual fields of a class:
Here is an example:
using namespace System;
using namespace System::IO;
public ref class CCar
{
public:
String ^ Make;
String ^ Model;
int Year;
int Color;
CCar();
};
CCar::CCar()
{
Make = L"Toyota";
Model = L"Corolla";
Year = 2002;
Color = 2;
}
int main()
{
CCar ^ vehicle = gcnew CCar;
FileStream ^ stmCar = File::Create(L"ToyotaCorolla.car");
BinaryWriter ^ bnwCar = gcnew BinaryWriter(stmCar);
try {
bnwCar->Write(vehicle->Model);
bnwCar->Write(vehicle->Year);
bnwCar->Write(vehicle->Color);
}
finally
{
bnwCar->Close();
stmCar->Close();
}
return 0;
}
When it comes to a class, the problem with saving individual fields is that you could forget to save one of the fields. For example, considering a Car class, if you don't save the Make information of a Car object and retrieve or open the saved object on another computer, the receiving user would miss some information and the car cannot be completely identifiable. An alternative is to save the whole Car object.
Object serialization consists of saving a whole object as one instead of its individual fields:
In other words, a variable declared from a class can be saved to a stream and then the saved object can be retrieved later or on another computer. The .NET Framework supports two types of object serialization: binary and SOAP.
Practical Learning: Introducing Serialization |
|
Start Microsoft Visual C++ and create a new CLR empty project named GeorgetownCleaningServices7
To add a new source file to the project, on the main menu, click Project -> Add New Item...
In the Templates list, click C++ File (.cpp)
Set the Name to Exercise and click Add
In the empty document, type the following:
using namespace System;
using namespace System::IO;
void HireEmployee()
{
FileStream ^ fsEmployee = nullptr;
BinaryWriter ^ bwEmployee = nullptr;
// Ask the clerk to enter an employee number
// using the format 00-000
Console::Write(L"Enter Employee Number (00-000): ");
String ^emplNumber = Console::ReadLine();
String ^ strPath = L"C:\\Georgetown Cleaning Services\\Employees\\"
+ emplNumber + L".gce";
if( File::Exists(strPath) )
{
Console::Write(L"\nEither the employee has already been hired, ");
Console::WriteLine(L"or there is already another employee with that number.");
return;
}
else // If no employee with that number was found, create it
{
try {
// If there is not yet a directory named Employees, then create it
Directory::CreateDirectory(L"C:\\Georgetown Cleaning Services\\Employees");
}
catch(DirectoryNotFoundException ^)
{
Console::WriteLine(L"The folder could not be created");
}
try {
fsEmployee = File::Create(strPath);
bwEmployee = gcnew BinaryWriter(fsEmployee);
Console::Write(L"Enter Employee First Name: ");
String ^emplFName = Console::ReadLine();
Console::Write(L"Enter Employee Last Name: ");
String ^emplLName = Console::ReadLine();
Console::Write(L"Enter Hourly Salary: ");
double emplSalary = double::Parse(Console::ReadLine());
// The minimum salary in this company is 7.50
if( emplSalary < 7.50 )
emplSalary = 7.50;
bwEmployee->Write(emplNumber);
bwEmployee->Write(emplFName);
bwEmployee->Write(emplLName);
bwEmployee->Write(emplSalary);
}
finally
{
bwEmployee->Close();
fsEmployee->Close();
}
}
Console::WriteLine();
}
int main()
{
wchar_t answer = L'0';
do {
try {
Console::WriteLine(L"What do you want to do?");
Console::WriteLine(L"0. Quit");
Console::WriteLine(L"1. Hire a new employee");
Console::WriteLine(L"2. Process a payroll");
Console::Write(L"Your Choice: ");
answer = wchar_t::Parse(Console::ReadLine());
}
catch(FormatException ^)
{
Console::WriteLine(L"Invalid Answer!");
}
switch(answer)
{
case L'1':
HireEmployee();
break;
case L'2':
break;
default:
break;
}
} while (answer == L'1' || answer == L'2');
Console::WriteLine();
return 0;
}
Execute the application and test it. Here is an example:
What do you want to do?
0. Quit
1. Hire a new employee
2. Process a payroll
Your Choice: 1
Enter Employee Number (00-000): 86-225
Enter Employee First Name: Anne
Enter Employee Last Name: Harang
Enter Hourly Salary: 16.75
What do you want to do?
0. Quit
1. Hire a new employee
2. Process a payroll
Your Choice: 1
Enter Employee Number (00-000): 42-713
Enter Employee First Name: Peter
Enter Employee Last Name: Lansome
Enter Hourly Salary: 12.45
What do you want to do?
0. Quit
1. Hire a new employee
2. Process a payroll
Your Choice: 1
Enter Employee Number (00-000): 29-368
Enter Employee First Name: Gertrude
Enter Employee Last Name: Monay
Enter Hourly Salary: 10.85
What do you want to do?
0. Quit
1. Hire a new employee
2. Process a payroll
Your Choice: 0
Press any key to continue . . .
Close the DOS window
Serialization |
|
Binary serialization works by processing an object rather than streaming its individual member variables. This means that, to use it, you define an object and initialize it, or "fill" it, with the necessary values and any information you judge necessary. This creates a "state" of the object. It is this state that you prepare to serialize. When you save the object, it is converted into a stream.
To perform binary serialization, there are a few steps you must follow. When creating the class whose objects would be serialized, start it with the [Serializable] attribute. Here is an example:
[Serializable]
public ref class CCar
{
public:
String ^ Make;
String ^ Model;
int Year;
int Color;
CCar();
};
Before serializing an object, you should reference the System::Runtime::Serialization::Formatters::Binary namespace. The class responsible for binary serialization is called BinaryFormatter. This class is equipped with two constructors. The default constructor is used to simply create an object. After declaring the variable, to actually serialize an object, call the Serialize() method of the BinaryFormatter class. The method is overloaded with two versions. One of the versions of this method uses the following syntax:
public:
virtual void Serialize(Stream ^ serializationStream,
Object ^ graph) sealed;
The first argument to this method must be an object of a Stream-based class. In the previous lessons, we saw how to create Stream objects (for example using the FileStream class).
The second argument must be the object to serialize. This means that, before calling this method, you should have built the object.
Here is an example:
using namespace System;
using namespace System::IO;
using namespace System::Runtime::Serialization::Formatters::Binary;
[Serializable]
public ref class CCar
{
public:
String ^ Make;
String ^ Model;
int Year;
int Color;
};
int main()
{
CCar ^ vehicle = gcnew CCar;
vehicle->Make = L"Lexus";
vehicle->Model = L"LS";
vehicle->Year = 2007;
vehicle->Color = 4;
FileStream ^ stmCar = gcnew FileStream(L"LexusLS.car",
FileMode::Create);
BinaryFormatter ^ bfmCar = gcnew BinaryFormatter;
bfmCar->Serialize(stmCar, vehicle);
return 0;
}
Practical Learning: Serializing an Object |
|
To create a new class, in the Class View, right-click GeorgetownCleaningServices7 -> Add -> Class...
In the Templates list, click C++ Class and click Add
Set the Name to CPayrollInformation and click Finish
Change the PayrollInformation.h header file as follows:
#pragma once
using namespace System;
[Serializable]
public ref class CPayrollInformation
{
private:
String ^ number;
String ^ fname;
String ^ lname;
double salary;
DateTime start;
public:
CPayrollInformation(void);
property String ^ EmployeeNumber
{
String ^ get() { return this->number; }
void set(String ^ value) { this->number = value; }
}
property String ^ FirstName
{
String ^ get() { return this->fname; }
void set(String ^ value) { this->fname = value; }
}
property String ^ LastName
{
String ^ get() { return this->lname; }
void set(String ^ value) { this->lname = value; }
}
property double HourlySalary
{
double get() { return this->salary; }
void set(double value) { this->salary = value; }
}
property DateTime StartPeriod
{
DateTime get() { return this->start; }
void set(DateTime value) { this->start = value; }
}
property DateTime EndPeriod
{
DateTime get() { return start.AddDays(13); }
}
double Week1Monday;
double Week1Tuesday;
double Week1Wednesday;
double Week1Thursday;
double Week1Friday;
double Week2Monday;
double Week2Tuesday;
double Week2Wednesday;
double Week2Thursday;
double Week2Friday;
double RegularHours;
double OvertimeHours;
double RegularAmount;
double OvertimeAmount;
double TotalEarnings;
};
Access the Exercise.cpp source file and change it as follows:
#include "PayrollInformation.h"
using namespace System;
using namespace System::IO;
using namespace System::Runtime::Serialization::Formatters::Binary;
void HireEmployee();
void CreatePayroll();
void SavePayroll(CPayrollInformation ^ pay);
void ShowPayroll(CPayrollInformation ^ payed);
void HireEmployee()
{
FileStream ^ fsEmployee = nullptr;
BinaryWriter ^ bwEmployee = nullptr;
// Ask the clerk to enter an employee number
// using the format 00-000
Console::Write(L"Enter Employee Number (00-000): ");
String ^emplNumber = Console::ReadLine();
String ^ strPath = L"C:\\Georgetown Cleaning Services\\Employees\\"
+ emplNumber + L".gce";
if( File::Exists(strPath) )
{
Console::Write(L"\nEither the employee has already been hired, ");
Console::WriteLine(L"or there is already another employee with that number.");
return;
}
else // If no employee with that number was found, create it
{
try {
// If there is not yet a directory named Employees, then create it
Directory::CreateDirectory(L"C:\\Georgetown Cleaning Services\\Employees");
}
catch(DirectoryNotFoundException ^)
{
Console::WriteLine(L"The folder could not be created");
}
try {
fsEmployee = File::Create(strPath);
bwEmployee = gcnew BinaryWriter(fsEmployee);
Console::Write(L"Enter Employee First Name: ");
String ^emplFName = Console::ReadLine();
Console::Write(L"Enter Employee Last Name: ");
String ^emplLName = Console::ReadLine();
Console::Write(L"Enter Hourly Salary: ");
double emplSalary = double::Parse(Console::ReadLine());
// The minimum salary in this company is 7.50
if( emplSalary < 7.50 )
emplSalary = 7.50;
bwEmployee->Write(emplNumber);
bwEmployee->Write(emplFName);
bwEmployee->Write(emplLName);
bwEmployee->Write(emplSalary);
}
finally
{
bwEmployee->Close();
fsEmployee->Close();
}
}
Console::WriteLine();
}
void CreatePayroll()
{
FileStream ^ fsPayroll = nullptr;
BinaryReader ^ brPayroll = nullptr;
DateTime dteStartDate;
CPayrollInformation ^ payroll = gcnew CPayrollInformation();
double monday1 = 0.00, tuesday1 = 0.00,
wednesday1 = 0.00, thursday1 = 0.00,
friday1 = 0.00, monday2 = 0.00,
tuesday2 = 0.00, wednesday2 = 0.00,
thursday2 = 0.00, friday2 = 0.00;
double totalHoursWeek1 = 0.00,
totalHoursWeek2 = 0.00;
double regHours1 = 0.00, regHours2 = 0.00,
ovtHours1 = 0.00, ovtHours2 = 0.00;
double regAmount1 = 0.00, regAmount2 = 0.00,
ovtAmount1 = 0.00, ovtAmount2 = 0.00;
double regularHours = 0.00, overtimeHours = 0.00;
double regularAmount = 0.00,
overtimeAmount = 0.00,
totalEarnings = 0.00;
Console::Write(L"Enter Employee Number: ");
String ^emplNumber = Console::ReadLine();
String ^ strEmployeePath = L"C:\\Georgetown "
L"Cleaning Services\\Employees\\"
+ emplNumber + ".gce";
if( !File::Exists(strEmployeePath) )
{
Console::WriteLine(L"There is no employee with "
L"that number in our records");
return;
}
// If an employee with that number was found,
// continue with the payroll
else
{
try {
fsPayroll = gcnew FileStream(strEmployeePath,
FileMode::Open,
FileAccess::Read);
brPayroll = gcnew BinaryReader(fsPayroll);
payroll->EmployeeNumber = brPayroll->ReadString();
payroll->FirstName = brPayroll->ReadString();
payroll->LastName = brPayroll->ReadString();
payroll->HourlySalary = brPayroll->ReadDouble();
Console::WriteLine(L"\n------------------------"
L"------------------------");
Console::WriteLine(L"Employee #: {0}",
payroll->EmployeeNumber);
Console::WriteLine(L"Full Name: {0}, {1}",
payroll->LastName,
payroll->FirstName);
Console::WriteLine(L"Hourly Salary: {0:C}",
payroll->HourlySalary);
Console::WriteLine(L"-------------------------"
L"-----------------------\n");
}
finally
{
brPayroll->Close();
fsPayroll->Close();
}
try {
do {
Console::Write(L"Enter Payroll Start "
L"Date (mm/dd/yyyy): ");
dteStartDate = DateTime::Parse(Console::ReadLine());
if( dteStartDate.DayOfWeek != DayOfWeek::Sunday )
{
Console::WriteLine(L"Invalid Date Entry");
Console::WriteLine(L"Payrolls start "
L"on a Sunday");
}
} while (dteStartDate.DayOfWeek !=
DayOfWeek::Sunday);
payroll->StartPeriod = dteStartDate;
}
catch(FormatException ^)
{
Console::WriteLine(L"Invalid Date Entry");
}
}
// Retrieve the value of each day worked
Console::WriteLine(L"\nEnter the time worked "
L"for each day (0.00)");
Console::WriteLine(L"=-= Week 1 =-=");
try {
Console::Write(L"{0}: ",
payroll->StartPeriod.AddDays(1).ToString(L"D"));
monday1 = double::Parse(Console::ReadLine());
}
catch(FormatException ^)
{
Console::WriteLine(L"You typed an invalid value");
}
try {
Console::Write(L"{0}: ",
payroll->StartPeriod.AddDays(2).ToString(L"D"));
tuesday1 = double::Parse(Console::ReadLine());
}
catch(FormatException ^)
{
Console::WriteLine(L"You typed an invalid value");
}
try {
Console::Write(L"{0}: ",
payroll->StartPeriod.AddDays(3).ToString(L"D"));
wednesday1 = double::Parse(Console::ReadLine());
}
catch(FormatException ^)
{
Console::WriteLine(L"You typed an invalid value");
}
try {
Console::Write(L"{0}: ",
payroll->StartPeriod.AddDays(4).ToString(L"D"));
thursday1 = double::Parse(Console::ReadLine());
}
catch(FormatException ^)
{
Console::WriteLine(L"You typed an invalid value");
}
try {
Console::Write(L"{0}: ",
payroll->StartPeriod.AddDays(5).ToString(L"D"));
friday1 = double::Parse(Console::ReadLine());
}
catch(FormatException ^)
{
Console::WriteLine(L"You typed an invalid value");
}
Console::WriteLine(L"=-= Week 2 =-=");
try {
Console::Write(L"{0}: ",
payroll->StartPeriod.AddDays(8).ToString(L"D"));
monday2 = double::Parse(Console::ReadLine());
}
catch(FormatException ^)
{
Console::WriteLine(L"You typed an invalid value");
}
try {
Console::Write(L"{0}: ",
payroll->StartPeriod.AddDays(9).ToString(L"D"));
tuesday2 = double::Parse(Console::ReadLine());
}
catch(FormatException ^)
{
Console::WriteLine(L"You typed an invalid value");
}
try {
Console::Write(L"{0}: ",
payroll->StartPeriod.AddDays(10).ToString(L"D"));
wednesday2 = double::Parse(Console::ReadLine());
}
catch(FormatException ^)
{
Console::WriteLine(L"You typed an invalid value");
}
try {
Console::Write(L"{0}: ",
payroll->StartPeriod.AddDays(11).ToString(L"D"));
thursday2 = double::Parse(Console::ReadLine());
}
catch(FormatException ^)
{
Console::WriteLine(L"You typed an invalid value");
}
try {
Console::Write(L"{0}: ",
payroll->StartPeriod.AddDays(12).ToString(L"D"));
friday2 = double::Parse(Console::ReadLine());
}
catch(FormatException ^)
{
Console::WriteLine(L"You typed an invalid value");
}
// Calculate the total number of hours for each week
totalHoursWeek1 = monday1 + tuesday1 + wednesday1 +
thursday1 + friday1;
totalHoursWeek2 = monday2 + tuesday2 + wednesday2 +
thursday2 + friday2;
// The overtime is paid time and half
double ovtSalary = payroll->HourlySalary * 1.5;
// If the employee worked under 40 hours,
// there is no overtime
if( totalHoursWeek1 < 40 )
{
regHours1 = totalHoursWeek1;
regAmount1 = payroll->HourlySalary * regHours1;
ovtHours1 = 0.00;
ovtAmount1 = 0.00;
} // If the employee worked over 40 hours,
// calculate the overtime
else if( totalHoursWeek1 >= 40 )
{
regHours1 = 40;
regAmount1 = payroll->HourlySalary * 40;
ovtHours1 = totalHoursWeek1 - 40;
ovtAmount1 = ovtHours1 * ovtSalary;
}
if( totalHoursWeek2 < 40 )
{
regHours2 = totalHoursWeek2;
regAmount2 = payroll->HourlySalary * regHours2;
ovtHours2 = 0.00;
ovtAmount2 = 0.00;
}
else if( totalHoursWeek2 >= 40 )
{
regHours2 = 40;
regAmount2 = payroll->HourlySalary * 40;
ovtHours2 = totalHoursWeek2 - 40;
ovtAmount2 = ovtHours2 * ovtSalary;
}
regularHours = regHours1 + regHours2;
overtimeHours = ovtHours1 + ovtHours2;
regularAmount = regAmount1 + regAmount2;
overtimeAmount = ovtAmount1 + ovtAmount2;
totalEarnings = regularAmount + overtimeAmount;
payroll->Week1Monday = monday1;
payroll->Week1Tuesday = tuesday1;
payroll->Week1Wednesday = wednesday1;
payroll->Week1Thursday = thursday1;
payroll->Week1Friday = friday1;
payroll->Week2Monday = monday2;
payroll->Week2Tuesday = tuesday2;
payroll->Week2Wednesday = wednesday2;
payroll->Week2Thursday = thursday2;
payroll->Week2Friday = friday2;
payroll->RegularHours = regularHours;
payroll->OvertimeHours = overtimeHours;
payroll->RegularAmount = regularAmount;
payroll->OvertimeAmount = overtimeAmount;
payroll->TotalEarnings = totalEarnings;
ShowPayroll(payroll);
Console::Write(L"Do you want to save "
L"the payroll (y/n): ");
String ^ strAnswer = Console::ReadLine();
if( strAnswer->ToUpper() == L"Y")
SavePayroll(payroll);
}
void SavePayroll(CPayrollInformation ^ pay)
{
// We will need this value to create the
// name of the payroll file
String ^ strMonth = L"0", ^strDay = L"0", ^strYear = L"0";
// We want the month and day to include 0 if necessary
strMonth = pay->StartPeriod.Month.ToString();
if( pay->StartPeriod.Month < 10 )
strMonth = L"0" + pay->StartPeriod.Month.ToString();
strDay = pay->StartPeriod.Day.ToString();
if( pay->StartPeriod.Day < 10 )
strDay = L"0" + pay->StartPeriod.Day.ToString();
strYear = pay->StartPeriod.Year.ToString();
String ^ strPayrollFilename = L"C:\\Georgetown "
L"Cleaning Services\\Payrolls\\"
+ pay->LastName[0] +
pay->FirstName[0] +
strMonth + strDay +
strYear + ".epr";
try {
// If there is not yet a directory for the
// payrolls, then create it
Directory::CreateDirectory(L"C:\\Georgetown Cleaning "
L"Services\\Payrolls");
}
catch(DirectoryNotFoundException ^)
{
Console::WriteLine(L"The employee payroll file "
L"could not be created");
}
if( File::Exists(strPayrollFilename) )
{
Console::WriteLine(L"The employee's payroll "
L"for that period exists already");
}
FileStream ^ fsEmployeePayroll =
gcnew FileStream(strPayrollFilename,
FileMode::Create);
BinaryFormatter ^ bfEmployeePayroll =
gcnew BinaryFormatter();
bfEmployeePayroll->Serialize(fsEmployeePayroll, pay);
fsEmployeePayroll->Close();
}
void ShowPayroll(CPayrollInformation ^ payed)
{
Console::WriteLine(L"\n============================="
L"===================");
Console::WriteLine(L"=$= Payroll summary =$=");
Console::WriteLine(L"-------------------------------"
L"-----------------");
Console::WriteLine(L"Employee #: {0}",
payed->EmployeeNumber);
Console::WriteLine(L"Full Name: {0}, {1}",
payed->FirstName, payed->LastName);
Console::WriteLine(L"Hourly Salary: {0:C}",
payed->HourlySalary);
Console::WriteLine(L"Start Period: {0:D}",
payed->StartPeriod);
Console::WriteLine(L"End Period: {0:D}",
payed->EndPeriod);
Console::WriteLine(L"--------------------------------"
L"----------------");
Console::WriteLine(L" Monday Tuesday Wednesday "
L"Thursday Friday");
Console::WriteLine(L"Week 1: {0:F} {1:F} "
L"{2:F} {3:F} {4:F}",
payed->Week1Monday, payed->Week1Tuesday,
payed->Week1Wednesday, payed->Week1Thursday,
payed->Week1Friday);
Console::WriteLine(L"Week 2: {0:F} {1:F} "
L"{2:F} {3:F} {4:F}",
payed->Week2Monday, payed->Week2Tuesday,
payed->Week2Wednesday, payed->Week2Thursday,
payed->Week2Friday);
Console::WriteLine(L"-------------------------------"
L"-----------------");
Console::WriteLine(L"Monetary Summary");
Console::WriteLine(L" Hours Amount");
Console::WriteLine(L"Regular: {0,6} {1,6}",
payed->RegularHours.ToString(L"F"),
payed->RegularAmount.ToString(L"F"));
Console::WriteLine(L"Overtime: {0,6} {1,6}",
payed->OvertimeHours.ToString(L"F"),
payed->OvertimeAmount.ToString(L"F"));
Console::WriteLine(L"-------------------------------"
L"-----------------");
Console::WriteLine(L"Net Pay: {0:F}",
payed->TotalEarnings);
Console::WriteLine(L"==============================="
L"=================\n");
}
void ViewPayroll()
{
}
int main()
{
wchar_t answer = L'0';
Console::WriteLine(L"========================"
L"========================");
Console::WriteLine(L"Georgetown Cleaning Services");
Console::WriteLine(L"========================"
L"========================");
do {
try {
Console::WriteLine(L"\nWhat do you want to do?");
Console::WriteLine(L"0. Quit");
Console::WriteLine(L"1. Hire a new employee");
Console::WriteLine(L"2. Process a payroll");
Console::WriteLine(L"3. View an employee's payroll");
Console::Write(L"Your Choice: ");
answer = wchar_t::Parse(Console::ReadLine());
Console::WriteLine();
}
catch(FormatException ^)
{
Console::WriteLine(L"Invalid Answer!");
}
switch(answer)
{
case L'1':
HireEmployee();
break;
case L'2':
CreatePayroll();
break;
case L'3':
ViewPayroll();
break;
default:
break;
}
} while( (answer == L'1') ||
(answer == L'2') ||
(answer == L'3') );
Console::WriteLine();
return 0;
}
Execute the application and test it. Here is an example:
================================================
Georgetown Cleaning Services
================================================
What do you want to do?
0. Quit
1. Hire a new employee
2. Process a payroll
3. View an employee's payroll
Your Choice: 2
Enter Employee Number: 29-368
------------------------------------------------
Employee #: 29-368
Full Name: Monay, Gertrude
Hourly Salary: $10.85
------------------------------------------------
Enter Payroll Start Date (mm/dd/yyyy): 11/12/05
Invalid Date Entry
Payrolls start on a Sunday
Enter Payroll Start Date (mm/dd/yyyy): 11/12/06
Enter the time worked for each day (0.00)
=-= Week 1 =-=
Monday, November 13, 2006: 8.00
Tuesday, November 14, 2006: 8.50
Wednesday, November 15, 2006: 9.50
Thursday, November 16, 2006: 8
Friday, November 17, 2006: 8.50
=-= Week 2 =-=
Monday, November 20, 2006: 6.50
Tuesday, November 21, 2006: 7.00
Wednesday, November 22, 2006: 8
Thursday, November 23, 2006: 6.00
Friday, November 24, 2006: 7.00
================================================
=$= Payroll summary =$=
------------------------------------------------
Employee #: 29-368
Full Name: Monay, Gertrude
Hourly Salary: $10.85
Start Period: Sunday, November 12, 2006
End Period: Saturday, November 25, 2006
------------------------------------------------
Monday Tuesday Wednesday Thursday Friday
Week 1: 8.00 8.50 9.50 8.00 8.50
Week 2: 6.50 7.00 8.00 6.00 7.00
------------------------------------------------
Monetary Summary
Hours Amount
Regular: 74.50 808.33
Overtime: 2.50 40.69
------------------------------------------------
Net Pay: 849.01
================================================
Do you want to save the payroll (y/n): Y
What do you want to do?
0. Quit
1. Hire a new employee
2. Process a payroll
3. View an employee's payroll
Your Choice: 0
Press any key to continue . . .
Close the DOS window
Execute the application again and process another payroll. Here is an example:
================================================
Georgetown Cleaning Services
================================================
What do you want to do?
0. Quit
1. Hire a new employee
2. Process a payroll
3. View an employee's payroll
Your Choice: 2
Enter Employee Number: 86-025
There is no employee with that number in our records
What do you want to do?
0. Quit
1. Hire a new employee
2. Process a payroll
3. View an employee's payroll
Your Choice: 2
Enter Employee Number: 86-225
------------------------------------------------
Employee #: 86-225
Full Name: Harang, Anne
Hourly Salary: $16.75
------------------------------------------------
Enter Payroll Start Date (mm/dd/yyyy): 11/26/2006
Enter the time worked for each day (0.00)
=-= Week 1 =-=
Monday, November 27, 2006: 8
Tuesday, November 28, 2006: 6.5
Wednesday, November 29, 2006: 8.5
Thursday, November 30, 2006: 8
Friday, December 01, 2006: 8
=-= Week 2 =-=
Monday, December 04, 2006: 9
Tuesday, December 05, 2006: 8.5
Wednesday, December 06, 2006: 8
Thursday, December 07, 2006: 9.5
Friday, December 08, 2006: 8.00
================================================
=$= Payroll summary =$=
------------------------------------------------
Employee #: 86-225
Full Name: Anne, Harang
Hourly Salary: $16.75
Start Period: Sunday, November 26, 2006
End Period: Saturday, December 09, 2006
------------------------------------------------
Monday Tuesday Wednesday Thursday Friday
Week 1: 8.00 6.50 8.50 8.00 8.00
Week 2: 9.00 8.50 8.00 9.50 8.00
------------------------------------------------
Monetary Summary
Hours Amount
Regular: 79.00 1323.25
Overtime: 3.00 75.38
------------------------------------------------
Net Pay: 1398.63
================================================
Do you want to save the payroll (y/n):
Close the DOS window
De-Serialization |
|
As serialization is the process of storing an object to a medium, the opposite, serialization is used to retrieve an object from a stream. To support this, the BinaryFormatter class is equipped with the Deserialize() method. Like Serialize(), the Deserialize() method is overloaded with two versions. One of them uses the following syntax:
public:
Object ^ Deserialize(Stream ^ serializationStream) sealed;
This method takes as argument a Stream-based object, such as a FileStream variable, that indicates where the file is located The Deserialize() method. The Deserialize() method returns an Object object. As a goal, you want the Deserialize() method to produce the type of object that was saved so you can retrieve the values that the returned object holds. Because the method returns an Object value, you must cast the returned value to the type of your class.
Once the Deserialize() method has returned the desired object, you can access its values. Here is an example:
using namespace System;
using namespace System::IO;
using namespace System::Runtime::Serialization::Formatters::Binary;
[Serializable]
public ref class CCar
{
public:
String ^Make;
String ^Model;
int Year;
int Color;
};
int main()
{
FileStream ^ stmCar = gcnew FileStream(L"LexusLS.car",
FileMode::Open);
BinaryFormatter ^ bfmCar = gcnew BinaryFormatter();
CCar ^ vehicle = dynamic_cast<CCar ^>(bfmCar->Deserialize(stmCar));
Console::WriteLine(L"Make: {0}", vehicle->Make);
Console::WriteLine(L"Model: {0}", vehicle->Model);
Console::WriteLine(L"Year: {0}", vehicle->Year);
Console::Write(L"Color: ");
int clr = vehicle->Color;
switch(clr)
{
case 1:
Console::WriteLine(L"Black");
break;
case 2:
Console::WriteLine(L"Gray");
break;
case 3:
Console::WriteLine(L"White");
break;
case 4:
Console::WriteLine(L"Red");
break;
case 5:
Console::WriteLine(L"Blue");
break;
}
stmCar->Close();
return 0;
}
This would produce:
Make: Lexus
Model: LS
Year: 2007
Color: Red
Press any key to continue . . .
Practical Learning: De-Serializing an Object |
|
In the Exercise.cpp file, implement the ViewPayroll() function as follows:
void ViewPayroll()
{
String ^ strEmplNumber, ^strFName, ^strLName;
String ^ strMonth, ^strDay, ^strYear;
// Ask the clerk to enter an employee number
// using the format 00-000
Console::Write(L"Enter Employee Number (00-000): ");
strEmplNumber = Console::ReadLine();
String ^ strFilename = L"C:\\Georgetown Cleaning "
L"Services\\Employees\\"
+ strEmplNumber + ".gce";
if( !File::Exists(strFilename) )
{
Console::Write(L"There is no employee "
L"with that number.");
}
else
{
FileStream ^ fsEmployee = nullptr;
BinaryReader ^ brEmployee = nullptr;
try {
// We need to formally open the file
// because we need the employees initials
fsEmployee = gcnew FileStream(strFilename,
FileMode::Open,
FileAccess::Read);
brEmployee = gcnew BinaryReader(fsEmployee);
// Read the file, mainly to get the
// employee's name
strEmplNumber = brEmployee->ReadString();
strFName = brEmployee->ReadString();
strLName = brEmployee->ReadString();
}
finally
{
brEmployee->Close();
fsEmployee->Close();
}
Console::Write(L"Enter the start date of the "
L"payroll you want to see (mm/dd/yyyy): ");
DateTime dteStartDate =
DateTime::Parse(Console::ReadLine());
// We want the month and day to include 0 if necessary
strMonth = dteStartDate.Month.ToString();
if( dteStartDate.Month < 10 )
strMonth = L"0" + dteStartDate.Month.ToString();
strDay = dteStartDate.Day.ToString();
if( dteStartDate.Day < 10 )
strDay = L"0" + dteStartDate.Day.ToString();
strYear = dteStartDate.Year.ToString();
strFilename = L"C:\\Georgetown Cleaning "
L"Services\\Payrolls\\"
+ strLName[0] +
strFName[0] + strMonth +
strDay + strYear + ".epr";
if( !File::Exists(strFilename) )
{
Console::Write(L"{0}, {1} doesn't have a "
L"payroll in that time frame",
strLName, strFName);
}
else
{
// Open the payroll and display it
FileStream ^ fsPayroll =
gcnew FileStream(strFilename,
FileMode::Open);
BinaryFormatter ^ bfPayroll =
gcnew BinaryFormatter();
CPayrollInformation ^ pay =
dynamic_cast<CPayrollInformation ^>
(bfPayroll->Deserialize(fsPayroll));
ShowPayroll(pay);
}
}
}
Execute the application and test it. Here is an example:
================================================
Georgetown Cleaning Services
================================================
What do you want to do?
0. Quit
1. Hire a new employee
2. Process a payroll
3. View an employee's payroll
Your Choice: 3
Enter Employee Number (00-000): 29-368
Enter the start date of the payroll you want to see (mm/dd/yyyy): 11/12/06
================================================
=$= Payroll summary =$=
------------------------------------------------
Employee #: 29-368
Full Name: Gertrude, Monay
Hourly Salary: $10.85
Start Period: Sunday, November 12, 2006
End Period: Saturday, November 25, 2006
------------------------------------------------
Monday Tuesday Wednesday Thursday Friday
Week 1: 8.00 8.50 9.50 8.00 8.50
Week 2: 6.50 7.00 8.00 6.00 7.00
------------------------------------------------
Monetary Summary
Hours Amount
Regular: 74.50 808.33
Overtime: 2.50 40.69
------------------------------------------------
Net Pay: 849.01
================================================
What do you want to do?
0. Quit
1. Hire a new employee
2. Process a payroll
3. View an employee's payroll
Your Choice: 0
Press any key to continue . . .
Close the DOS window
SOAP Serialization |
|
Serialization |
|
The .NET Framework supports another technique of serialization referred to as SOAP (which stands for Simple Object Access Protocol). This technique a little more related to XML but, although we haven't studied XML, you don't need to know anything about it to use SOAP serialization.
To serialize an object using SOAP, you follow the same steps we reviewed for the binary serialization with one addition that you must add a certain reference.
When creating the class whose objects would be serialized, mark it with the [Serializable] attribute. Here is an example:
[Serializable]
public ref class CCar
{
public:
String ^Make;
String ^Model;
int Year;
int Color;
}
To support SOAP serialization, the .NET Framework provides the SoapFormatter class. This class is defined in the System::Runtime::Serialization::Formatters::Soap namespace that is part of the System::Runtime::Serialization::Formatters::Soap.dll assembly. In order to use The SoapFormatter class, you must reference this assembly. You can do this by adding it to your list of references:
After these two steps, you can create an object and initialize it as you see fit. Before saving it, as always, create a Stream-based object that would indicate the name (and location) of the file and the type of action to perform. Then, declare a SoapFormatter variable using its default constructor. To actually save the object, call the Serialize() method of this class. This method uses the same syntax as that of the BinaryFormatter class: it takes two arguments. The first is a Stream-based object. The second is the object that needs to be serialized.
Here is an example:
using namespace System; using namespace System::IO; using namespace System::Runtime::Serialization::Formatters::Soap;
[Serializable] public ref class CCar { public: String ^ Make; String ^ Model; int Year; int Color; };
int main() { CCar ^ vehicle = gcnew CCar;
vehicle->Make = L"Volvo"; vehicle->Model = L"S40"; vehicle->Year = 2006; vehicle->Color = 3;
FileStream ^ stmCar = gcnew FileStream(L"VolvoS40.car", FileMode::Create); SoapFormatter ^ sopCar = gcnew SoapFormatter();
sopCar->Serialize(stmCar, vehicle); return 0; } |
|
De-Serialization |
|
De-serialization in soap is performed exactly as done for the binary de-serialization. To support it, the SoapFormatter class is equipped with the Deserialize() method. This method uses the same syntax as its equivalent of the BinaryFormatter class. The approach to use it is also the same.
Here is an example:
using namespace System;
using namespace System::IO;
using namespace System::Runtime::Serialization::Formatters::Soap;
[Serializable]
public ref class CCar
{
public:
String ^ Make;
String ^ Model;
int Year;
int Color;
};
int main()
{
FileStream ^ stmCar =
gcnew FileStream(L"VolvoS40.car",
FileMode::Open);
SoapFormatter ^ sopCar = gcnew SoapFormatter();
CCar ^ vehicle = dynamic_cast<CCar ^>(sopCar->Deserialize(stmCar));
Console::WriteLine(L"Car Information");
Console::WriteLine(L"Make: {0}", vehicle->Make );
Console::WriteLine(L"Model: {0}", vehicle->Model);
Console::WriteLine(L"Year: {0}", vehicle->Year);
Console::Write(L"Color: ");
switch(vehicle->Color)
{
case 1:
Console::WriteLine(L"Black");
break;
case 2:
Console::WriteLine(L"Gray");
break;
case 3:
Console::WriteLine(L"White");
break;
case 4:
Console::WriteLine(L"Red");
break;
case 5:
Console::WriteLine(L"Blue");
break;
}
return 0;
}
This would produce:
Car Information
Make: Volvo
Model: S40
Year: 2006
Color: White
Press any key to continue . . .
Details on Serialization |
|
Partial Serialization |
|
In the examples we have used so far, we were saving the whole object. You can make it possible to save only some parts of the class. When creating a class, you can specify what fields would be serialized and which ones would not be. To specify that a member cannot be saved, you can mark it with the [NonSerialized] attribute. Here is an example:
[Serializable]
public ref class CCar
{
public:
String ^Make;
String ^Model;
// Because the value of a car can change,
// there is no reason to save it
[NonSerialized]
public:
double Value;
int Year;
int Color;
}
After creating the class, you can declare a variable of it and serialize it, using either the binary or the SOAP approach. Here is an example:
using namespace System;
using namespace System::IO;
using namespace System::Runtime::Serialization::Formatters::Binary;
[Serializable]
public ref class CCar
{
public:
String ^Make;
String ^Model;
// Because the value of a car can change,
// there is no reason to save it
[NonSerialized]
public:
double Value;
int Year;
int Color;
}
int main()
{
CCar vehicle = gcnew CCar;
vehicle->Make = L"Lexus";
vehicle->Model = L"LS";
vehicle->Year = 2007;
vehicle->Color = 4;
vehicle->Value = 28640M;
FileStream ^ stmCar = gcnew FileStream(L"LexusLS.car",
FileMode::Create);
BinaryFormatter ^ bfmCar = gcnew BinaryFormatter;
bfmCar->Serialize(stmCar, vehicle);
return 0;
}
}
You can then retrieve the object and its values, using any of the techniques we learned earlier. Here is an example:
using namespace System;
using namespace System::IO;
using namespace System::Runtime::Serialization::Formatters::Binary;
[Serializable]
public ref class CCar
{
public:
String ^Make;
String ^Model;
// Because the value of a car can change,
// there is no reason to save it
[NonSerialized]
public:
double Value;
int Year;
int Color;
}
int main()
{
FileStream ^ stmCar = gcnew FileStream(L"LexusLS.car",
FileMode::Open);
BinaryFormatter bfmCar = new BinaryFormatter();
CCar ^ vehicle = dynamic_cast<CCar ^>(bfmCar->Deserialize(stmCar));
Console::WriteLine(L"Car Information");
Console::WriteLine(L"Make: {0}", vehicle->Make);
Console::WriteLine(L"Model: {0}", vehicle->Model);
Console::WriteLine(L"Year: {0}", vehicle->Year);
Console::Write(L"Color: ");
switch (vehicle->Color)
{
case 1:
Console::WriteLine(L"Black");
break;
case 2:
Console::WriteLine(L"Gray");
break;
case 3:
Console::WriteLine(L"White");
break;
case 4:
Console::WriteLine(L"Red");
break;
case 5:
Console::WriteLine(L"Blue");
break;
}
Console::WriteLine(L"Value: {0}\n", vehicle->Value);
return 0;
}
This would produce:
Car Information
Make: Lexus
Model: LS
Year: 2007
Color: Red
Value: 0
Press any key to continue . . .
Notice that the value of the Value field was not saved: it holds the default value of its data type. This indicates that, you can assign a value a [NonSerialized] field and save the object. The value of that field would not be saved but the compiler would not throw an exception.
Implementing a Custom Serialized Class |
|
To support serialization, the .NET Framework provides the ISerializable interface. You can create a class that implements this interface to customize the serialization process. Even if you plan to use this interface, the class you create must be marked with the [Serializable] attribute.
.NET Built-In Serialized Classes |
|
The .NET Framework is filled with many classes ready for serialization. To know that a class is ready for serialization, when viewing its documentation either in the MSDN web site or in the help documentation, check that it is marked with the [SerializableAttribute]. Here is an example of such as class:
Some of these classes provide the properties and methods to create an object and directly save it. For some other classes, you must first create a class, mark it with the [Serializable] attribute, build an object of it, and then pass it to the .NET class.
