You are on page 1of 542

Microsoft Visual C++/CLI
Step by Step

Julian Templeman

Pub shed w th the author zat on of M crosoft Corporat on by
O’Re y Med a, Inc
1005 Gravenste n H ghway North
Sebastopo , Ca forn a 95472
Copyr ght © 2013 by Ju an Temp eman
A r ghts reserved No part of the contents of th s book may be reproduced or transm tted n any form or by any
means w thout the wr tten perm ss on of the pub sher
ISBN 978-0-7356-7517-9
1 2 3 4 5 6 7 8 9 LSI 8 7 6 5 4 3
Pr nted and bound n the Un ted States of Amer ca
M crosoft Press books are ava ab e through bookse ers and d str butors wor dw de If you need support re ated
to th s book, ema M crosoft Press Book Support at msp nput@m crosoft com P ease te us what you th nk of
th s book at http://www.microsoft.com/learning/booksurvey
M crosoft and the trademarks sted at http://www.microsoft.com/about/legal/en/us/IntellectualProperty/
Trademarks/EN-US.aspx are trademarks of the M crosoft group of compan es A other marks are property of
the r respect ve owners
The examp e compan es, organ zat ons, products, doma n names, ema addresses, ogos, peop e, p aces, and
events dep cted here n are fict t ous No assoc at on w th any rea company, organ zat on, product, doma n name,
ema address, ogo, person, p ace, or event s ntended or shou d be nferred
Th s book expresses the author’s v ews and op n ons The nformat on conta ned n th s book s prov ded w thout
any express, statutory, or mp ed warrant es Ne ther the authors, O’Re y Med a, Inc , M crosoft Corporat on,
nor ts rese ers, or d str butors w be he d ab e for any damages caused or a eged to be caused e ther d rect y
or nd rect y by th s book
Acquisitions and Developmental Editor: Russe Jones
Production Editor: Kara Ebrah m
Technical Reviewer: Luca Regn co
Copyeditor: Octa Pub sh ng, Inc
Indexer: BIM Index ng and Proofread ng Serv ces
Cover Design: Tw st Creat ve • Seatt e
Cover Composition: E e Vo ckhausen
Illustrator: Rebecca Demarest

I would like to dedicate this book to my wife, Jane, without
whose steadfast love and support none of this would be possible.
—Jul an Templeman

Contents at a Glance
Introduction xxi
Part I

GETTING STARTED WITH C++ .NET

Chapter 1

Hello C++!

Chapter 2

Introducing object-oriented programming

13

Chapter 3

Variables and operators

23

Chapter 4

Using functions

37

Chapter 5

Decision and loop statements

57

Chapter 6

More about classes and objects

77

Chapter 7

Controlling object lifetimes

Chapter 8

Inheritance 121

Part II

MICROSOFT .NET PROGRAMMING BASICS

Chapter 9

Value types

143

Chapter 10

Operator overloading

159

Chapter 11

Exception handling

175

Chapter 12

Arrays and collections

197

Chapter 13

Properties 229

Chapter 14

Delegates and events

245

Chapter 15

The .NET Framework class library

263

Part III

USING THE .NET FRAMEWORK

Chapter 16

Working with files

281

Chapter 17

Reading and writing XML

305

Chapter 18

Using ADO.NET

333

Chapter 19

Writing a service by using Windows
Communication Foundation

351

Chapter 20

Introducing Windows Store apps

369

Chapter 21

More about Windows Store apps

397

3

103

Part IV

ADVANCED TOPICS

Chapter 22

Working with unmanaged code

437

Chapter 23

Attributes and reflection

453

Chapter 24

Living with COM

475

Index 487

vi

Contents at a Glance

Contents
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxi

Part I

GETTING STARTED WITH C++ .NET

Chapter 1 Hello C++!

3

What s C++/CLI?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3

Your first C++/CLI app cat on. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

4

The main funct on. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

4

C++ keywords and dent fiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

5

Creat ng an executab e app cat on—theory. . . . . . . . . . . . . . . . . . . . . . . . . .

6

Ed t ng the app cat on source fi es. . . . . . . . . . . . . . . . . . . . . . . . . . . . .

6

Comp ng the source fi es . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

6

Runn ng and test ng the app cat on . . . . . . . . . . . . . . . . . . . . . . . . . . .

7

Creat ng an executab e app cat on—pract ce

7

Creat ng a project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

8

Ed t ng the C++ source code. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

9

Bu d ng the executab e . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

9

Execut ng the app cat on. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

11

Conc us on. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

11

Qu ck reference. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

11

Chapter 2 Introducing object-oriented programming

13

What s object-or ented programm ng?. . . . . . . . . . . . . . . . . . . . . . . . . . . . .

13

Features of object-or ented programm ng anguages. . . . . . . . . . . . . . . . .

14

Encapsu at on. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

14

Inher tance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

15

Po ymorph sm. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

15

C asses and objects. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

16

vii

Benefits to the deve opment fe cyc e. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

16

A s mp e examp e. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

17

Qu ck reference. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

22

Chapter 3 Variables and operators

23

What s a var ab e? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

23

The fundamenta data types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

23

Dec ar ng a var ab e. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

25

Var ab e nam ng. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

25

Dec ar ng mu t p e var ab es. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

26

Ass gn ng va ues to var ab es . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

26

Hand es and po nters. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

27

Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

28

Constants. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

28

Typedefs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

29

The NET Framework String c ass. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

29

Operators and express ons. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

30

Ass gnment operators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

30

Ar thmet c operators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

30

Re at ona and og ca operators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

31

B tw se operators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

32

The ternary operator. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

33

Type cast ng . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

33

Operator precedence and assoc at v ty. . . . . . . . . . . . . . . . . . . . . . . .

34

Qu ck reference. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Chapter 4 Using functions
Dec ar ng funct on prototypes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

viii Contents

35

37
38

Dec ar ng a s mp e funct on prototype . . . . . . . . . . . . . . . . . . . . . . . .

38

Dec ar ng parameters n a funct on prototype. . . . . . . . . . . . . . . . . .

39

Dec ar ng the return type n a funct on prototype . . . . . . . . . . . . . .

39

Dec ar ng defau t va ues for funct on parameters. . . . . . . . . . . . . . .

40

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 Defin ng c ass-w de members. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 Defin ng c ass-w de member funct ons. . . . . . . . . . . . . . . . . . . . . . . . 92 Contents ix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 77 78 Dec ar ng a c ass n a header fi e. . . 70 Us ng do-while oops. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 Defin ng constructors. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 Us ng for oops. . . 79 Imp ement ng a c ass n a source fi e. . . . . . . . . . . . . . . . . . . . . . . . 73 Qu ck reference. . . . . . . . . . . . . . . . 68 Us ng while oops. . . . . 90 C ass constructors . . . . . . . . . . . . . . 71 Perform ng uncond t ona jumps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 Creat ng objects . .Defin ng funct on bod es . . . . Chapter 6 More about classes and objects Organ z ng c asses nto header fi es and source fi es. . . . . . . . . 51 Qu ck reference. . . . . . . . . . . . . . . . . . . . . . 87 Defin ng c ass-w de data members. . 62 Perform ng nested tests. . . . . 65 Us ng fa -through n a switch statement. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 Understand ng oca and g oba scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 5 Decision and loop statements Mak ng dec s ons by us ng the if statement. . . . . . . . . . . . . . . . . . . . . . . . . . 64 Mak ng dec s ons by us ng the switch Statement. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 Stepp ng through the app cat on by us ng debugger. . . . . . . . 65 Defin ng s mp e switch statements. . . . . . . . . . . . . . . Perform ng one-way tests . . . . . . . . . . . . . . . . . 83 In t a z ng objects by us ng constructors. . . . . . . . . . . 61 Perform ng mu t way tests. . . . . . 84 Member n t a zat on sts. . . . . . . . . . . . . . . 67 Perform ng oops . . . . 41 Ca ng funct ons. . . . . . . . . . . . . . . . . . . . . . . . . . 55 57 57 57 Perform ng two-way tests . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 Concrete and abstract c asses. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 7 Controlling object lifetimes 100 101 103 The NET approach to object fet mes. . . . . . . . 106 Imp ement ng the destructor and fina zer for a c ass. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 Objects and stack semant cs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 Copy constructors. . . . . . . . . . . . . . . . . . . . . . . . . 122 Inher tance and code reuse. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 Des gn ng an nher tance h erarchy. . . . . . . . . 97 Test ng the app cat on. . . . . 116 Qu ck reference. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 Creat ng der ved c ass objects . . . . . . 105 Destructors. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Inher tance term no ogy. . . . . . . . . . . . . 93 Us ng nstance constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 Us ng c ass-w de constants. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .Us ng constants n c asses. . . . . . . . . 95 Defin ng the LoyaltyScheme C ass. . . . . . . . . . . . . Qu ck reference. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 F na zers . . . 131 . 119 Chapter 8 Inheritance 121 What s nher tance?. . . . . . . . . . . . . . . . . . . . . . . . A word on subst tutab ty . . . . . . . . 94 Defin ng object re at onsh ps. . . . . . 113 Re at ng objects w th stack semant cs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124 Defin ng a der ved c ass. . . . . . . . . . . . . . . . . . . . . . . . . . . 95 Imp ement ng the LoyaltyScheme c ass. . 96 Creat ng and us ng LoyaltyScheme objects. . . . 130 Overr d ng member funct ons . . . . . . . . . . . . . . . . . . . . . . 103 Destruct on and fina zat on. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . x Contents 121 123 123 Defin ng a base c ass . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . 163 Contents xi . . .NET PROGRAMMING BASICS Chapter 9 Value types Reference types and va ue types. . . . . . . . . . . . . . . . . . . . . . . 156 Qu ck reference. 161 Over oad ng operators n managed types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 Enumerat ons. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creat ng and us ng a s mp e struct. . . . Creat ng and us ng an enumerat on. . . Part II 137 Defin ng and us ng nterfaces. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 Over oad ng ar thmet c operators. 144 Propert es of va ue types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 Us ng memory effic ent y. . . . . . . . . . . . . . . . . . . . . . . . . 149 Us ng one structure w th n another . . . . . . . . . . . . . . . . . . . . . . . . 153 153 Us ng enumerat ons n app cat ons. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147 The d fferences between structures and c asses . . . . . . . . . . . . . . . . . . . . . . . 161 Us ng stat c operator over oads. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146 146 Invest gat ng the structure. . . . . . . 160 What can you over oad?. . . . . . 149 Imp ement ng constructors for a structure. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 Copy ng structures. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 Qu ck reference. . . . . . . . . . . . . . . . . . . . . . . . . . . 160 Ru es of over oad ng. . . 139 MICROSOFT . . . 136 Defin ng sea ed c asses. . . . . .Protected access. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156 159 159 What types need over oaded operators? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 143 The need for va ue types . . . . . . . . . . . . . . . . . . Chapter 10 Operator overloading What s operator over oad ng?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 Abstract and sea ed. . . . . . . . . . . . . . . . . . . 145 Structures. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . 180 Us ng the try and catch construct. . . . . . . . . . . . . . . . . . . . . . . . . . . 205 Managed arrays. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .What funct ons can you over oad?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 175 How do except ons work?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166 Imp ement ng og ca operators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178 Throw ng except ons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 11 Exception handling What are except ons?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200 In t a z ng arrays . . . . 203 Gener c types. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180 Custom z ng except on hand ng. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188 The catch(…) b ock. . . . . . . . . . 191 Us ng except ons across anguages. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185 The finally b ock. . . . . . . . 173 Qu ck reference. . . . xii Contents 174 197 197 Pass ng arrays to funct ons. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 Operators and reference types. . 202 Dynam c a ocat on and arrays. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178 Hand ng except ons. . . . . . . . . . . . . . . . . . . . . . . . 202 Mu t d mens ona arrays. . . . . . . . . . . 207 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 Imp ement ng ncrement and decrement. . . . 189 Creat ng your own except on types. . . . . . . . . . . . . . . . . . . . . . 192 Qu ck reference. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172 Gu de nes for prov d ng over oaded operators. . . . . . . . . . . . . . . . . . . . . . . 195 Chapter 12 Arrays and collections Nat ve C++ arrays. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 Except on types . . . . . . . 184 Nest ng and rethrow ng except ons. . . . 182 Us ng the except on h erarchy. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189 Us ng safe cast for dynam c cast ng. . . . . . . . . . . . . . . . . . . . . . . . . . . 183 Us ng except ons w th constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . .mp emented propert es. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . The STL/CLR brary. . . . nher tance. . . . . . . . . Qu ck reference. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .The NET array c ass . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . The two k nds of propert es. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 Bas c operat ons on arrays. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229 230 Imp ement ng sca ar propert es. . . . . . . . . . . . . . . . . 247 Imp ement ng de egates. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245 What s the purpose of de egates? 246 Defin ng de egates. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236 Creat ng Account c ass propert es. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219 The SortedList<K. . . 222 Gener cs and temp ates. . . . . . . . . . . .V> c ass. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239 Add ng accounts to the Bank c ass . . . . . 233 Read-on y and wr te-on y propert es. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232 Auto. . . . . . . . 240 Imp ement ng the Add and Remove methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247 Contents xiii . . . . . . . . . . . . . 213 More advanced array operat ons . 215 Us ng enumerators. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233 Propert es. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218 Other NET co ect on c asses. 241 Qu ck reference. . . . . . . . . . . 224 224 227 Chapter 13 Properties 229 What are propert es?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236 The Bank examp e. . . . . . . . . . . . . and nterfaces. . . . . . . . . . . . . . . . . . . . . . . . . . 231 Errors n propert es . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240 Imp ement ng an ndexed property to retr eve accounts. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 14 Delegates and events 244 245 What are de egates?. . . . . . . 219 The List<T> c ass. . . . . . . . . . . . . . . . . . . . . . . . . . 235 Imp ement ng ndexed propert es. . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265 Assemb es. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270 The System namespace. . . . . 264 The Common Type System. . . . . . . . . . . . . . . . . . . . . . . . . 276 The Web namespaces. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiv Contents 253 Imp ement ng an event source c ass. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274 The Windows namespaces. . . . 262 263 263 The Common Language Runt me. . . . . . . . . . . . . . . . 275 The Xml namespaces. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268 Us ng namespaces n C++ app cat ons. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258 Qu ck reference. . . . . . . . . . . . . . . . 272 The Collections nterfaces. . . . . . . .What are events?. . . . . . . 275 The ServiceModel namespaces . . . . . . . . . . . . 275 The Net namespaces. . . . . . . . . . . . . . . . . . . . . . . . . . . . 273 The Diagnostics namespace. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266 The NET Framework namespaces. . . . 270 The Collections namespaces. . . . 276 The Data namespaces. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266 Metadata. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254 Imp ement ng an event rece ver. . . . . . . . . . . 264 The M crosoft Intermed ate Language. . . . . . . . . . . . . . . . . . . . . . . . . . . 264 The Common Language Spec ficat on. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277 Qu ck reference. Chapter 15 The . . . . . . . . . . . . . . . . . . 265 The NET Framework c ass brary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .NET Framework class library What s the NET Framework?. . . . . . . . . . . . . . . . . 274 The IO namespace. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256 Hook ng t a together. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . 332 333 334 ADO NET data prov ders. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 18 Using ADO. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B nary I/O. . . . . . . . . . . . . . . . . . . 306 Pars ng XML by us ng XmlReader. . . . . . . . . . . . . . . . . . 282 Imp ement ng text I/O by us ng readers and wr ters. . . . . . 322 What s the W3C DOM? . . . . . . . . . . 323 The XmlNode c ass. 335 ADO NET assemb es. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334 ADO NET namespaces. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299 Qu ck reference. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283 The FileStream c ass. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286 Us ng TextReader. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287 Work ng w th fi es and d rector es. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298 The BinaryReader c ass. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283 Us ng TextWriter. . . . . . . . . . . . . . . . . . . .Part III USING THE . . . . . . . . . . . . . 306 The XML process ng c asses. . . . . . . . . . . . . . . . . . 315 Wr t ng XML by us ng XmlTextWriter . . . . . . . . . . . . . . .NET FRAMEWORK Chapter 16 Working with files 281 The System::IO namespace . . . Gett ng nformat on about fi es and d rector es. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318 Us ng XmlDocument. . . . Chapter 17 Reading and writing XML XML and NET . . . . . . . . . . 303 305 305 The NET XML namespaces. . . . . . . . . . . . . . . . . . . . . . . . . . . . .NET What s ADO NET? . . . . . . . . . . . . . . . 336 Contents xv . . . . . . . . . 323 The XmlDocument c ass . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325 Qu ck reference. . . . . . . . . . 290 290 298 The BinaryWriter c ass. . . . . . . . . . . . . . . . . . . 307 Pars ng XML w th va dat on. . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353 Endpo nts. . . . . . . . . . . 354 B nd ng. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361 Add ng metadata to the serv ce. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342 Creat ng a d sconnected app cat on. . . . . . . . . . . . . . . . . . . . . . Chapter 20 Introducing Windows Store apps A (br ef) h story of wr t ng W ndows user nterface app cat ons. . . . . . . . . 355 Contract. . 345 Qu ck reference. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370 . . . . 352 Serv ces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350 Chapter 19 Writing a service by using Windows Communication Foundation 351 What s W ndows Commun cat on Foundat on?. . . . . . . . . . . . . . . . . . . 337 Creat ng and execut ng a command 340 Execut ng a command that mod fies data. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369 M crosoft Foundat on C asses. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356 Message exchange patterns. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344 D sconnected operat on us ng a DataSet. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358 Creat ng a serv ce. . . . . . . . . . . . . . . . . . . . . . . . . . D str buted systems. . . . . . 353 Address . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .Creat ng a connected app cat on. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357 Behav ors. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370 W ndows Forms. . . . . . . . . . . . . . . . 363 Access ng a serv ce by us ng a proxy. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvi Contents 351 368 369 369 The W n32 API . . . . . . . . . . . . . . . . . . . . . . . . . . . 336 Connect ng to a database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352 Connect v ty. . . . . . . . . . . 341 Execut ng quer es and process ng the resu ts. . 365 Qu ck reference. . . . . . . . . . . . . . . . . . . . . . 353 The ABCs of WCF. . . . . . . . . . . . . . . . . . . . . . . . . . 359 Wr t ng a serv ce c ent. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Ma n features of W ndows Store apps. . . . . . . . . . . . . . . . . . . . . 372 Introduc ng W ndows Store apps. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 410 Improv ng the graph cs. . . . . . . . . . . . . . . . . . . . . . . . . . 403 Perform ng ca cu at ons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433 Contents xvii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Wr t ng a W ndows Store app. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 416 Us ng app bars. . . . . . . . . . 393 Qu ck reference. . . . . . . . . . . . . . . . . . . . . . . . . . . . 389 C++/CX and W ndows RT . . . . . . . . . . . . . . . . . . . . . . . . 395 Chapter 21 More about Windows Store apps 397 Bu d ng the bas c ca cu ator. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391 Common namespaces. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .W ndows Presentat on Foundat on. . . . 372 373 374 Creat ng your first W ndows Store app . . . . . . . . 407 Test ng the ca cu ator . . 380 What s XAML?. . . . . . . . . . . . . . . . . . . . . . . . . . . . 381 XAML contro s . . . . . . . . . . . . . . . . . . . . . . . 382 Layout contro s. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 398 Hand ng number nput . . . . . . . 425 Add ng shar ng. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433 Qu ck reference. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 390 C++/CX syntax . . . . . . . . 428 Where next?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375 Exam n ng the project. . . . 384 Event hand ng. . . . . . . . . . . . . . . . . . . . . . . . . . 389 W ndows RT 390 Metadata. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371 Wh ch UI brary to choose?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 412 Hand ng d fferent number bases. . . . . . . . . . . . . . . 379 Introduc ng XAML. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397 Lay ng out the number buttons . . . . . . . . . . . . . . . . . . . . 371 W ndows 8 and W ndows Store. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380 XAML syntax. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 401 Add ng ar thmet c operat ons. . . . . . . . . . . . . . . . .

. . . . 444 The DllImportAttribute c ass. . . . . . . . . . . . . . . 447 Pass ng structures . . 437 The GCHandle type. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 467 The Type c ass. 453 454 457 The Assemb yInfo cpp fi e. 469 Access ng custom attr bute data. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 461 Attr bute c ass propert es. . . . . . . . . . . 440 441 P nn ng po nters. . . 463 Wr t ng a custom attr bute. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xviii Contents 437 472 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441 Box ng and unbox ng . . . 467 Access ng standard attr butes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463 Des gn cr ter a for attr bute c asses. . . . . . . . . . . . . . . . . . 457 Us ng the predefined attr bute c asses. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463 Us ng reflect on to obta n attr bute data. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 443 Unbox ng. . . . . . . . . . . . . . . . . . . . . . . . . 437 M xed c asses . . . . . . . . 458 Defin ng your own attr butes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452 Chapter 23 Attributes and reflection 453 Metadata and attr butes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449 Qu ck reference. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 442 Box ng . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 438 P nn ng and box ng Inter or po nters. . . . . . . . . . . . . .Part IV ADVANCED TOPICS Chapter 22 Working with unmanaged code Managed vs unmanaged code . . . . . . . . . . . . . . . . . . . . . . . . Us ng predefined attr butes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 443 Us ng P/Invoke to ca funct ons n the W n32 API. . . . . . . . . . . . . . Us ng ILDASM. . . . . . 470 Qu ck reference. . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .Chapter 24 Living with COM 475 COM components and the COM Interop. . . . . . . 477 Hand ng COM errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 485 Index 487 Contents xix . 476 How do RCWs work?. . . 480 Late b nd ng to COM objects. . . . . . . . . . . . . . . . . . . 481 Us ng NET components as COM components. . . . . . . . . . . . . . . . . . . . . . . . . . 476 Creat ng and us ng RCWs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483 What must NET types mp ement to be used as COM objects?. . . . 476 Us ng COM components from NET code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483 Qu ck reference. . . .

.

you may w sh to ook at Build Windows 8 Apps with Microsoft Visual C++ Step by Step by Luca Regn co . and you can use t. a ong w th other anguages such as C#. from wr t ng games. pub shed by M crosoft Press xxi . another var ant of C++ ntroduced spec fica y for th s purpose Who should read this book Th s book ex sts to he p programmers earn how to wr te app cat ons us ng C++ on the W ndows p atform It w be usefu to those who want an ntroduct on to wr t ng NET app cat ons us ng C++. W ndows 8 has ntroduced many new features to the W ndows operat ng system.Introduction C ++ s a powerfu . and prov de a comp ete y new way to construct user nterfaces on W ndows C++ s one of the ma n anguages supported for W ndows Store deve opment. to ne-of-bus ness app cat ons Th s book s go ng to ntroduce you to severa of the areas n wh ch C++ s used n W ndows deve opment For over a decade NET has become estab shed as the way to wr te desktop app cat ons for W ndows.eve system software. ndustr a -strength programm ng anguage used n tens of thousands of app cat ons around the wor d. and th s book w g ve you an ntroduct on to these app cat ons and how to deve op them n C++/CX. and t prov des a wea th of techno og es to support deve opers C++/CLI s the var ant of C++ that runs n the NET env ronment. but perhaps the most exc t ng s the debut of W ndows Store app cat ons These graph ca app cat ons are des gned to run on touch screen and mob e dev ces. and th s book w show you how to get started us ng C++ on W ndows Of a the anguages supported by M crosoft. as we as to those who want to see how to wr te W ndows Store app cat ons If you are spec fica y nterested n W ndows Store app cat ons. and Roberto Brunett . Pao o P a ors . C++ g ves you access to the w dest range of techno og es on the W ndows p atform. to create r ch desktop app cat ons More recent y. through ow.

because t concentrates on two M crosoft var ants (C++/CLI and C++/CX) and does not cover top cs such as the CLR or MFC n any deta Organization of this book Th s book s d v ded nto four sect ons ■ ■ ■ ■ xxii  Introduction Part I. “Us ng the NET Framework. “Gett ng Started.” covers the ma n features n the NET Framework brar es used for wr t ng NET app cat ons Th s part nc udes d scuss on of work ng w th fi es. so that you are fam ar w th concepts such as funct ons and arrays It s qu te suffic ent to have exper ence n a procedura anguage such as V sua Bas c. and creat ng graph ca app cat ons Part IV.Assumptions Th s book expects that you have some exper ence of programm ng n a h gh. I recommend start ng w th a book such as Programming: Principles and Practice Using C++ by Bjarne Stroustrup.eve anguage.” ntroduces the ma n parts of the C++ anguage. pub shed by Add son-Wes ey Th s book s a so not su tab e for those who want to earn standard C++ or o dersty e W n32 deve opment.” cont nues by ntroduc ng those parts of C++ that are spec fic to M crosoft’s C++/CLI anguage Part III. or of C++ n part cu ar (a though any know edge of a “cur y bracket” anguage w be usefu ) Who should not read this book Th s book s not su tab e for comp ete beg nners to programm ng For readers who are comp ete y new to programm ng and want to earn C++. gett ng you used to cod ng n C++ and bu d ng app cat ons n V sua Stud o 2012 Part II. “M crosoft NET Programm ng Bas cs. “Advanced Top cs. nc ud ng deta s for work ng w th egacy code .” covers some more advanced mater a . XML and databases. and I do not assume that you have any exper ence of object-or ented programm ng n genera .

presented as numbered steps (1. Fam ar w th OO programm ng but not w th C++ Read Part carefu y. and so on Introduction  xxiii . but you can om t Chapter 2. then the next.NET. F e C ose) means that you shou d se ect the first menu or menu tem. you may w sh to focus on spec fic areas of the book Use the fo ow ng tab e to determ ne how best to proceed through the book If you are Follow these steps New to C++ Read Part carefu y before cont nu ng to the rest of the book. but not W ndows Store app cat ons. Fam ar w th . Read Chapters 20 and 21. “Press A t+Tab” means that you ho d down the A t key wh e you press the Tab key A vert ca bar between two or more menu tems (e g . Most of the book’s chapters nc ude exerc ses that et you try out the concepts you have just earned So ut ons to these exerc ses can be down oaded us ng the compan on code nk from th s book’s web page on ore y com See the “Code samp es” sect on for deta s on how to down oad the compan on code Conventions and features in this book Th s book presents nformat on us ng convent ons des gned to make the nformat on readab e and easy to fo ow ■ ■ ■ ■ ■ Each exerc se cons sts of a ser es of tasks.Finding your best starting point in this book The var ous sect ons of th s book cover a w de range of techno og es assoc ated w th C++ on the W ndows p atform Depend ng on your needs and your ex st ng understand ng of C++. 2. Fam ar w th C++ Rev ew Part . ook ng for the d fferences be tween standard C++ and C++/CL . and so on) st ng each act on you must take to comp ete the exerc se Boxed e ements w th abe s such as “Note” prov de add t ona nformat on or a ternat ve methods for comp et ng a step successfu y Text that you type (apart from code b ocks) appears n bo d A p us s gn (+) between two key names means that you must press those keys at the same t me For examp e.

you w need W ndows 8 ■ V sua Stud o 2012. can be down oaded from the fo ow ng page http://aka. W ndows 8. or W ndows Server 2008 R2 Note that f you want to bu d and run the W ndows Store app cat ons featured n Chapters 20 and 21. you m ght requ re Loca Adm n strator r ghts to nsta or configure V sua Stud o 2012 Code samples Most of the chapters n th s book nc ude exerc ses that et you nteract ve y try out new mater a earned n the ma n text A samp e projects. W ndows Server 2008 w th Serv ce Pack 2.ms/VCCLISbS/files xxiv  Introduction . any ed t on ■ A computer that has a 1 6 GHz or faster processor (2 GHz s recommended) ■ 1 GB (32 B t) or 2 GB (64 B t) RAM ■ 3 5 GB of ava ab e hard d sk space ■ 5400 RPM hard d sk dr ve ■ D rectX 9 capab e v deo card runn ng at 1024 x 768 or h gher-reso ut on d sp ay ■ DVD-ROM dr ve ( f nsta ng V sua Stud o from DVD) ■ Internet connect on to down oad software or chapter examp es Depend ng on your W ndows configurat on. n both the r pre-exerc se and post-exerc se formats.System requirements You w need the fo ow ng hardware and software to comp ete the pract ce exerc ses n th s book ■ One of W ndows 7.

Acknowledgments
Produc ng a book nvo ves a number of peop e, and I’d ke to thank the fo ow ng n
part cu ar
I’d ke to thank a at M crosoft Press and O’Re y for the r he p and support, espec a y Devon Musgrave at M crosoft for nv t ng me to start th s project, and Russe
Jones at O’Re y for prov d ng so much he p w th wr t ng and ed tor a matters, and
espec a y h s gu dance n us ng the (not a ways good-tempered) Word temp ates
The techn ca qua ty of the book has been great y mproved by Luca Regn co , who
as tech rev ewer po nted out numerous errors and om ss ons I espec a y va ue h s nput
on the W ndows Store chapters
Kara Ebrah m at O’Re y, a ong w th D anne Russe and Bob Russe at Octa Pub shng, prov ded exce ent ed tor a support and made sure everyth ng got done on t me
And ast y, I’d ke to thank my fam y, who have put up w th a the extra work nvo ved n wr t ng a book, and are probab y hop ng that th s s ast one for a wh e!

Errata and book support
We’ve made every effort to ensure the accuracy of th s book and ts compan on content Any errors that have been reported s nce th s book was pub shed are sted on our
M crosoft Press s te at ore y com
http://aka.ms/VCCLISbS/errata
If you find an error that s not a ready sted, you can report t to us through the
same page
If you need add t ona support, ema M crosoft Press Book Support at mspinput@
microsoft.com
P ease note that product support for M crosoft software s not offered through the
addresses above

Introduction  xxv

We want to hear from you
At M crosoft Press, your sat sfact on s our top pr or ty, and your feedback our most
va uab e asset P ease te us what you th nk of th s book at
http://www.microsoft.com/learning/booksurvey
The survey s short, and we read every one of your comments and deas Thanks n
advance for your nput!

Stay in touch
Let’s keep the conversat on go ng! We’re on Tw tter http://twitter.com/MicrosoftPress

xxvi  Introduction

PAR T I

Getting started with
C++ .NET
CHAPTER 1

He o C++!

CHAPTER 2

Introduc ng object-or ented programm ng . . . . . .

13

CHAPTER 3

Var ab es and operators . . . . . . . . . . . . . . . . . . . . . . .

23

CHAPTER 4

Us ng funct ons

37

CHAPTER 5

Dec s on and oop statements

57

CHAPTER 6

More about c asses and objects . . . . . . . . . . . . . . . .

77

CHAPTER 7

Contro ng object fet mes . . . . . . . . . . . . . . . . . . .

103

CHAPTER 8

Inher tance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

121

3

1

CHAPTER 1

Hello C++!
After completing this chapter, you will be able to

Recogn ze C++ funct ons

Recogn ze C++ keywords and dent fiers

Create a C++ app cat on

W

e come to the exc t ng wor d of programm ng M crosoft NET w th M crosoft V sua C++ Th s
chapter ntroduces the C++/CLI anguage and shows you how to perform s mp e nput/output (I/O)

What is C++/CLI?
C++/CLI s a vers on of the C++ programm ng anguage des gned to run on the NET Framework
It has been ava ab e s nce M crosoft V sua Stud o 2005 and s the subject of an nternat ona standard You can find deta s of the ECMA standard at http://www.ecma-international.org/publications/
standards/Ecma-372.htm
To ach eve th s, some changes had to be made to standard C++ There are some th ngs that you
can do n standard C++ that are not perm tted n C++/CLI (for examp e, you cannot nher t from
mu t p e base c asses) and there have been some changes to the anguage geared to support NET
features (such as nterfaces and propert es) and to work w th the NET Runt me
Why wou d you choose to use C++/CLI to wr te NET code nstead of another NET anguage such
as C#? Apart from persona preference, there are two very good reasons to choose C++/CLI The first
s for nteroperab ty; C++/CLI makes t s mp e to ncorporate standard C++ code nto NET projects
The second s that we have a NET vers on of the C++ Standard Temp ate L brary (STL), and so peop e
used to cod ng aga nst the STL w find t poss b e to work n the same way n NET
Even f ne ther of these reasons app es to you, C++/CLI s st a perfect y good way to earn about
NET programm ng because t exposes a of the features that you need to wr te NET programs and
exp ore the NET p atform

3

Your first C++/CLI application
It’s t me to get our hands d rty w th a s mp e C++/CLI app cat on Of course, no programm ng book
wou d be comp ete w thout nc ud ng the customary “He o Wor d” app cat on, so et’s start w th that
using namespace System;
int main()
{
Console::WriteLine("Hello, World!");
return 0;
}

Th s short app cat on

ustrates some fundamenta C++/CLI concepts

The first ne (wh ch beg ns w th using) nforms the comp er that you’re us ng the NET System
brary Many d fferent brar es cou d be used n a s ng e project; the using statement spec fies
to the comp er wh ch brary you want to use
The rest of the app cat on s an examp e of a C++ function A b ocks of code n C++ are
ca ed funct ons—there’s no such th ng as a procedure or a subrout ne Each C++ funct on
conta ns the header (the first ne of th s app cat on) and the funct on body (a of the text
between the braces, { and }) The header shows the return type of the funct on ( n th s case
int, short for integer), the name of the funct on (main), and the st of parameters ns de round
brackets Note that you st need to nc ude the round brackets even f you don’t have anyth ng to pass to the funct on
A statements n C++ are term nated w th a sem co on

Of the s x nes of code n the examp e app cat on, on y two conta n C++ statements the Console
ne and the return ne The Console ne outputs characters to the conso e, and the argument to the
funct on cons sts of the str ng that you want to output The return ne ex ts from the funct on— n
th s case, the app cat on, because there s on y one funct on—and returns zero, wh ch s the standard
va ue to return when execut on s successfu

The main function
Why s the on y funct on n the prev ous examp e ca ed main? The s mp e answer s that the code
won’t comp e f t sn’t! However, t m ght be more usefu to exp a n how the anguage works
A norma C++ app cat on conta ns many funct ons (and a so many c asses, as s d scussed n
Chapter 2, “Introduc ng object-or ented programm ng”) How does the comp er know wh ch funct on
shou d be ca ed first? Obv ous y, you can’t a ow the comp er to just random y choose a funct on The
ru e s that the comp er a ways generates code that ooks for a funct on named main If you om t the
main funct on, the comp er reports an error and doesn’t create a fin shed executab e app cat on

4  Microsoft Visual C++/CLI Step by Step

Outs de of these restr ct ons, any dent fier w
ed, such as the fo ow ng

work However, some cho ces are not recommend-

Identifier

Reason it’s not recommended

ma n

Cou d be confused w th the funct on ma n.

NT

Too c ose to the reserved word nt.

B4ugotxtme

Just too crypt c!

dent fier1

Underscores at the beg nn ng of names are a owed, but they are not recommended because
comp ers often use ead ng underscores when creat ng nterna var ab e names, and they are
a so used for var ab es n system code. To avo d potent a nam ng confl cts, you shou d not use
ead ng underscores.

Creating an executable application—theory
Severa stages are requ red to bu d an executab e app cat on; M crosoft V sua Stud o 2012 he ps you
accomp sh th s by automat ng them To exam ne and understand these stages, however, et’s ook at
them br efly You’ see these stages aga n ater n the chapter when we bu d our first app cat on

Editing the application source files
Before you can create an app cat on, you must wr te someth ng V sua Stud o 2012 prov des an
ntegrated C++ ed tor, comp ete w th co or syntax h gh ght ng and M crosoft Inte Sense to show
funct on parameter nformat on and prov de word comp et on

Compiling the source files
The C++/CLI comp er s the too for convert ng text source fi es nto someth ng that can be executed
by a computer processor The comp er takes your source fi es (wh ch usua y have a .cpp extens on)
and bu ds them nto e ther a stand-a one executab e fi e (w th a .exe extens on) or a brary fi e to be
used n other projects (w th a .dll extens on)

Standard C++ and C
If you have ever worked w th standard C++ or C, you m ght be fam ar w th the dea of comp ng to object fi es and then nk ng w th brar es to bu d the fina executab e fi e—wh ch s
common y referred to s mp y as an executab e A though you can comp e to the equ va ent of
an object fi e (ca ed a module n the NET wor d) and then nk those together by us ng a too
ca ed the assembly linker, V sua Stud o takes you stra ght from source to executab e w thout
you see ng the ntermed ate step

6  Microsoft Visual C++/CLI Step by Step

Running and testing the application
After you have successfu y bu t the app cat on, you need to run t and test t
For many deve opment env ronments, runn ng and test ng s often the most d fficu t part of the
app cat on deve opment cyc e However, V sua Stud o 2012 has yet another ace up ts s eeve the
ntegrated debugger The debugger has a r ch set of features w th wh ch you can eas y perform runt me debugg ng, such as sett ng breakpoints and variable watches

Creating an executable application—practice
Go ahead and start V sua Stud o 2012 An nv t ng y b ank w ndow appears on your screen

Th s w ndow s the powerfu V sua Stud o ntegrated deve opment env ronment (IDE) It conta ns
a the too s you’ need to create fu -featured, easy-to-use app cat ons

Note  This book was written by using the Release Candidate (RC) version of Visual Studio
2012. As a result, screen shots and other details might differ from the version you’re using
when you read this.

Chapter 1  He o C++!   7

Creating a project
The first task s to create a new project for the “He o, Wor d” program
1. In V sua Stud o, on the F e menu, po nt to New, and then c ck Project (A ternat ve y, you can

press Ctr +Sh ft+N )

Note  I am using the Professional version of Visual Studio 2012. If you are using other versions, the way in which you create a project might be different. For example, in
the Express version, you will find New Project on the File menu.
The New Project d a og box opens

2. In the nav gat on pane on the eft, under Temp ates, c ck V sua C++, and then c ck CLR In the

center pane, c ck CLR Conso e App cat on and then, toward the bottom of the d a og box, n
the Name box, type HelloWorld

Note  Depending on how Visual Studio has been set up, you might find Visual C++
under the Other Languages node.
3. C ck the Locat on st and se ect a ocat on for your new project or c ck Browse and nav gate

to an appropr ate d rectory
8  Microsoft Visual C++/CLI Step by Step

c ck Bu d So ut on or press F7 Chapter 1  He o C++!   9 . so et’s remove them Th s w g ve you some pract ce n us ng the ed tor as we as mak ng the code eas er to understand The app cat on s not go ng to rece ve any command. so remove everyth ng between the open ng and c os ng parentheses fo ow ng main— n th s examp e. so you can remove that. array<System::String ^> ^args In add t on. as we Building the executable The next step s to bu d the executab e The term build n V sua Stud o 2012 refers to comp ng and nk ng the app cat on V sua Stud o comp es any source fi es that have changed s nce the ast bu d and— f no comp e errors were generated—performs a nk To bu d the executab e.4. C ck OK to create the project The w zard correct y n t a zes a the comp er sett ngs for a conso e project Editing the C++ source code The w zard creates a project for you w th a the fi es needed for a s mp e conso e app cat on It a so opens the ma n source fi e n the ed tor that conta ns just the code we want Not ce that the keywords automat ca y appear n b ue (prov ded that you spe them correct y) There are a few th ngs n the automat ca y generated source code that we don’t need. the “L” before the “Hello World” str ng sn’t necessary e ther (for reasons that I’ exp a n ater). on the Bu d menu.ne arguments when you run t.

0 up-to-date.Note  The shortcut keys might differ depending on the version of Visual Studio you are using. you can open t by se ect ng Output from the V ew menu If any prob ems occur. An Output w ndow opens near the bottom of the V sua Stud o w ndow. 0 skipped w appear n the Output w ndow If th s w ndow s c osed. the Error L st w ndow w conta n a st of errors and warn ngs You can doub e-c ck the error ne n the Error L st w ndow to p ace the cursor at the ne n the source fi e where the comp er encountered the error F x the error (you m ght have m sspe ed a keyword or forgotten a sem co on) and rebu d the project If the Error L st pane s c osed. in the Ultimate edition. get r d of them Warn ngs are there for a reason. show ng the bu d progress If no errors are encountered. the shortcut is F6. the message Build: 1 succeeded. they’re te ng you that your code s not correct 10  Microsoft Visual C++/CLI Step by Step . you can open t by se ect ng Error L st from the V ew menu How should you treat warnings? A ways treat warn ngs as errors— n other words. For example. 0 failed.

Add a fi e to a project. t demonstrates some key C++ deve opment po nts It ntroduces the V sua Stud o 2012 IDE and the ab ty to comp e and nk a app cat on. or press Ctr +Sh ft+N. and t serves as an ntroduct on to the C++/CLI anguage Now. n the Express vers on. C ck F e New Project. C ck Debug Start W thout Debugg ng. or press Ctr +Sh ft+B. C ck Bu d Bu d So ut on. c ck New Project. or press Ctr +N. or press Ctr +F5. C ck F e New F e.Executing the application After you’ve e m nated a errors and you’ve successfu y bu t the project. don’t forget to have some fun Go back and try a few var at ons on the examp e app cat on. Execute a program from w th n V sua Stud o 2012. and take some t me to become fam ar w th the env ronment Quick reference To Do this Create a new project n V sua Stud o 2012. c ck a few menus. w th the message “Press any key to cont nue” at the bottom of the output Th s ne s added by the IDE so that the conso e w ndow doesn’t s mp y d sappear when the app cat on has fin shed runn ng Conclusion A though the examp e n th s chapter sn’t the most exc t ng app cat on ever wr tten. you can fina y execute the app cat on On the Debug menu. there’s no turn ng back Every new C++/CLI and V sua Stud o 2012 feature that you earn about w fire your mag nat on to earn more and be ncreas ng y product ve Software deve opment s an exc t ng wor d F na y. Chapter 1  He o C++!   11 . Bu d a V sua Stud o 2012 project. on the F e menu. c ck Start W thout Debugg ng to run the app cat on You can a so press Ctr +F5 to execute the app cat on You’ see the output of your app cat on.

.

Toyotas and Fords are cars. and so on It s a natura human tra t to try to organ ze these objects. but t m ght figure heav y n the menta mode of car c ass ficat ons used by a Ferrar sa esperson Object-or ented programm ng ets us bu d h erarch es of objects.CHAPTER 2 Introducing object-oriented programming After completing this chapter. footba games. cha rs. and that the r propert es and behav or can be descr bed Examp es of such objects m ght be bank accounts. and so on There can be many eve s to these categor es and many ways to c ass fy the objects n the wor d How peop e c ass fy th ngs depends to a arge extent on what they want to do w th them as we as the re evant features of the objects themse ves For examp e. cars. researchers rea zed that many computer programs mode ed ent t es that can be named. dogs and cats are mamma s. a car’s co or m ght not matter. and users. a of wh ch are ana ogous to objects n the rea wor d 13 . we a so tend to h gh ght certa n attr butes of objects n preference to others For nstance. a reta er of househo d app ances s ke y to use d fferent categor es—poss b y deeper and r cher—for ts products than a typ ca homeowner When group ng objects nto c ass ficat on schemes. creat ng them and defin ng how they are re ated As ong ago as the 1960s. bank accounts. sw mm ng and tenn s are sports. arrays. toasters and refr gerators are app ances. to an eng neer. arrangng them nto some form of c ass ficat on and choos ng to h gh ght certa n features of objects n preference to others So. trucks and cars are veh c es. fi es. you will be able to ■ Descr be the key concepts of object-or ented programm ng ■ Understand how these concepts are supported by C++ anguage constructs ■ Understand the major deve opment benefits of object-or ented programm ng ■ Create and use s mp e c asses What is object-oriented programming? Object-or ented programm ng s a parad gm that prov des a natura way to deve op many k nds of systems We perce ve the wor d as cons st ng of objects tab es. computers.

for examp e. se f-conta ned ent t es For examp e. such as an nteger The c ass exposes the essent a features of the Account object wh e h d ng the mp ementat on deta s The account’s name and the state of ts ba ance are some of the attr butes of the object n wh ch the c ent s nterested and needs to know Deta s of how the account name s stored—whether t’s an array of 50 characters or a str ng object. inheritance. but t s much eas er to do object-or ented programm ng f you use a anguage that s des gned to support object-or ented programm ng methods Object-or ented programm ng anguages such as C++ and C# are character zed by three key features encapsulation. add ng attr butes to the objects to descr be the features re evant to the prob em context. you no onger need to worry about the deta s of the mp ementat on of the c ass You can use the c ass anywhere n your app cat on n much the same way you wou d use a bu t. s mp e doesn’t necessar y mean easy A co ect on of objects cou d potent a y be c ass fied n many ways The ab ty to dent fy the mportant attr butes of objects and to form good abstract ons and appropr ate h erarch es s cruc a Even w th n the context of a prob em doma n. t s a s mp e process Yet.n type. take a tr p over the Rock es n a go f cart. t’s somet mes hard to determ ne the correct eve s of abstract on and su tab e c ass ficat on h erarch es Just dec d ng wh ch c ass or group ng an object be ongs to can be very d fficu t As ph osopher Ludw g W ttgenste n po nted out n h s 1953 book Philosophical Investigations.Object-or ented programm ng can crude y be character zed as dent fy ng the objects re evant to the prob em. just the same as you cou d. and polymorphism These features support th s natura process of dent fy ng and c ass fy ng objects Let’s take a c oser ook at each one Encapsulation One of the prob ems faced by software deve opers s that the systems we are deve op ng are becomng ncreas ng y arger and more comp ex Encapsu at on he ps to keep th ngs manageab e by breakng an app cat on down nto sma . you’ probab y need objects to represent accounts and nvo ces After you’ve deve oped the Account c ass. and t prevents the other objects from access ng deta s about wh ch they 14  Microsoft Visual C++/CLI Step by Step . organ z ng them nto h erarch es. but essent a y. or the fact that the account’s ba ance s ma nta ned as a currency var ab e—are rre evant to the c ent The process of h d ng the data structures and mp ementat on deta s of an object from other objects n the system s ca ed encapsulation (somet mes a so known as data hiding). f you’re bu d ng an accountng system. some objects w bear more of a fam y resemb ance to a concept than others. and add ng funct ons (methods) to the objects such that they can perform the r requ red tasks The deta s are a tt e more comp cated. hockey and tenn s are more obv ous y sports than are chess and synchron zed sw mm ng Features of object-oriented programming languages I’ve a ready po nted out that object-or ented programm ng means defin ng and bu d ng h erarch es of objects and defin ng the r propert es and behav or You can do th s to a certa n extent n any programm ng anguage. theoret ca y.

a car cons st ng of an eng ne and a chass s—can a so s mp fy the deve opment effort Do ng t th s way. by nher tance Inher tance prov des two benefits to the C++ programmer F rst.don’t need to know Encapsu at on makes arge programs eas er to comprehend. and CheckingAccount and SavingsAccount are more spec fic types The second benefit of object-or ented programm ng s that c asses can nher t features from c asses h gher n the h erarchy Instead of deve op ng new c asses from scratch. f you need to deve op c asses for a dr v ng game. each of the objects s s mp er and therefore eas er to des gn and mp ement than the co ect ve who e Polymorphism The th rd feature of object-or ented programm ng anguages s polymorphism. we cou d say that a veh c es have “start” funct ona ty Exact y how start ng s mp emented depends on the veh c e If t s a Ford Mode T. so I’ use some examp es to show you what po ymorph sm s and eave the prec se defin t ons to more academ c wr ters Po ymorph sm essent a y means that c asses can have the same behav or but mp ement t n d fferent ways Cons der severa d fferent types of veh c e they a need to be started. new c asses can nher t the funct ona ty of ex st ng c asses and then mod fy or extend th s funct ona ty The parent c ass from wh ch the new c ass nher ts s known as the base class. and the new c ass s known as the derived class One of the major tasks fac ng deve opers s find ng appropr ate c ass ficat ons for the objects and c asses n the r programs For examp e. and most mportant. start ng w mean manua y crank ng the Chapter 2  ntroduc ng object or ented programm ng   15 . the nner work ngs of a c ass can be changed w thout affect ng the code that uses objects created. you can pass t a SavingsAccount or a CheckingAccount because both c asses are types of Account Account s a genera c ass ficat on. from that c ass The programmer wou d have to worry on y about the methods n the c ass that accessed that var ab e rather than worry about a the p aces n the app cat on that an object nstant ated from that c ass m ght be ca ed Inheritance The natura tendency for humans to c ass fy objects nto h erarch es s usefu from a programmer’s perspect ve and s supported n object-or ented anguages. or instantiated. SavingsAccount and CheckingAccount. wh ch s Greek for “many forms ” It s qu te a hard concept to define. nc ud ng C++. data h d ng makes them more robust Objects can nteract w th other objects through on y the r pub c y exposed attr butes and methods The more attr butes and methods that are pub c y exposed. t makes more sense for you to deve op a genera car c ass and then use th s c ass as a base c ass for spec fic car types such as sportscar or truck These der ved c asses wou d then extend or mod fy the genera car c ass by add ng new attr butes and methods or by overr d ng ex st ng methods Compos ng objects from subobjects—for examp e. t ets you bu d h erarch es that express the “is a” re at onsh ps between types Suppose that you have two c asses. both of wh ch are der ved from the parent Account c ass If you have a funct on that requ res an Account as an argument. so n programm ng terms. the more d fficu t t w be to mod fy the c ass w thout affect ng the code that uses the c ass When done proper y.

you define c asses. such as the ab ty to depos t. you cannot use c asses d rect y A c ass s ke a temp ate.start ng hand e at the front of the veh c e. I can st depos t funds. so the Animal c ass does  not represent a spec fic an ma but the c ass of a an ma s When you want to use an Animal object. t doesn’t matter exact y what type of account t s. object-or ented programm ng s about objects An object s composed of data that descr bes the object and the operat ons that can be performed on the object However. you wou d not define an Animal object Instead. but f t s a modern car. you wou d define an Animal c ass a ong w th ts attr butes and methods The c ass represents the concept. start ng w mean turn ng the key n the gn t on If the veh c e s a steam ocomot ve. cons der the aforement oned SavingsAccount and CheckingAccount types A types der ved from Account share certa n funct ona ty. ndeed As another examp e. when you create an app cat on n C++. you have to nstant ate an Animal object from the c ass The c ass can be cons dered as the abstract representat on of an ent ty. wh ch s used to create ( nstant ate) objects Just as you have to dec are an int var ab e before you can use t. the terms “c ass” and “object” have been used fa r y nterchangeab y However. not objects A class s a user-defined type. start ng w be a very d fferent and more comp ex process. whereas SavingsAccount m ght accrue nterest. reusability. and query the ba ance Th s funct ona ty s usefu n programm ng terms because t g ves you the ab ty to work w th gener c object types—accounts and veh c es— when you’re not concerned w th the way n wh ch each c ass mp ements funct ona ty Classes and objects Up to th s po nt n the chapter. w thdraw funds. but they a work the same way Th s means that f I’m passed an Account. and we need to c ar fy the d fferences between these terms As the name mp es. c asses and objects aren’t the same th ng. t encapsu ates both the data and the methods that work on that data W th the except on of stat c funct ons. and extensibility Break ng code down nto c asses makes t more comprehens b e by mpos ng a structure as programs grow arger and arger The dea s to assemb e object-or ented systems from prewr tten c asses and to make the requ red mod ficat ons to support the new requ rements by us ng nher tance 16  Microsoft Visual C++/CLI Step by Step . whereas the nstant at on of the c ass—the object— s the concrete representat on Benefits to the development life cycle There are three key benefits to object-or ented programm ng comprehensibility. and query the ba ance They m ght mp ement them n d fferent ways because CheckingAccount m ght perm t an overdraft. w thdraw. you a so have to nstant ate an object of the c ass before you can use t For examp e.

thus. hence reduc ng the r costs to ma nta n Der v ng new c asses from ex st ng c asses prov des add t ona funct ona ty and makes t poss b e to extend the software w thout a ter ng the ex st ng c asses F na y. under Temp ates.and compos t on to der ve new c asses from the ex st ng c asses The ex st ng c asses are reused as bu d ng b ocks and not a tered n any way Creat ng systems from reusab e components natura y eads to h gher product v ty. and then c ck Project The New Project d a og box opens 3. any bugs that m ght have ex sted have been found and fixed n these c asses. type Animals 6. t s ke y to conta n fewer bugs than c asses deve oped from scratch Over t me. and access member funct ons and attr butes 1. nher tance. On the F e menu. t means that you are us ng code that has a ready been tested and proven n ear er projects. Toward the bottom of the d a og box. wh ch s probab y the most frequent y c ted benefit of object-or ented approaches Object-or ented programm ng shou d a so resu t n h gher-qua ty systems When you reuse c asses. n the Name box. po nt to New. data h d ng a so eads to more secure systems The state of an object can be mod fied on y by ts pub c y exposed methods. C ck the Locat on box and se ect a ocat on for the new project (or c ck Browse to find t). c ck V sua C++. Start M crosoft V sua Stud o 2012 2. the deve oper s s mp y creat ng objects Large systems m ght requ re more objects than sma systems. In the nav gat on pane on the eft. regard ess of the s ze of the system. wh ch ncreases the pred ctab ty of object behav or A simple example The fo ow ng s mp e examp e shou d serve to show you how to create a c ass. and then c ck CLR 4. nstant ate objects. and po ymorph sm) of object-or ented programm ng a so prov de benefits Encapsu at on makes t eas er to sca e up from sma systems to arge systems For the most part. but the eve of comp ex ty fac ng the deve oper s not s gn ficant y ncreased Inher tance he ps to mprove the flex b ty and extens b ty of systems. and then c ck OK Chapter 2  ntroduc ng object or ented programm ng   17 . In the center pane choose CLR Conso e App cat on 5. whereas code that s wr tten from scratch has yet to pass through the same bug detect on and fix ng process The features (encapsu at on.

private. no other app cat on or c ass w be ab e to access these var ab es The members of a c ass—data and methods—are pr vate by defau t and can on y be accessed by methods of the c ass tse f C++ prov des three access mod fiers. you have created an Animal c ass w th an int var ab e for the number of ts egs and a String var ab e for ts name As t stands.7. you use the keywords ref class fo owed by a name for the c ass— Animal n th s examp e—and then you st a the member var ab es and funct ons for the c ass between open ng and c os ng braces ({ and }) So far. public. doub e-c ck the An ma s cpp fi e 8. The fi e An ma s cpp shou d a ready be open n the ed tor If t s not. n the Source F es fo der. and protected. add the fo ow ng c ass defin t on ref class Animal { int legs. To dec are a c ass n C++. String ^name. Immed ate y under the using namespace System. Add the keyword public fo owed by a co on ( ) on a new ne between the open ng brace and the first var ab e dec arat on 18  Microsoft Visual C++/CLI Step by Step . }. wh ch you use to spec fy the v s b ty of the var ous members of the c ass 9. n So ut on Exp orer. ne.

private: String ^name. “More about c asses and objects. }. } String^ GetName() { return name. }. t s not usua y a good dea to a ow other c asses and parts of your app cat on access to the var ab es of a c ass As d scussed ear er n the sect on on encapsu at on. Add the keyword private fo owed by a co on ( ) between the first int var ab e and the second String var ab e ref class Animal { public: int legs. we use the keyword private to prevent d rect access to the String var ab e of the c ass We’ eave the int var ab e legs w th pub c access. After the dec arat on of the int var ab e and before the private access mod fier. t’s better to keep the mp ementat on deta s of a c ass h dden from users of that c ass and to contro the access to the c ass’s data through funct ons In the next step. t’s eas est to dec are and mp ement them as inline functions In ne funct ons are exp a ned further n Chapter 6. you make both of them access b e However. To prov de access to the pr vate String var ab e.ref class Animal { public: int legs: String ^name. add the fo ow- ng method dec arat ons or mp ementat on nes void SetName(String ^nm) { name = nm. } Because these methods are sma funct ons. s mp y to show how t can then be d rect y accessed by the ma n app cat on 10.” when we go nto c asses n greater deta Chapter 2  ntroduc ng object or ented programm ng   19 . By dec ar ng the var ab es after the keyword public. pub c accessor funct ons and methods need to be added to the c ass to a ow other funct ons to man pu ate ts va ue 11.

dog. dog.legs = 4. the var ab es wou d have been created on the stack Instead of dec ar ng hand es for th s c ass and then creat ng the objects on the CLR heap. you use the dot operator ( ) You can read th s as “set the name of the cat to ‘Cat’. reference types must be accessed v a the r hand es. wh ch cou d force a garbage co ect on to occur In add t on. the NET Framework a so supports value types Va ue types are objects created on the stack The var ab e conta ns the object tse f rather than a hand e to the object Hence. t s created on the Common Language Runt me (CLR) heap The fet me of an object nstant ated from the c ass s managed by the NET Framework’s garbage co ector When the object goes out of scope. the memory used by the object s garbage-co ected automat ca y ref c asses are known as reference types because the var ab e does not actua y conta n the object. 3. the objects are dec ared n the same way as the bu t. To access the member var ab es and funct ons of an object.You have probab y not ced the ref keyword Th s C++/CLI keyword s mp fies the nteract on w th NET Framework components By p ac ng ref n front of the class keyword.SetName("Cat").legs = 4. cat. 2. wh ch of course mproves performance To dec are a va ue type c ass. In the main funct on. dog. and the member var ab es are accessed by the dot operator Now that you have wr tten the Animal c ass.SetName("Dog"). your app cat on can use t just as the app cat on wou d use a bu t. and set the legs var ab e for both objects to 4 cat.” w th the dot operator re at ng the funct on to the object on wh ch t s operat ng Hav ng created a coup e of Animal objects and ass gned data to them. you are now go ng to d sp ay that data on the screen 20  Microsoft Visual C++/CLI Step by Step . Dec are and create two Animal objects n your main funct on Animal cat. affect ng both the s ze and speed of the comp ed app cat on Because of these performance ssues. there are performance ssues to cons der when us ng reference types The memory has to be a ocated from the managed heap. the c ass becomes a managed c ass When the object s nstant ated. the var ab e doesn’t have to be dereferenced to man pu ate the object. Use the member funct on SetName to ass gn the names Cat and Dog to the respect ve cat and dog objects. rather t s a po nter to the memory ocat on of the object. the value keyword shou d be used nstead of the ref keyword In th s case.n C++ types.n type 1. known as a handle However. de ete the fo ow ng ne Console::WriteLine(L"Hello World").

dog. cat.legs = 4. Console::WriteLine(cat. ref class Animal { public: int legs. Console::Write("Legs: "). Console::WriteLine(cat. Chapter 2  ntroduc ng object or ented programm ng   21 . int main(array<System::String ^> ^args) { Animal cat. Console::WriteLine().SetName("Cat"). Console::WriteLine().legs). Console::WriteLine(dog. Console::Write("Name: "). Console::WriteLine(cat. Console::WriteLine(). Console::Write("Name: ").legs). cat. } String^ GetName() { return name. } private: String ^name. the ent re app cat on s sted here #include "stdafx. Console::WriteLine("Animal 2"). void SetName(String ^nm) { name = nm.legs).GetName()). Console::WriteLine(dog.GetName()).legs = 4. c ck Bu d So ut on or use the keyboard shortcut F6 In case you’ve had any prob ems putt ng the app cat on together from the fragments n the preced ng steps. Console::Write("Name: "). t’s t me to bu d the app cat on 5. Console::Write("Legs: "). dog.h" using namespace System. Console::WriteLine("Animal 2"). Console::Write("Name: "). Console::WriteLine(dog.GetName()). Now.4. dog.SetName("Dog"). On the Bu d menu. Console::Write("Legs: ").GetName()). Console::WriteLine(cat. Console::WriteLine("Animal 1"). Add the fo ow ng nes Console::WriteLine("Animal 1"). }.

run the app cat on by c ck ng Start W thout Debugg ng on the Debug menu. fo owed by a co on (:). 22  Microsoft Visual C++/CLI Step by Step . nstant ate a reference type c ass object. Use the keyword class. return 0. Console::WriteLine(). P ace the value keyword before the class spec fier. If the bu d was successfu .legs).Console::Write("Legs: "). Dec are a va ue type c ass. or use the keyboard shortcut Ctr +F5 Quick reference To Do this Create a c ass. private. or protected. Use the name of the c ass when dec ar ng an object. Dec are a reference type c ass. Contro the v s b ty of var ab es and methods. Console::WriteLine(dog. } 6. Use the access contro keywords public. for examp e: Animal cat. P ace the ref keyword before the class spec fier.

and a va ue The va ue of the var ab e can be changed dur ng the execut on of the app cat on.n C++ data types ■ Use the M crosoft NET Framework Str ng c ass ■ Ass gn va ues to a var ab e ■ Create express ons by us ng the C++ operators ■ Cast (change) the type of a var ab e I n Chapter 2 “Introduc ng object-or ented programm ng. and you must g ve t a name The type of a var ab e defines the a owab e range of va ues that the var ab e can ho d and the operat ons that you can perform on t The fundamental data types C++ has a bu t. the fundamenta data types of C++. how to access and use c asses from the NET Framework. as out ned n the fo ow ng tab e 23 .” you ooked at the advantages of objector ented programm ng and deve oped a s mp e app cat on to ustrate the creat on and use of c asses In th s chapter. you will be able to: ■ Dec are (create) var ab es ■ Use the bu t. a type.CHAPTER 3 Variables and operators After completing this chapter. hence. you’ take a c oser ook at how to create and use var ab es. the name var ab e Before you can use a var ab e.n set of data types. and how to create express ons by us ng C++ operators What is a variable? Var ab es are ocat ons n memory where data can be temporar y stored for use by the app cat on They have a name. you must dec are t you must spec fy ts type.

.

the comp er does the fo ow ng ■ ■ A ocates enough memory to store the var ab e of that type and to assoc ate the name of the var ab e w th that memory ocat on Reserves the name of the var ab e to prevent t from be ng used by other var ab es w th n the same scope Note  Scope refers to that part of the code for which a variable is visible—in other words. // A double variable without qualifier or // initializer. and underscores. y. unsigned) You can a so p ace an n t a zer after the var ab e name to g ve t an n t a va ue (for examp e. they shou d be mean ngfu . long salary = 0. as ong as the first character of the var ab e name s a etter or an underscore A though C++ does not p ace any restr ct ons on your cho ce of var ab e names. t’s not a good dea to d fferent ate var ab es so e y on the bas s of case. and you shou d be cons stent n your nam ng convent ons to ncrease the readab ty of your code C++ s case-sens t ve Th s means that myvariable and myVariable are two separate var ab es However. // An unsigned integer variable i. f you have dec ared a var ab e as a char.Declaring a variable As I ment oned ear er. where it can be used. do ng so cou d ead to confus on It wou d be easy to type a etter n the wrong case and end up us ng a comp ete y wrong var ab e! Chapter 3  Var ab es and operators   25 . fo owed by one or more var ab e names separated by commas and term nated by a sem co on.” ■ Ensures that the var ab e s used n a way cons stent w th ts type For examp e. you can’t store the va ue 3 7 n t Variable naming A C++ var ab e name can be any comb nat on of etters. double y. The concept of scope is explained more in Chapter 4. When you dec are a var ab e. int i = 0) The qua fier and the n t a zer are opt ona and are not requ red to appear n the dec arat on. double x. z. unsigned int i. // A long variable initialized to zero. numbers. you must dec are var ab es before you can use them A s mp e dec arat on cons sts of a type. as shown n the fo ow ng examp e int primeNumber. but the base type and var ab e name must be present The dec arat on s term nated by a sem co on [qualifier] type name [initializer]. note the // qualifier limiting the variable to // positive numbers. You can g ve each var ab e a qua fier before the type (for examp e. “Using functions.

Th s statement creates three ntegers ca ed x. or t must be exp ct y converted (cast) to the correct type Assignment conversions Ass gnment convers ons occur when var ab es on oppos te s des of an equa s gn are of d fferent types and the comp er can convert between the two types w thout any poss b e oss of data For nstance. and t can be rather dangerous because you’re d rect ng the comp er to app y a convers on that t otherw se wou d not do. as demonstrated n the fo ow ng int x = 10. You g ve the name of the type to wh ch to convert. wh ch s on the eft s de When ass gn ng a va ue to a var ab e. and you’d better be sure you’re correct 26  Microsoft Visual C++/CLI Step by Step . z = 11. y. Microsoft uses this naming convention to specify macros and Microsoft-specific keywords. Declaring multiple variables You can dec are severa var ab es of the same type n the same statement s mp y by separat ng them w th commas. you can nstruct the comp er to convert one of the va ues to a doub e. A). d v d ng two ntegers resu ts n an nteger resu t f you want a float ng-po nt resu t. fo owed by the va ue n parentheses Th s process s ca ed casting.” it’s not a good idea to create identifiers that begin with two underscores or an underscore followed by a capital letter (for example. so starting your variables with these combinations could lead to name conflicts.Note  As is mentioned in Chapter 1. ass gn ng an int to a double resu ts n an ass gnment convers on because conceptua y a the comp er has to do s to add 0 to the nteger to make the convers on You m ght occas ona y need to force the comp er to perform a convers on that t otherw se wou dn’t do For examp e. the va ue must be ong to the same type as the var ab e. “Hello C++!. and z The first nteger s n t a zed to 10 and the th rd to 11. y. t must be a type for wh ch C++ w perform an ass gnment convers on (such as between float and ntegra types). whereas the second s not n t a zed Assigning values to variables You ass gn a va ue to a var ab e by us ng the ass gnment operator = (the equa s gn) The va ue on the r ght s de of the operator s stored n the var ab e. as ustrated here double result = double(640) / 480.

hand e var ab es are dec ared to be data-type spec fic A hand e to a Person object can’t store the address of an Account A hand e var ab e s dec ared n the same way as the data-type var ab e.56. the address stored n your po nter m ght become out of date. // handle to a Person // handle to an Account Note  It is in fact possible to use pointers in some circumstances in C++/CLI. but the hand e operator ^ (caret character) s prepended to the var ab e name Person ^pp. In th s fina case the comp er w generate the warn ng “C4244 ‘=‘ convers on from ‘float’ to ‘ nt’ poss b e oss of data ” The reason for th s s because the ass gnment to an nteger w ose the fract ona part. thus. ustrated here Person ^pp = gcnew Person("Fred"). // Assignment conversion from float to int // results in loss of data. but that is beyond the scope for this introductory discussion. float y. Account ^ac. ead ng to prob ems f you try to use t For th s reason po nters. n the trad t ona C++ sense. as You typ ca y create an object dynam ca y and obta n a hand e to t by us ng the gcnew operator. y = 3. so 3 56 w be truncated to 3 Handles and pointers In standard C++. wh ch means that you can use a po nter to refer nd rect y to a var ab e In C++/CLI.int x. wh ch a so conta n the address of a var ab e but wh ch w be updated by the runt me f t has to move the var ab e around A though a hand e conta ns an address and therefore can store a memory address of any data type. are not used n C++/CLI Instead. however. and t reserves the r ght to move th ngs around to max m ze the ava ab e free memory Th s means that an object m ght not stay at the same address throughout ts fet me. z = x. double z. // The integer 3 is stored in the variable x. the runt me s manag ng memory on your beha f. x = 1. you use handles (a so known as tracking handles). a po nter s a var ab e that ho ds the memory address of another var ab e or funct on. x = y. Chapter 3  Var ab es and operators   27 .

but does not corrupt memory Each storage ocat on s ca ed an element of the array E ements of the array are accessed by an ndex. the va ue of a constant can’t be changed after t has been dec ared It has to be n t a zed when t’s created and can’t be ass gned a new va ue ater C++ has two types of constants literal and symbolic A tera constant s s mp y a va ue typed nto the app cat on The statements n the fo ow ng code ass gn the tera s 40 and Dog to the respect ve var ab es noOfEmployees and name noOfEmployees = 40. each of wh ch ho ds the same type of data. arr[0] = 23. wh ch s d scussed n more deta n the fo ow ng chapters Arrays An array s a co ect on of data-storage ocat ons. but the qua fier must start w th the keyword const and the var ab e must be 28  Microsoft Visual C++/CLI Step by Step . // The first element in the array starts at offset 0 arr[9] = 21. name = "Dog". pass ng n the str ng “Fred” as n t a zat on data. // Declare an array of ten integers. int x. A symbo c constant s a constant that s represented by a name You define t n exact y the same way as a var ab e. // Use an element from the array Constants L ke var ab es. wh ch starts at zero and cont nues up to one ess than the array bound Why not start the ndex from one? Th s s to preserve compat b ty w th other C-type anguages. and return a hand e to the object t has created When you access a member of an object through a hand e.Th s code nstructs the runt me to create a new Person object. such as a ntegers or a doub es Arrays are very usefu when you want to represent a co ect on of va ues (such as the number of days n each month or the names of company emp oyees) and you know how many you need to store Un ke c ass c C++. un ke a var ab e. wh ch a start array ndex ng from zero To dec are an array. constants are named data-storage ocat ons However. you use the po nter operator (->). // The last element in the array starts at offset 9 x = arr[0]. arrays n C++/CLI are objects that know how much data they are manag ng Th s makes them safer than trad t ona C++ arrays because any attempt to read or wr te past the end of the array resu ts n a run-t me error. you need to spec fy the type of tem that you are go ng to store You create array objects dynam ca y by us ng the gcnew operator array<int> ^arr = gcnew array<int>(10).

const unsigned long noOfPartTimeEmployees = 234. The . as shown n the fo ow ng const unsigned long noOfFullTimeEmployees = 49.n type. you can use the constant name anywhere that you can use a var ab e of that type. Th s typedef dec ares positiveNumber to be a synonym of unsigned int and can be used n a dec arat on nstead of the actua type name positiveNumber one. ts fu name s System::String.n t a zed After dec arat on. the number of days n a week or months n a year These va ues can be eft as tera s w thout reduc ng the readab ty or ma nta nab ty of the code Typedefs A typedef s a user-defined synonym for an ex st ng type To create a synonym for a type. There are a coup e of advantages to us ng symbo c constants rather than tera constants ■ ■ The symbo c names make the app cat on more readab e The symbo c constant noOfFull TimeEmployees s more mean ngfu than the tera constant 49 It’s eas er to change a s ng e symbo c constant dec arat on than to find and rep ace a occurrences of a tera n a app cat on However.NET Framework String class The String c ass s not a bu t. you a so need a c os ng sem co on typedef unsigned int positiveNumber. noOfEmployees = noOfFullTimeEmployees + noOfPartTimeEmployees. Th s ne makes t eas er to use certa n NET c asses Because String s n the System namespace. for examp e. unsigned long noOfEmployees. us ng symbo c constants nstead of tera s can be taken too far It s not necessary to rep ace a tera s w th constants There are some constants that are ntu t ve y obv ous to everyone and that are not go ng to change.n data type ke int or long. you must nc ude some fi es n your project before the comp er w et you use t Code that wants to use the String c ass needs to nc ude the fo ow ng ne at the top of ts source code fi e using namespace System. t s a part of the NET Framework Because String sn’t a bu t. two. you use the keyword typedef fo owed by the name of the type and the new name you are defin ng Because typedef s a C++ statement. but a using namespace statement such as th s makes t poss b e for you to use the name w thout qua ficat on Th s w be exp a ned n more deta ater on Chapter 3  Var ab es and operators   29 .

the mu t p cat on operator * (the aster sk). // result = 3 // result = 20 // remainder = 1 In add t on. In th s examp e. it is immutable: It can’t be changed after it is created. noOfDogs. a three var ab es—noOfMammals.3. and the modu us operator % (the percent s gn). The member functions of the String class that appear to alter strings. If you need to make repeated changes to a string. Here the add t on operator + (p us s gn) s used to add the operands salary and bonus. and the ass gnment operator = (equa s gn) s used to store the tota n the remuneration var ab e Assignment operators You use an ass gnment express on to ass gn a va ue to a var ab e A express ons return a va ue when eva uated. such as Insert and Replace. there are a number of ar thmet c ass gnment operators. adding a using namespace statement for the System::Text namespace to simplify access. result = 4 * 5. wh ch returns the rema nder after d v s on result = 4 + 2 . which contains the modified string. and noOfCats—are set to 0 Arithmetic operators C++ has 12 ar thmet c operators. remainder = 7 % 3. the subtract on operator – (the m nus s gn). Operators and expressions Express ons are bu t by us ng operators that work w th data—the operands—to g ve a resu t Look at th s examp e remuneration = salary + bonus. and the va ue of the ass gnment express on becomes the new va ue of the object on the eft s de Th s funct ona ty makes t poss b e to ass gn the same va ue to a group of var ab es noOfMammals = noOfDogs = noOfCats = 0.The String c ass conta ns a arge number of methods to s mp fy man pu at ng str ngs. such as Insert and Replace Note  After you initialize a String object. 5 of wh ch operate ke the standard mathemat ca operators the add t on operator + (the p us s gn). actually return a new String object. the d v s on operator / (the s ash). you should use the StringBuilder class. each of wh ch cons sts of the operator and the = (equa s gn) so the add t on ass gnment operator += s a p us s gn w th an equa 30  Microsoft Visual C++/CLI Step by Step .

both of wh ch must be true for the operator to return a true va ue The OR operator returns true f e ther of the two express ons eva uates to true Chapter 3  Var ab es and operators   31 . // Subtracts 1 from the value of the variable a There are two forms of the ncrement and decrement operators the prefix form ++a or – –a. b. and the NOT operator ! (an exc amat on po nt) The AND operator re ates two express ons. b = 1 // c = 1. the var ab e s ncremented or decremented after the var ab e has been used n the express on int a = b = c = a. n the prefix form. a++. there s no d fference between the two statements In both statements. but these operators on y add or subtract 1 from the va ue of the var ab e a++. the OR operator (two p pes). thus. %= These operators are shorthand forms that comb ne the correspond ng mathemat ca operat on w th the ass gnment operat on So. the fo ow ng two statements are dent ca a = a + 5. and we a so have –=. = 0. and c = 1 The prefix ncrement operator express on added 1 to the va ue of a before ass gn ng the va ue of the var ab e a to the var ab e b The postfix ncrement operator express on ass gned the va ue of the var ab e a to the var ab e c and then ncremented the va ue of the var ab e a by 1 Relational and logical operators Re at ona operators are used to compare two va ues or express ons. // a = 1. as shown n the fo ow ng code a a a a a a > b >= b < b <= b == b != b // // // // // // returns returns returns returns returns returns true true true true true true if if if if if if a a a a a a is is is is is is greater than greater than less than b. b = c ++a. a += 5. and the postfix forms a++ or a– – A though both forms add or subtract 1.s gn. fo owed by an ass gnment The second form s just a shorter way of express ng a frequent y used operat on The ncrement and decrement operators are s m ar shorthand operators. b = 1. equal to b. return ng a va ue of true or fa se C++ has s x re at ona operators. or equal to b. *=. the mathemat ca operat on s performed before the var ab e s used n the express on. A og ca operator s used to re ate two re at ona express ons C++ has three og ca operators the AND operator && (two ampersands). c. The add t on ass gnment operator s a shortcut operators. the fina va ues of the var ab es are a = 2. n the postfix form. // Adds 1 to the value of the variable a a--. /=. b. a = 2 In th s code fragment. not equal to b. an add t on s performed. less than or equal to b.

flags. wh ch are d scussed n Chapter 5.a && b (a > b) && (a < c) a || b (a > b) || (a < c) // // // // // // returns returns is less returns returns or a is true true than true true less if both a and b are true if a is greater than b and a c if either a or b are true if either a is greater than b than c The eva uat on of a re at ona express on stops as soon as the og ca va ue of the who e express on s determ ned. f the b t s 0. the OR operator (a vert ca bar). and long The b tw se AND operator compares the b ts of two operands. the comp ement operator ~ (a t de). e ther b t s 0 the resu tng b t s set to 0 Th s operator s often used to mask off b ts The b tw se OR operator compares the b ts of two operands If e ther b t s 1. f the var ab e s s gned. t s set to 1 The eft-sh ft operator moves the b t pattern of ts eft operand to the eft by the number of b ts spec fied by ts r ght operand The b ts vacated by the eft sh ft are fi ed w th zeros The r ght-sh ft operator moves the b t pattern of ts r ght operand to the r ght by the number of b ts spec fied by ts r ght operand If the var ab e s an uns gned data type. the vacated b ts w be fi ed w th the s gn b t int a. the resu t ng b t s 1. a feature known as short-circuit evaluation For examp e. the correspond ng b t of the resu t s set to 0 The b tw se OR operator s often used to turn on b ts. the vacated b ts w be fi ed w th zeros. // The bits of a will be shifted two bits to the left // and the value of 20 assigned to a. the b t s set to 0 The comp ement operator reverses the b t sett ng of the operand If the b t s 1. f the b t n the same pos t on for each operand s 1. or opt ons The exc us ve OR operator sets the resu t b t to 1 on y f one of the operands has the correspondng b t set to 1 If the correspond ng b t of both operands s 1 or 0. the r ght-sh ft operator >> (two r ght ang e brackets). a = 5. the express on expr1 && expr2 s true on y f both expr1 and expr2 are true If expr1 s fa se. 32  Microsoft Visual C++/CLI Step by Step . t s set to 0. however. a = a << 2. f. expr2 s not eva uated The NOT operator returns the negat on of the Boo ean va ue of ts operand !a // returns false if a is true // returns true if a is false These operators are most often used n dec s on or oop structures. and the eft-sh ft operator << (two eft ang e brackets) These operators work on the nd v dua b ts of the byte and can on y be app ed to ntegra operands—the types char. short. and therefore. and f both b ts are 0. the fina va ue of the express on must be fa se. int. the exc us ve OR operator ^ (a caret). “Dec s on and oop statements ” Bitwise operators C++/CLI has s x b tw se operators the AND operator & (an ampersand). the correspond ng b t of the resu t s 1.

f t s true. t performs Chapter 3  Var ab es and operators   33 .a = 5. b = true. f an express on needs to convert an int to a double. Type casting C++/CLI supports the C-sty e cast operator. a = b ? 1 : 2. the number shou d be cast by us ng the static cast<double> operator Here’s an examp e int a = 10. // b is false. the va ue or express on after the co on w be returned int a. the va ue or express on between the quest on mark and the co on w be returned If t s fa se. double b. // The bits of a will be shifted two bits to the // right and the value of 1 assigned to a. // C++ static cast You use the dynamic cast<> operator to cast objects down or across the nher tance h erarchy The const cast<> operator works w th po nters. for examp e. so a is assigned 2. whereby the type to wh ch you want to convert the express on s p aced n parentheses n front of the express on. // b is true. bool b. a = b ? 1 : 2. b = false. (float) 7 It a so supports five C++ cast operators ■ static cast<> ■ const cast<> ■ dynamic cast<> ■ safe cast<> ■ reinterpret cast<> The static cast<> operator changes the data type of the var ab e. b = (int) a. // old C-style cast b = static_cast<double>(a). so a is assigned 1. w th the type to wh ch you want to cast be ng p aced n the ang e brackets For examp e. The ternary operator The ternary operator ?: (a quest on mark and a co on) acts ke an n ne if statement (See Chapter 5 for more nformat on on if statements ) The express on to the eft of the quest on mark s eva uated. a = a >> 2. and references can be used to add or remove the const qua ficat on of the var ab e The safe cast<> operator s an extens on added to C++/CLI.

.

Group homogenous data together. Chapter 3  Var ab es and operators   35 . Use parentheses to group operators. Use the . Overr de defau t operator precedence. Use the static cast<> operator. fo owed by a sem co on. Prevent data from be ng changed. Use an array. Convert one data type to another. Make the var ab e a constant. and dec are the var ab e to be of that type. Access a String c ass.NET String c ass. fo owed by spaces and then the var ab e name. For examp e: int number1. Use the ass gnment operator =. For examp e: const int x = 10. Restr ct the va ues a var ab e can accept to a sma set. or make the code more readab e. long longNumber1. Dec are an enumerated constant. Spec fy the type.Quick reference To Do this Dec are a var ab e. Ass gn va ues to a var ab e.

.

wh ch reduces cod ng effort and therefore mproves deve oper product v ty 37 . you’ earn how to d v de a C++/CLI app cat on nto funct ons F rst. you’ see how to dec are funct on prototypes to ntroduce the funct ons to the comp er Next. you’ see how to define funct on bod es to carry out the requ red process ng For examp e. use operators. as your programs beg n to grow arger. you’ see how to ca a funct on from e sewhere n your app cat on Why use functions? There are many good reasons for d v d ng an app cat on nto funct ons Here are three of them ■ ■ ■ Each funct on s usua y qu te short and d screte It’s eas er to wr te an app cat on as a ser es of funct ons than as a s ng e.CHAPTER 4 Using functions After completing this chapter. you will be able to: ■ Dec are funct on prototypes ■ Define funct on bod es ■ Ca funct ons ■ Dea w th oca and g oba var ab e scope ■ Define and use over oaded funct ons B y now. you m ght wr te a funct on to ca cu ate the expected growth on an nvestment or to extract the user’s password from a ogon screen F na y. you need to organ ze your code to cope w th the grow ng comp ex ty In th s chapter. wr te statements. ong funct on because you don’t have to remember what the ent re app cat on s do ng Funct ons are reusab e After you’ve wr tten a funct on. you can ca t whenever you need t n your app cat on. you shou d be fa r y comfortab e w th bas c C++/CLI syntax You’ve seen how to dec are var ab es. and perform s mp e conso e output However. ong scr pt because you can concentrate on one funct on at a t me It’s a so eas er to read and debug an app cat on that conta ns ots of sma funct ons than one that conta ns a s ng e.

but f you’re wr t ng C++/CLI code. Microsoft Visual Basic . Start V sua Stud o 2012 and create a new CLR Conso e App cat on project named InvestmentPlanner After the project s created. wh ch s trad t ona y typed n owercase etters In th s exerc se. A function prototype doesn’t give you any indication as to what the function does. and it marks the end of the function prototype. and nd v dua words w th n the name shou d a so be cap ta zed. and t does not return a va ue. The semicolon is a statement terminator. For example. wh ch means that the funct on doesn’t take any parameters The void keyword at the beg nn ng of the funct on prototype nd cates that the funct on doesn’t return a va ue. the funct on just d sp ays a we come message on the screen Note  Some programming languages differentiate between functions (which return a value) and subroutines (which do not return a value). In th s examp e.ne statement that ntroduces the name of a funct on to the comp er The prototype a so nd cates what types of parameters can be passed nto the funct on and what type of va ue the funct on returns The comb nat on of nformat on about a funct on’s name and parameters s ca ed the function signature Declaring a simple function prototype The fo ow ng examp e shows a s mp e funct on prototype void DisplayWelcome(). it just provides the function signature. the source fi e appears n the ed tor w ndow 38  Microsoft Visual C++/CLI Step by Step . the name of the funct on s DisplayWelcome The parentheses are requ red to nd cate that th s s a funct on The parentheses are empty n th s examp e.NET uses the Function keyword for functions and the Sub keyword for subroutines. you wou d be w se to adopt the convent on used n the M crosoft NET brar es Funct on names shou d start w th a cap ta etter. use the void return type if the function doesn’t return a value. A note on function naming Some anguages have very strong nam ng convent ons that gu de how you shou d construct funct on and var ab e names C++ has never had such a un versa convent on.Declaring function prototypes A funct on prototype s a s ng e. e ther 1. C++ only has functions. presumab y. you w dec are a s mp e funct on prototype n a C++/CLI app cat on The funct on does not take any parameters. notice the semicolon at the end of the function prototype. Also. as n DisplayWelcome or CreateNewCustomerOrder The except on to th s convent on s the entry po nt main.

Th s funct on prototype dec ares a funct on named DisplayProjectedValue The funct on takes three parameters a double. you w dec are a funct on prototype that uses parameters 1. Bu d your app cat on to check the syntax Declaring the return type in a function prototype As we as spec fy ng nput parameters for a funct on. an int. you must a so spec fy a return type for the funct on As you saw ear er.2. the void return type nd cates that the funct on does not return a va ue In th s exerc se. you w see how to spec fy a non-void return type for a funct on 1. Cont nue work ng w th the project you created n the prev ous exerc se 2. c ck Bu d So ut on to bu d your app cat on and check that there are no syntax errors There’s no po nt n runn ng the app cat on yet because you haven’t mp emented or ca ed the DisplayWelcome funct on You’ do that ater n th s chapter Declaring parameters in a function prototype Funct ons can take parameters to make them more gener c You must dec are the data types for these parameters n the funct on prototype In th s exerc se. Add the fo ow ng funct on prototype mmed ate y be ow the void DisplayWelcome() ne void DisplayProjectedValue(double amount. Th s ne s the funct on prototype you saw ear er You p ace funct on prototypes near the top of the source fi e so that they are v s b e to the rest of the code n the fi e 3. Cont nue work ng w th the project from the prev ous exerc se 2. int years. At the top of the fi e. parameter names help to convey the meaning of the parameters. and another double The comp er uses th s nformat on to ensure that the funct on s a ways ca ed w th the correct number and types of parameters Tip  Parameter names are optional in the function prototype. Strictly speaking. However. Chapter 4  Us ng funct ons   39 . so it’s good practice to use them. add the fo ow ng funct on prototype void DisplayWelcome(). mmed ate y be ow the using namespace System. On the Bu d menu. you could omit the parameter names and just specify the parameter types. ne. double rate). Add the fo ow ng funct on prototype mmed ate y be ow the void DisplayProjectedValue() ne double GetInvestmentAmount(). 3.

int max=25). as shown in this example: double CalculateAverageValue(int number1. Mod fy the funct on prototype as fo ows to define defau t parameter va ues int GetInvestmentPeriod(int min=10. int number2). The fact that the GetInvestmentPeriod parameters and return type are all ints is entirely coincidental. Bu d your app cat on 40  Microsoft Visual C++/CLI Step by Step . Bu d your app cat on Declaring default values for function parameters When you dec are a funct on prototype. you w ear er define defau t parameters n one of the funct on prototypes you dec ared 1. 3. It’s quite easy to imagine a function whose parameter types and return type are different. but t returns a doub e 3. int max). Th s funct on prototype has two parameters named min and max The parameters are fo owed by = (the equa s gn) and then a defau t va ue We have defined a defau t va ue of 10 for the min parameter and a defau t va ue of 25 for the max parameter You’ see how to ca th s funct on n the sect on “Ca ng funct ons” ater n th s chapter 4. Cont nue work ng w th the project from the prev ous exerc se 2. mmed ate y be ow the double GetInvestment Amount() ne int GetInvestmentPeriod(int min. Add another funct on prototype as fo ows. int max). the comp er w subst tute the defau t va ue on your beha f In th s exerc se. 4. F nd the fo ow ng funct on prototype int GetInvestmentPeriod(int min. Th s examp e shows how to dec are a funct on that takes parameters and returns a va ue The GetInvestmentPeriod funct on takes two int parameters and returns an int Note  The parameter types and return type are independent of one another. you can spec fy defau t va ues for some or a of ts parameters Defau t va ues are usefu for parameters that usua y have the same va ue each t me the funct on s ca ed Spec fy ng a defau t va ue for a funct on parameter means that you can om t the parameter va ue when you ca the funct on.Th s funct on prototype dec ares a funct on named GetInvestmentAmount The funct on doesn’t take any parameters.

and ts return type However. the return keyword s superfluous because the c os ng brace of the funct on acts as an mp c t return However. “Dec s on and oop statements ” In th s exerc se. } Not ce that the first ne of the funct on body s dent ca to the funct on prototype. you w define funct on bod es for a the funct on prototypes ntroduced ear er Defining a simple function body The fo ow ng examp e shows a s mp e funct on body. you must define a funct on body The funct on body conta ns executab e statements to perform the des red operat ons n the funct on In th s sect on. to return premature y from a funct on You’ see more about the if statement n Chapter 5. Chapter 4  Us ng funct ons   41 . funct on prototypes do not conta n any executab e statements. correspond ng to the DisplayWelcome funct on prototype from ear er n chapter void DisplayWelcome() { Console::WriteLine("---------------------------------------"). you earned how to dec are funct on prototypes Reca that a funct on prototype spec fies the name of a funct on. Console::WriteLine("---------------------------------------"). the DisplayWelcome funct on d sp ays a s mp e we come message on the screen In the next two sect ons you’ see more comp ex funct ons that perform conso e nput and mathemat ca ca cu at ons The return keyword at the end of the funct on causes flow of contro to return to the ca ng funct on In th s examp e. define the DisplayWelcome funct on body as fo ows void DisplayWelcome() { Console::WriteLine("--------------------------------"). you can use return n other ocat ons n a funct on.Defining function bodies In the prev ous sect on. return. Locate the end of the main funct on On the next ne. except that there s no sem co on Th s first ne s known as the function header After the funct on header. Cont nue work ng w th the project you created ear er n th s chapter 2. Console::WriteLine( "Welcome to your friendly Investment Planner"). such as w th n an if statement. a pa r of braces ({}) enc oses the executab e statements for the funct on body In th s examp e. you w add the DisplayWelcome funct on body to your C++/CLI app cat on 1. they do not nform you as to what the funct on w do when t s ca ed To prov de the behav or for a funct on. Console::WriteLine( "Welcome to your friendly Investment Planner"). ts parameter st.

Define some oca var ab es w th n the funct on double rateFraction = 1 + (rate/100). Defining a function body that uses parameters When you define a funct on body that uses parameters. f the rate s 6 percent.Console::WriteLine("---------------------------------"). 2). you w define a funct on body for the DisplayProjectedValue funct on You saw the prototype for th s funct on ear er void DisplayProjectedValue(double amount. int years. You can’t define one function body inside the braces ({}) of another function. double rate) { 3. int years. years). you should use the same parameter names in the prototype and the function body. return. double rate). However. For example. rateFraction w be 1 06 42  Microsoft Visual C++/CLI Step by Step . you can place the DisplayWelcome function body before or after the main function body. } 3. double finalAmount = amount * Math::Pow(rateFraction. The funct on body w have the same s gnature as the prototype and w ca cu ate the projected va ue of an nvestment after a spec fied number of years at a part cu ar growth rate 1. Bu d your app cat on You shou dn’t get any comp er errors Note  You can define function bodies in any order in C++/CLI. However. Scro to the end of the source code and add the fo ow ng nes—th s s the start of the DisplayProjectedValue funct on body void DisplayProjectedValue(double amount. Cont nue work ng w th the project from the prev ous exerc se 2. finalAmount = Math::Round(finalAmount. you must define exact y the same number and types of parameters as n the funct on prototype Th s s qu te reasonab e The who e po nt of the funct on prototype s to ntroduce the exact s gnature of the funct on Tip  The function body can use different parameter names than the prototype because the parameter names in the prototype are there just for documentation. the rateFraction var ab e ho ds the growth rate as a fract ona va ue For examp e. In th s exerc se. Here. functions cannot be nested. for consistency.

years) shows how to ra se a number to a power n C++/CLI For examp e. Math::Pow(1. as you saw ear er double GetInvestmentAmount(). Bu d your app cat on Defining a function body that returns a value When you define a funct on w th a non-void return type. you w define a funct on body for the GetInvestmentAmount funct on Here s the prototype for the funct on. Console::Write("Period [years]: "). } 5. The funct on asks the user how much money she wants to nvest It returns th s va ue as a double data type You w a so define a funct on body for the GetInvestmentPeriod funct on The prototype for th s funct on s as fo ows int GetInvestmentPeriod(int min=10. f finalAmount s 1000 775. Console::WriteLine(rate).The express on Math::Pow(rateFraction. The funct on asks the user how ong she wants to nvest the money It returns th s va ue as an int va ue 1. Console::WriteLine(finalAmount). use the return keyword fo owed by the va ue that you want to return Note  If you forget to return a value. int max=25). return. Console::Write("Growth rate [%]: "). you’ll get an error when the compiler reaches the closing brace of the function. Console::WriteLine(amount). In th s exerc se. Cont nue work ng w th the project from the prev ous exerc se Chapter 4  Us ng funct ons   43 . Console::WriteLine(years).06. Console::Write("Projected final value of investment: "). the rounded va ue w be 1000 78 4. 2) rounds finalAmount to two dec ma p aces For examp e. Add the fo ow ng statements to the funct on to d sp ay the resu t of the ca cu at ons Console::Write("Investment amount: "). you must return an appropr ate va ue from the funct on To return a va ue. 3) s equ va ent to 1 06 * 1 06 * 1 06 The express on Math::Round(finalAmount. This point is where the compiler realizes you haven’t returned a value from the function.

ask ng the user how much money she wants to nvest The Console::ReadLine funct on ca reads a ne of text from the keyboard. int years = Convert::ToInt32(input). Console::Write("min="). For example. Console::Write(". Console::Write("] ? "). int max) { Console::Write("Over how many years ["). } The Console::Write funct on ca s ask the user to enter a va ue between min and max These va ues are supp ed as parameters nto the GetInvestmentPeriod funct on The Console::ReadLine funct on ca reads the user’s nput as a String.2. for which you have to declare local variables at the start of a block. String ^input = Console::ReadLine(). double amount = Convert::ToDouble(input). and the Convert::ToInt32 funct on ca converts th s va ue nto a 32-b t nteger The return statement returns th s va ue to the ca ng funct on 44  Microsoft Visual C++/CLI Step by Step . Console::Write(max). } The first statement d sp ays a prompt message on the conso e. Console::Write(min). String ^input = Console::ReadLine(). Typically. which is different from the C programming language. you should declare variables at the point where they are first needed in the function. 3. Add the fo ow ng funct on body int GetInvestmentPeriod(int min. return amount. return years. Scro to the end of the source code and define the GetInvestmentAmount funct on body as fo ows double GetInvestmentAmount() { Console::Write("How much money do you want to invest? "). here the input and amount variables are declared halfway down the GetInvestmentAmount function. max="). and the resu t s ass gned to a String var ab e The Convert::ToDouble funct on ca parses the String and converts t to a double va ue The return statement returns th s va ue back to the ca ng funct on Tip  You can declare local variables anywhere in a function.

and the default value for max is 25. Note  You can ignore the return value from a function if you want. Th s s a s mp e examp e because the funct on doesn’t take any parameters or return a va ue If you want to ca a funct on that returns a va ue. Chapter 4  Us ng funct ons   45 . the ast step s to ca the funct ons at the appropr ate p ace n the app cat on To ca a funct on. 6. If you want to ca a funct on that takes parameters. but the value is discarded. Default values are specified only in the function prototype—you don’t mention these default values in the function body. 25. Just provide the parameter values. pass ng n three tera va ues as parameters DisplayProjectedValue(10000. When you call the function. you can ca the DisplayWelcome funct on as fo ows DisplayWelcome(). pass the parameter va ues between the parentheses n the funct on ca The fo ow ng examp e ca s the DisplayProjectedValue funct on. spec fy ts name fo owed by a pa r of parentheses For examp e. If you accidentally define the default values in the function body as well as in the function prototype. you can ass gn the return va ue to a var ab e The fo ow ng examp e ca s the GetInvestmentAmount funct on and ass gns the return va ue (a double) to a oca var ab e named sum double sum = GetInvestmentAmount(). The function still returns the value.Note  The function prototype for GetInvestmentPeriod declared default values for the min and max parameters. Note  You don’t specify the parameter data types when you call a function. you’ll get a compiler error at the function body. 4. The default value for min is 10. Bu d your app cat on Calling functions Now that you have defined a the funct on bod es n the samp e app cat on.0). leave out the assignment operator on the left side of the function name.

you must use the default values for each subsequent parameter in the parameter list. Locate the main funct on and then rep ace the ne that pr nts “He o. // First parameter is 5. // second parameter // defaults to 25.) You can use these default values when you call the function. 6. Next add the fo ow ng statements to ask the user how much he wants to nvest and for how ong Console::WriteLine("\nEnter details for your investment:"). int period = GetInvestmentPeriod(5. the following function call is invalid: int period = GetInvestmentPeriod(. you ca the GetInvestmentPeriod funct on to get a va ue between 5 and 25 You ass gn the return va ue to a oca int var ab e named period int period = GetInvestmentPeriod(5. For example.. 46  Microsoft Visual C++/CLI Step by Step // Try to use default value // for just the first // parameter – illegal.The fo ow ng examp e shows how to ca a funct on that takes parameters and returns a va ue In th s examp e. you w extend your samp e app cat on to nc ude the funct on ca s you’ve just seen 1. 25). double sum = GetInvestmentAmount(). wor d” w th the fo ow- ng statement. 25. . The GetInvestmentAmount and GetInvestmentPeriod funct on ca s return these va ues Note The GetInvestmentPeriod function has default values for each of its parameters. If you use a default value for a parameter.000 after 25 years at a growth rate of 6 percent 4. The DisplayProjectedValue funct on ca d sp ays the va ue of 10. and the second parameter has a default value of 25. 20). Add the fo ow ng statements to d sp ay an ustrat on of nvestment growth Console::WriteLine("\nIllustration. (The first parameter has a default value of 10. 25). 3. Cont nue work ng w th the project from the prev ous exerc se 2. Calling functions in the sample application In th s exerc se. DisplayProjectedValue(10000. For example.. the following function call uses the default value for the second parameter: int period = GetInvestmentPeriod(5).0)."). wh ch ca s the DisplayWelcome funct on DisplayWelcome().

c ck next to the DisplayWelcome funct on ca to n- sert a debug breakpo nt A red dot appears n the border.5. Bu d your app cat on and fix any comp er errors On the Debug menu. Add the fo ow ng statements to ca cu ate and d sp ay the projected fina va ue of th s nvest- ment. In the gray border to the eft of the code. as shown n the graph c that fo ows Tip  If you add a breakpoint in the wrong place."). Open the project from the prev ous exerc se 2. DisplayProjectedValue(sum. Locate the main funct on 3. c ck Start W thout Debugg ng to run the app cat on You shou d see output s m ar to the fo ow ng Stepping through the application by using debugger In th s exerc se. assum ng a growth rate of 6 percent Console::WriteLine("\nYour plan. you w step through the app cat on by us ng the debugger Do ng so w he p you understand how the flow of contro passes from one funct on to another n your app cat on Th s exerc se a so ustrates the concept of var ab e scope You w see how oca var ab es n a funct on come nto scope dur ng the funct on’s execut on and d sappear from scope at the end of the funct on 1. period. simply click again on the red dot to remove it. 6.0). 6. Chapter 4  Us ng funct ons   47 ...

4. Press F11 to step nto the DisplayWelcome funct on The debugger ca s the DisplayWelcome funct on and d sp ays a ye ow arrow at the start of that funct on 48  Microsoft Visual C++/CLI Step by Step . t executes and stops at the breakpo nt n the main funct on A ye ow arrow appears n the marg n next to the DisplayWelcome funct on ca The ye ow arrow nd cates that th s s the next statement to be executed 5. Start the debugg ng sess on by press ng F5 After the app cat on oads.

6. To display the Debug toolbar. point to Toolbars and then click Debug from the list of toolbars that appears. the debugger returns you to the main funct on The ye ow arrow nd cates the next statement to execute n main Chapter 4  Us ng funct ons   49 .Note  You can also use the Debug toolbar to control the debugger. Press F10 severa t mes to step over each statement one at a t me n the DisplayWelcome funct on Th s causes a we come message to be d sp ayed n the conso e w ndow At the end of the funct on. Each of the debug function keys mentioned in the remainder of this exercise has an equivalent Debug toolbar button. on the View menu.

Keep press ng F10 unt you reach the end of the DisplayProjectedValue funct on and return to main 50  Microsoft Visual C++/CLI Step by Step . and then c ck Loca s The oca var ab es n th s funct on appear The Loca s w ndow d sp ays five oca var ab es The first three var ab es—amount. Press F11 to step nto the DisplayProjectedValue funct on On the Debug menu. the debugger s a tt e m s eadng here because the finalAmount and rateFraction var ab es haven’t even been dec ared yet These var ab es don’t rea y ex st unt the var ab e dec arat on statements further on n the funct on 9. po nt to W ndows.7. and rate—are the funct on parameters These var ab es are a ready n t a zed w th the va ues you passed nto the funct on The ast two var ab es—finalAmount and rateFraction—do not have mean ngfu va ues because the var ab es haven’t been ass gned a va ue yet In fact. years. Press F10 severa t mes to step over the statements n the DisplayProjectedValue funct on Observe how the finalAmount and rateFraction var ab es change dur ng the funct on (The debugger d sp ays va ues that were changed dur ng the execut on of the prev ous statement n red for prom nence ) Take a ook at the conso e w ndow to see what s d sp ayed 10. Press F10 to step over the Console::WriteLine funct on The debugger executes the Console::WriteLine funct on but doesn’t take you through t step by step The ye ow arrow moves on to the DisplayProjectedValue funct on ca n main 8.

press F5. Press F11 to step nto the GetInvestmentAmount funct on Step through the statements n th s funct on When the debugger executes the ReadLine statement. Cont nue stepp ng through the app cat on n th s manner unt the app cat on term nates Tip  If the debugger takes you into a function that you’re not interested in stepping through. Press F10 one more t me and then exam ne the oca var ab es n main Not ce that the return va ue from GetInvestmentAmount has been ass gned to the sum oca var ab e n main 15. press F10 to step over the Console::WriteLine statement 12. press Shift+F11 to step out of the function. In main. the conso e w ndow appears and you are asked to enter a number Type a number such as 20 and then press Enter 13.11. wh ch means you can qu te happ y have var ab es w th the same name n d fferent funct ons w thout nterference Chapter 4  Us ng funct ons   51 . If you just want to run the application without stopping at all. Understanding local and global scope The prev ous exerc se demonstrated how each funct on defines ts own scope for oca var ab es The oca var ab es are created dur ng funct on execut on and are automat ca y destroyed at the end of the funct on. Keep stepp ng through the GetInvestmentAmount funct on unt you return to ma n 14.

as fo ows int numberOfYourFunctionsCalled = 0. it can be difficult to pinpoint where the problem occurred. Before the start of the main funct on. as shown n the fo ow ng 52  Microsoft Visual C++/CLI Step by Step . Global variables have too much visibility. if one becomes corrupt. In th s exerc se.It’s a so poss b e to dec are var ab es g oba y. ncrement the numberOfYourFunctionsCalled var ab e. For these reasons. you should use global variables sparingly. Because global variables can often be used in several functions. especially in object-oriented languages such as C++. 3. define a g oba nteger var ab e named numberOf YourFunctionsCalled. as you saw earlier in this chapter. you w define a g oba var ab e n your app cat on You w n severa funct ons to ustrate ts g oba scope use th s g oba var ab e 1. outs de of any funct on G oba var ab es are v s b e n a funct on bod es that come after the g oba var ab e defin t on n your source fi e You can use g oba var ab es as a rud mentary way of shar ng nformat on between mu t p e funct ons Important  Global variables are generally considered bad programming practice. A better way of sharing information between functions is to pass parameters and return values. Global variables also introduce too much dependency between functions. F nd the DisplayWelcome funct on n your code At the start of th s funct on. Cont nue work ng w th the project from the prev ous exerc se 2.

just before the return statement. Bu d and run your app cat on How many of your funct ons are ca ed dur ng the app cat on? Overloading functions W th C++/CLI. This can make it easier to work with code by hiding functions that are not of interest at the moment. int arraySize). Add a s m ar statement to the start of every funct on n your app cat on 5. Chapter 4  Us ng funct ons   53 . Average. Mod fy the main funct on At the end of th s funct on.Note  You can click the minus sign (–) symbol to the left of the code to collapse a block of code. as ong as each funct on has a d fferent parameter st Th s process s known as function overloading Funct on over oad ng s usefu f you have severa d fferent ways of perform ng a part cu ar operat on based on d fferent nput parameters For examp e. the main function has been collapsed. you m ght want to prov de an Average funct on to find the average va ue of two double va ues. 4. d sp ay the va ue of the numberOfYourFunctionsCalled var ab e 6. To view a collapsed block. double Average(int array[]. to emphas ze the common purpose of these funct ons Define d fferent parameter sts for the funct ons to d fferent ate one from another double Average(double number1. In the preceding screen shot. you can prov de many funct ons w th the same name. click the plus sign (+) to expand it again. and you m ght have another Average funct on to find the average va ue of an array of ntegers You can define two funct ons to support these requ rements G ve each funct on the same name. double number2).

you’ll get a compiler error. Add the fo ow ng funct on prototype at the start of your code. p ac ng t after the ex st ng DisplayProjectedValue funct on void DisplayProjectedValue(double amount. Random r. In the main funct on.You must st mp ement both of these funct ons—there s no mag c here! When you ca the Average funct on. int randomRate = r. the functions must have different parameter lists. 20). In th s exerc se. } Tip  You now have two overloaded DisplayProjectedValue functions. Th s funct on uses the Random c ass to ca cu ate a random number between 0 and 20 The funct on passes the random number nto the or g na vers on of the DisplayProjectedValue funct on to ca cu ate the va ue of the nvestment us ng th s random rate 54  Microsoft Visual C++/CLI Step by Step . 3. ocate the second ca to the DisplayProjectedValue funct on Mod fy the funct on ca so that you pass on y two parameters nto the funct on DisplayProjectedValue(sum.Next(0. you w define an over oaded vers on of the DisplayProjectedValue funct on The new vers on ca cu ates a random growth rate between 0 and 20 percent rather than use a spec fic growth rate 1. be ow the ex st ng prototype for DisplayProjectedValue void DisplayProjectedValue(double amount. period). int years). randomRate). DisplayProjectedValue(amount. int years) { numberOfYourFunctionsCalled++. 4. Define the new DisplayProjectedValue funct on body as fo ows. the comp er deduces wh ch vers on of the funct on to ca based on the parameter va ues you supp y Note  If you define overloaded functions. Cont nue work ng w th the project from the prev ous exerc se 2. years. It is good practice to keep overloaded functions together in the source code. If you define overloaded functions that differ only in their return type.

Use an = operator. For examp e: double MyFunction(int p1. Define defau t parameters. fo owed by the defau t va ue. Spec fy the funct on name and pass parameter va ues w th n parentheses. Define the g oba var ab e outs de of any funct on. void MyFunction() { myGlobal++.. For examp e: return (p1 + p2) / 2. Spec fy the return type of the funct on. fo owed by the funct on name. Run the app cat on severa t mes to ver fy that the growth rate rea y s random Quick reference To Do this Dec are a funct on prototype. Define a funct on body. Define defau t parameters n the funct on prototype. Spec fy the return type of the funct on. Remember to nc ude the sem co on at the end of the funct on prototype. Do not spec fy defau t parameters here.00. For examp e: double MyFunction(int p1. f the funct on returns a va ue. } Return a va ue from a funct on. fo owed by the va ue that you want to return.. For examp e: double MyFunction(int p1. Define the funct on body w th n braces. Bu d the app cat on and start t n the debugger 7. fo owed by the parameter st enc osed n parentheses. Use the var ab e n any subsequent funct on n the source fi e.5. f requ red.. fo owed by the funct on name. 175). For examp e: double result = MyFunction(100. . Define breakpo nts at the start of both of the DisplayProjectedValue funct ons 6. you can ass gn t to a var ab e. Define and use g oba var ab es. fo owed by the parameter st enc osed n parentheses. Observe wh ch vers ons of DisplayProjectedValue are ca ed as your app cat on executes See what random number the app cat on uses for your growth rate 8.. short p2). short p2=100). short p2) { int n = p1 + p2. Ca a funct on. . For examp e: int myGlobal = 0. Use the return keyword. } Chapter 4  Us ng funct ons   55 .

.

the next statement s executed. you w C++/CLI app cat on see how to use these statements to contro the flow of execut on through a Making decisions by using the if statement The most common way to make a dec s on n C++/CLI s to use the if statement You can use the if statement to perform a one-way test. for.CHAPTER 5 Decision and loop statements After comp et ng th s chapter. a mu t way test.eve anguages prov de keywords w th wh ch you can make dec s ons and perform oops C++ s no except on C++ prov des the if statement and the switch statement for mak ng dec s ons. you w be ab e to ■ Make dec s ons by us ng the if statement ■ Make mu t way dec s ons by us ng the switch statement ■ Perform oops by us ng the while. for. Console::WriteLine("The end"). and do-while statements for perform ng oops In add t on. because t s outs de the body of the if statement 57 . or a nested test Let’s cons der a s mp e one-way test first Performing one-way tests The fo ow ng examp e shows how to define a one-way test n C++/CLI if (number < 0) Console::WriteLine("The number is negative"). and do-while statements ■ Perform uncond t ona jumps n a oop by us ng the break and continue statements A h gh. C++ prov des the break statement to ex t a oop mmed ate y and the continue statement to return to the start of the oop for the next terat on In th s chapter. wh ch n th s examp e w d sp ay the message “The number s negat ve” Not ce that the message “The end” w a ways be d sp ayed. The if keyword s fo owed by a cond t ona express on. and t prov des the while. wh ch must be enc osed n parentheses If the cond t ona express on eva uates to true. regard ess of the outcome of the test. a two-way test.

At the top of the source code fi e. int month). } 58  Microsoft Visual C++/CLI Step by Step . // Note the spurious semicolon This statement is equivalent to the following statement. ne. as shown here: if (number < 0). mp ement the GetYear funct on as fo ows int GetYear() { Console::Write("Year? "). It is a common C++ programming error to put one in by mistake. after the end of the main funct on. mmed ate y be ow the using namespace System. void DisplayDate(int year. Console::WriteLine(" is negative"). At the end of the fi e. as follows: if (number < 0) { Console::Write("The number "). int GetMonth(). int month. 3. you w create a new app cat on to perform one-way tests As th s chapter progresses. int GetDay(int year. Many developers reckon that it is good practice to enclose the if body in braces. int day). } Console::WriteLine("The end"). add the fo ow ng funct on prototypes (you w mp ement a these funct ons dur ng th s chapter) int GetYear(). In th s exerc se. int year = Convert::ToInt32(input). return year. you w extend the app cat on to use more comp ex dec s on-mak ng constructs and to perform oops For now. Console::Write(number). which is probably not what you intended: if (number < 0) . enclose the if body in braces ({}).Note  There is no semicolon after the closing parenthesis in the if test. the app cat on asks the user to enter a date and then t performs s mp e va dat on and d sp ays the date n a user-fr end y format on the conso e 1. // Null if-body – do nothing if number < 0 If you want to include more than one statement in the if body. Start V sua Stud o 2012 and create a new CLR Conso e App cat on project Name the app ca- t on CalendarAssistant 2. String ^input = Console::ReadLine(). This means that the code will still be correct if you (or another developer) add more statements to the if body in the future. even if it only consists of a single statement.

} Th s s a s mp fied mp ementat on. String ^input = Console::ReadLine(). month). int month. you w sure that the user enters a va d month enhance the funct on to en- 5. int month) { Console::Write("Day? "). Console::Write("-"). int day) { Console::WriteLine("\nThis is the date you entered:"). Chapter 5  Dec s on and oop statements   59 . int month = Convert::ToInt32(input). Console::WriteLine(). String ^input = Console::ReadLine(). return month. L ne Console::WriteLine("Welcome to your calendar assistant"). mmed ate y before the return 0. return day. int day = Convert::ToInt32(input).4. Console::Write(year). you w enhance th s funct on to ensure that the user enters a va d day for the g ven year and month 6. int month = GetMonth(). Console::WriteLine("\nPlease enter a date"). Add the fo ow ng code ns de the main method. } Later n th s chapter you w format enhance th s funct on to d sp ay the date n a more user-fr end y 7. Console::Write("-"). Imp ement the DisplayDate funct on as shown n the fo ow ng code to d sp ay the date as three numbers void DisplayDate(int year. Imp ement the GetMonth funct on as fo ows int GetMonth() { Console::Write("Month? "). int year = GetYear(). Console::Write(month). } Later. Imp ement the GetDay funct on as fo ows int GetDay(int year. ater n th s chapter. Console::Write(day). int day = GetDay(year.

” logical tests are performed from left to right. if the month is 0. 8. type an nva d date (for examp e. 7. the date s d sp ayed on the conso e If the date s nva d. Th s code asks the user to enter a year. there is no point performing the other tests—the date is definitely invalid. and day If the date passes a s mp fied va dat on test. Testing stops as soon as the final outcome has been established. Run the app cat on Type n va d numbers for the year. month. } Console::WriteLine("\nThe end\n"). and 33) The app cat on d sp ays the messages shown n the fo ow ng screen shot 60  Microsoft Visual C++/CLI Step by Step . day). 2. This is known as short-circuit evaluation. “Variables and operators. Run the app cat on aga n. and day (for examp e. and 22) The app cat on d sp ays the messages shown n the fo ow ng screen shot Observe that the app cat on d sp ays the date because t s va d The message “The End” a so appears at the end of the program 10. For example. but th s t me. Bu d the app cat on and fix any comp er errors that you m ght have 9. 2012. t s not d sp ayed at a Note This if statement combines several tests by using the logical AND operator &&. 2012. month. month.// Simplified test for now – assume there are 31 days in // every month :-) if (month >= 1 && month <= 12 && day >= 1 && day <= 31) { DisplayDate(year. As you learned in Chapter 3.

} Console::WriteLine("\nThe end\n"). rep ac ng the s mp e if w th an if-else statement to test for va d or nva d dates if (month >= 1 && month <= 12 && day >= 1 && day <= 31) { DisplayDate(year.Not ce that because the date you typed was nva d. day). Chapter 5  Dec s on and oop statements   61 . Cont nue work ng w th the project from the prev ous exerc se 2. month. the app cat on doesn’t d sp ay t Instead. Mod fy the main funct on. } else { Console::WriteLine("Invalid date"). day). you w enhance your Ca endar Ass stant app cat on to d sp ay an error message f an nva d date s entered 1. month. t just d sp ays “The End ” You can make the app cat on more user-fr end y by d sp ay ng an error message f the date s nva d To do so. } else { Console::WriteLine("Invalid date"). The else body defines what act on to perform f the test cond t on fa s In th s exerc se. } Console::WriteLine("\nThe end\n"). you need to use a two-way test Performing two-way tests The fo ow ng code shows how to define a two-way test for the Ca endar Ass stant app cat on if (month >= 1 && month <= 12 && day >= 1 && day <= 31) { DisplayDate(year.

3. This is unlike Microsoft Visual Basic . Bu d and run the app cat on Type an nva d date such as 2001. set maxDay to 30 If the month s February. In th s exerc se.NET. } Th s code spec fies that f the month s Apr . which uses the single keyword ElseIf. 0. } else { maxDay = 31. you w enhance your Ca endar Ass stant app cat on to d sp ay the max mum number of days n the user’s chosen month 62  Microsoft Visual C++/CLI Step by Step . maxDay s set to 28 (We’ gnore eap years for now!) If the month s anyth ng e se. September. } else if (month == 2) { maxDay = 28. if (month == 4 || month == 6 || month == 9 || month == 11) { maxDay = 30. set maxDay to 31 Note  There is a space between the keywords else and if because they are distinct keywords. as demonstrated n the fo ow ng screen shot Performing multiway tests You can arrange if-else statements n a cascad ng fash on to perform mu t way dec s on mak ng The fo ow ng code shows how to use a mu t way test to determ ne the max mum number of days (maxDay) n a month int maxDay. and 31 The app cat on now d sp ays an error message. June. or November.

1. as screen shot ustrated n the fo ow ng 4. int day = Convert::ToInt32(input). int month) { int maxDay. } Console::Write("Day [1 to "). Console::Write("]? "). Bu d and run the app cat on Type the year 2012 and the month 1 The app cat on prompts you to enter a day between 1 and 31. } else { maxDay = 31. Cont nue work ng w th the project from the prev ous exerc se 2. return day. Type a va d day and c ose the conso e w ndow when the date s d sp ayed Chapter 5  Dec s on and oop statements   63 . if (month == 4 || month == 6 || month == 9 || month == 11) { maxDay = 30. } 3. } else if (month == 2) { maxDay = 28. Console::Write(maxDay). Rep ace the GetDay funct on w th the fo ow ng code so that t uses an if-else-if statement to determ ne the max mum a owab e number of days int GetDay(int year. String ^input = Console::ReadLine().

as shown here 6. } If the month s February. you define a bool var ab e to determ ne f the year s a eap year A year s a eap year f t s even y d v s b e by 4 but not even y d v s b e by 100 (except years that are even y d v s b e by 400. } else { maxDay = 28. wh ch are eap years) The fo ow ng tab e shows some examp es of eap years and non– eap years 64  Microsoft Visual C++/CLI Step by Step . Type a va d day and c ose the conso e w ndow when the date s d sp ayed (Don’t worry about the date va dat on n main: You w remove t ater and rep ace t w th more comprehens ve va dat on n the GetMonth and GetDay funct ons ) Performing nested tests It s poss b e to nest tests w th n one another Th s makes t poss b e for you to perform more comp ex og ca operat ons The fo ow ng code shows how to use nested tests to accommodate eap years correct y n the Ca endar Ass stant app cat on int maxDay. if (isLeapYear) { maxDay = 29. } } else { maxDay = 31. } else if (month == 2) { bool isLeapYear = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0).5. Run the app cat on aga n Type the year 2012 and the month 2 The app cat on prompts you to enter a day between 1 and 28. if (month == 4 || month == 6 || month == 9 || month == 11) { maxDay = 30.

Cont nue work ng w th the project from the prev ous exerc se 2. rep ac ng the if…else if…else statements to match the b ock of code just descr bed to test for eap years 3. you w years enhance your Ca endar Ass stant app cat on to dea correct y w th eap 1. c ose the conso e w ndow 4. Run the app cat on aga n Type the year 1997 and the month 2 Ver fy that the app cat on prompts you to enter a day between 1 and 28 5. et’s take a ook at the switch statement Us ng the switch statement. you can test a s ng e var ab e and execute one of severa branches depend ng on the var ab e’s va ue Defining simple switch statements The examp e that fo ows shows the syntax for the switch statement The switch statement tests the numberOfSides n a shape and d sp ays a message to descr be that shape Chapter 5  Dec s on and oop statements   65 . In th s exerc se. Bu d and run the app cat on Type the year 1996 and the month 2 The app cat on prompts you to enter a day between 1 and 29 Type a va d day and then when the date s d sp ayed.Year Leap year? 1996 Yes 1997 No 1900 No 2000 Yes You then use a nested if statement to test the bool var ab e isLeapYear so that you can ass gn an appropr ate va ue to maxDay Note  There is no explicit test in the nested if statement. Mod fy the GetDay funct on. The condition if (isLeapYear) is equivalent to if (isLeapYear ! false). Run the app cat on severa more t mes us ng the test data from the prev ous tab e Making decisions by using the switch Statement Now that you have seen how the if statement works.

where foo is a variable whose value will only be known when the application executes. case 8: Console::Write("Octagon"). } The switch keyword s fo owed by an express on n parentheses Th s express on must eva uate to an nteger. case 5: Console::Write("Pentagon"). each of wh ch compr ses the keyword case. break. You can’t specify multiple values. 5 and a are va d. break. case 9: Console::Write("Nonagon"). Each case branch can conta n any number of statements At the end of each branch. This means that you can’t. break. break. you do need to use braces if you need to declare a variable within the branch code. case 10: Console::Write("Decagon"). for instance. In th s exerc se. the default branch can help you trap unexpected values and display a suitable warning to the user. break. and characters are a owed For examp e. but abc s not because t s a str ng tera Note  Each case label specifies a single literal value. default: Console::Write("Polygon"). You can define an opt ona default branch n the switch statement The default branch w ecuted f the express on doesn’t match any of the case abe s be ex- Tip  It’s good practice to define a default branch even if you don’t have any specific processing to perform. and the values must be known at compile time. you can’t define a range of values. say case foo. break. use a break statement to ex t the switch statement Note  There is normally no need to use braces around the code in a case branch. a character. enumerat on va ues. you w enhance your Ca endar Ass stant app cat on to d sp ay the month as a str ng such as January or February 66  Microsoft Visual C++/CLI Step by Step . case 7: Console::Write("Septagon"). and a co on The va ue dent fy ng a case branch must be a constant of nteger type Th s means that nteger numbers. // Number of sides in a shape . a va ue. or an enumerat on va ue The body of the sw tch cons sts of a ser es of case branches. Including the default branch shows that you haven’t just forgotten it. However. case 6: Console::Write("Hexagon"). The break statement marks the end of each case branch. Also. break.int numberOfSides. break. case 4: Console::Write("Quadrilateral")... switch (numberOfSides) { case 3: Console::Write("Triangle"). break.

break. break. break. Bu d the app cat on 4. default: Console::Write("Consonant"). flow of contro cont nues on to the next statement Th s process s ca ed fall-through Th s can be usefu to avo d dup cat on of code. Mod fy the DisplayDate funct on Rather than d sp ay the month as an nteger. break. case 8: Console::Write("August"). typ ng a d fferent month each t me Ver fy that the app ca- t on d sp ays the correct month name each t me Using fall-through in a switch statement If you om t the break statement at the end of a case branch. case 3: Console::Write("March"). 3. case 5: Console::Write("May"). break. but be carefu not to do t acc denta y The fo ow ng examp e ustrates why fa -through m ght be usefu Th s examp e tests a owercase etter to see f t s a vowe or a consonant char lowercaseLetter. case 9: Console::Write("September"). switch (lowercaseLetter) { case 'a': case 'e': case 'i': case 'o': case 'u': Console::Write("Vowel"). break. } There s no break statement n the first four case abe s As a resu t. break. Run the app cat on severa t mes. rep ace the Console::Write(month) statement w th a switch statement that d sp ays the month as a str ng switch (month) { case 1: Console::Write("January"). break. case 11: Console::Write("November"). case 4: Console::Write("April"). the flow of contro passes on to the next executab e statement to d sp ay the message Vowel The default branch dea s w th a the other etters and d sp ays the message Consonant Chapter 5  Dec s on and oop statements   67 . break..1. // Single lowercase letter. } break. break. break. for example 'a' . case 10: Console::Write("October"). break. case 7: Console::Write("July"). break. break. case 12: Console::Write("December"). case 2: Console::Write("February"). Cont nue work ng w th the project from the prev ous exerc se 2. default: Console::Write("Unknown"). case 6: Console::Write("June")..

the for oop. the for-each loop. break. you’ see how to perform oops n C++/CLI You’ a so see how to perform uncond t ona jumps n a oop by us ng the break and continue statements C++ has three ma n oop constructs the while oop. you w user’s date enhance your Ca endar Ass stant app cat on to d sp ay the season for the 1. but I’ll leave discussing that until we get to arrays.In th s exerc se. add the fo ow ng code after the ne Console::Write(day) to d sp ay the season switch (month) { case 12: case 1: case 2: Console::WriteLine(" [Winter]"). case 6: case 7: case 8: Console::WriteLine(" [Summer]"). and the do-while oop Note  There is actually a fourth loop type. break. month. case 3: case 4: case 5: Console::WriteLine(" [Spring]"). break. and day. Let’s ook at the while oop first Using while loops A while oop cont nues execut ng ts body for as ong as the cond t on n parentheses eva uates to true The fo ow ng examp e shows how to wr te a s mp e while oop n C++/CLI 68  Microsoft Visual C++/CLI Step by Step . } 3. Bu d the app cat on 4. typ ng a d fferent month each t me Ver fy that the app ca- t on d sp ays the correct season name each t me Performing loops For the rest of th s chapter. Cont nue work ng w th the project from the prev ous exerc se 2. case 9: case 10: case 11: Console::WriteLine(" [Fall]"). Run the app cat on severa t mes. break. Mod fy the DisplayDate funct on After d sp ay ng the year.

month. while (count <= 5) { Console::WriteLine(count * count). int day = GetDay(year. wh ch probab y sn’t what you want The preced ng examp e d sp ays the fo ow ng output In th s exerc se. You must fo ow the while keyword w th a cond t ona express on enc osed n parentheses As ong as the cond t ona express on eva uates to true.int count = 1. // Declare and initialize the loop counter while (count <= 5) // Test the loop counter { Console::Write("\nPlease enter a date "). you w dates enhance your Ca endar Ass stant app cat on so that the user can type five 1. count++. of course. int year = GetYear(). int count = 1. contro returns to the while statement and the cond t ona express on s tested aga n Th s sequence cont nues unt the test eva uates to fa se You must. the oop w terate forever. remember to nc ude some k nd of update statement n the oop so that t w term nate eventua y In th s examp e count++ s ncrement ng the oop counter If you don’t prov de an update statement. count++. Mod fy the code n the main funct on by rep ac ng the ent re body of the funct on w th the fo ow ng code Console::WriteLine("Welcome to your calendar assistant"). Cont nue work ng w th the project from the prev ous exerc se 2. Console::WriteLine(count). DisplayDate(year. int month = GetMonth(). month). the while body executes After the oop body has been executed. day). } Console::WriteLine("The end"). // Increment the loop counter } Chapter 5  Dec s on and oop statements   69 .

such as n t a z ng the oop counter Th s n t a zat on express on s executed once on y. at wh ch po nt the app cat on c oses.3. but f t s false. the app cat on prompts you to enter the second date Th s process cont nues unt you have typed five dates. count <= 5. count++) { Console::WriteLine(count * count). the oop fin shes and contro passes to the statement that fo ows the c osng parenthes s After the oop body has been executed. such as ncrement ng the oop counter 70  Microsoft Visual C++/CLI Step by Step . as dep cted n the fo ow ng screen shot Using for loops The for oop s an a ternat ve to the while oop It prov des more contro over the way n wh ch the oop executes The fo ow ng examp e shows how to wr te a s mp e for oop n C++/CLI Th s examp e has exact y the same effect as the while oop for (int count = 1. the oop body s executed. The preceding example illustrates this technique. The count variable is local to the for statement and goes out of scope when the loop terminates. The second express on statement defines a test If the test eva uates to true. the fina express on n the for statement s executed. The parentheses after the for keyword conta n three express ons separated by sem co ons The first express on performs oop n t a zat on. Bu d and run the app cat on The app cat on prompts you to enter the first date After you have typed th s date. at the start of the oop Note  You can declare loop variables in the first expression of the for statement. } Console::WriteLine("The end"). th s express on performs oop update operat ons.

DisplayDate(year. day). ). there’s st the for-each oop. wh ch you w meet ater) The do-while oop s fundamenta y d fferent from the while and for oops because the test comes at the end of the oop body. int day = GetDay(year. } Not ce that there s no count++ statement after d sp ay ng the date Th s s because the for statement takes care of ncrement ng the oop counter 3. int month = GetMonth(). wh ch means that the oop body s a ways executed at east once Chapter 5  Dec s on and oop statements   71 . you w mod fy your Ca endar Ass stant app cat on so that t uses a for oop rather than a while oop to obta n five dates from the user 1. which represents an infinite loop The preced ng examp e d sp ays the output shown n the fo ow ng screen shot In th s exerc se. Mod fy the code n the main funct on to use a for oop rather than a while oop. Cont nue work ng w th the project from the prev ous exerc se 2. count++) { Console::Write("\nPlease enter date "). count <= 5. You can omit any of the three expressions in the for construct as long as you retain the semicolon separators. Bu d and run the app cat on The app cat on asks you to enter five dates. as shown here Console::WriteLine("Welcome to your calendar assistant"). int year = GetYear(). month. month). You can even omit all three expressions. . Console::WriteLine(count). as before Using do-while loops The th rd oop construct you’ ook at here s the do-while oop (remember. as in for( .Note The for statement is very flexible. for (int count = 1.

Console::WriteLine(randomNumber). int randomNumber. month = Convert::ToInt32(input). to s mu ate a d e It then counts how many throws are needed to get a 6 Random ^r = gcnew Random(). } while (randomNumber != 6). do { Console::Write("Month [1 to 12]? ").The fo ow ng examp e shows how to wr te a s mp e do-while oop n C++/CLI Th s examp e generates random numbers between 1 and 6. wh ch forces the user to type a va d month int GetMonth() { int month = 0. Cont nue work ng w th the project from the prev ous exerc se 2. } 72  Microsoft Visual C++/CLI Step by Step . do { randomNumber = r->Next(1. Console::Write(throws). 7). you w mod fy your Ca endar Ass stant app cat on so that t performs nput va dat on. nc us ve. wh ch s a typ ca use of the do-while oop 1. throws++. Console::Write("You took "). String ^input = Console::ReadLine(). int throws = 0. fo owed by the oop body. fo owed by the while keyword and the test cond t on A sem co on s requ red after the c os ng parenthes s of the test cond t on The preced ng examp e d sp ays the output shown n the fo ow ng screen shot In th s exerc se. Console::WriteLine(" tries to get a 6"). Mod fy the GetMonth funct on as fo ows. The oop starts w th the do keyword.

you w mod fy the ma n oop n your Ca endar Ass stant app cat on You w g ve the user the chance to break from the oop premature y. int maxDay. Console::Write(maxDay). String ^input = Console::ReadLine(). day = Convert::ToInt32(input). as before (code not shown here) … … … do { Console::Write("Day [1 to "). Try to type an nva d day The app cat on keeps ask ng you to enter another day unt you type a va d number (wh ch depends on your chosen year and month) Performing unconditional jumps C++/CLI prov des two keywords—break and continue—w th wh ch you can jump uncond t ona y w th n a oop The break statement causes you to ex t the oop mmed ate y The continue statement abandons the current terat on and goes back to the top of the oop ready for the next terat on Note The break and continue statements can make it difficult to understand the logical flow through a loop. nc us ve 6. Cont nue work ng w th the project from the prev ous exerc se Chapter 5  Dec s on and oop statements   73 . } 3. return day. sk p the current date and cont nue on to the next one.while (month < 1 || month > 12). Mod fy the GetDay funct on as fo ows. Try to type an nva d month The app cat on keeps ask ng you to enter another month unt you type a va ue between 1 and 12. } 4. // Calculate maxDay. Use break and continue sparingly to avoid complicating your code unnecessarily. int month) { int day = 0. wh ch forces the user to type a va d day int GetDay(int year. or d sp ay the current date as norma 1. Console::Write("]? "). In th s exerc se. Bu d and run the app cat on 5. return month. } while (day < 1 || day > maxDay).

3.2. Console::Write("Press B (break). you are asked to type the th rd date 6. int month = GetMonth(). for (int count = 1. } else if (input->Equals("C")) { continue. count <= 5. and then press C fo owed by Enter. You will see another (and more idiomatic) way to do this using the operator when we discuss operator overloading. int day = GetDay(year. wh ch causes the break statement to be executed The break statement term nates the ent re oop 74  Microsoft Visual C++/CLI Step by Step . String ^input = Console::ReadLine(). C (continue). Mod fy the main funct on as fo ows. Console::Write("anything else to display date "). After you type the first date. Type the second date. wh ch causes the continue state- ment to be executed The continue statement abandons the current terat on w thout d sp ay ng your date Instead. you are asked whether you want to break or cont nue Press X (or any other key except B or C) and then press Enter to d sp ay the date as norma 5. } Note The Equals method is used here to check that two strings contain the same content. } DisplayDate(year. int year = GetYear(). Bu d and run the app cat on 4. month). or "). Console::WriteLine(count). day). wh ch g ves the user the opt on to break or continue f des red Console::WriteLine("Welcome to your calendar assistant"). count++) { Console::Write("\nPlease enter date "). month. Type the th rd date and then press B. if (input->Equals("B")) { break.

For examp e: int dayNumber. For examp e: int n = 10. For examp e: if (n < 0) { Console::Write("Negative"). Use the switch keyword fo owed by an ntegra expres s on enc osed n parentheses. } Perform terat on by us ng the while oop.Quick reference To Do this Perform a one way test. and define a defau t branch for a other va ues. break. Console::Write(n). break. } Test a s ng e express on aga nst a fin te set of constant va ues. while (n >= 0) { Console::WriteLine(n). default: Console::Write("Weekday"). Console::WriteLine(" is negative"). Use an if else construct. For examp e: if (n < 0) { Console::Write("The number "). // 0=Sun. … switch (dayNumber) { case 0: case 6: Console::Write("Weekend"). Use the while keyword fo owed by a test enc osed n parentheses. } else if (n == 0) { Console::Write("Zero"). } Perform a two way test. Use an if else if construct. 1=Mon. For examp e: if (n < 0) { Console::Write("Negative"). Define case branches for each va ue you want to test aga nst. } else { Console::Write("Positive"). } Chapter 5  Dec s on and oop statements   75 . } Perform a mu t way test. n--. Use the break statement to c ose a branch. etc. } else { Console::Write("Not negative"). Use the if keyword fo owed by a test enc osed n paren theses. You must enc ose the if body n braces f t con ta ns more than one statement.

.

wh ch be ong to the c ass as a who e You’ see how to define c ass members n th s chapter by us ng the static keyword F na y. t m ght create a new Employee object every t me a new emp oyee jo ns the company and a new Contract object to descr be the emp oyee’s terms of emp oyment Th s chapter bu ds on the ntroduct on to c asses and objects n Chapter 2 In th s chapter. a Human Resources app cat on m ght define c asses such as Employee and Contract When the app cat on s runn ng. and you create objects as nstances of these c asses For examp e. wh ch makes t poss b e for you to keep a c ean separat on between a c ass defin t on and ts mp ementat on You’ a so earn how to prov de constructors to n t a ze new objects when they’re created Most of the data members and member funct ons n a c ass are instance members because they be ong to spec fic nstances of the c ass It’s a so poss b e to define class members. you’ see how to create object re at onsh ps n C++ Th s concept s mportant n objector ented programm ng because t fac tates objects commun cat ng w th one another n a runn ng app cat on 77 . you will be able to: ■ Organ ze c asses nto header fi es and source fi es ■ Create objects ■ Define constructors to n t a ze an object ■ Define c ass-w de members by us ng the static keyword ■ Define re at onsh ps between objects n an app cat on C hapter 2. “Introduc ng object-or ented programm ng. you’ see how to organ ze c asses nto header fi es and source fi es.” d scusses how C++ s an object-or ented programm ng anguage Reca from that chapter that you define c asses to represent the mportant types of ent t es n your app cat on.CHAPTER 6 More about classes and objects After completing this chapter.

Organizing classes into header files and source files
Chapter 2 shows you how to define a s mp e c ass and mp ement a ts member funct ons n ne Let’s
refresh your memory by cons der ng the fo ow ng c ass, wh ch represents a cred t card account
ref class CreditCardAccount
{
public:
void PrintStatement()
{
Console::Write("Credit card balance: ");
Console::WriteLine(currentBalance);
}
private:
double currentBalance;
};

The CreditCardAccount c ass conta ns a s ng e member funct on named PrintStatement Th s funct on has been dec ared pub c, so t can be accessed by other parts of the app cat on The c ass a so
conta ns a s ng e data member named currentBalance, wh ch has been dec ared pr vate to preserve
encapsu at on
Not ce that the c ass defin t on conta ns the fu body of the PrintStatement funct on not just ts
prototype Th s s known as an inline function In ne funct ons are fine for sma funct ons but can
carry an overhead f used too much, and they can a so make the c ass defin t on hard to understand
Imag ne a c ass conta n ng 100 funct ons, a of wh ch are dec ared n ne The c ass defin t on wou d
be very ong, and t m ght be d fficu t to understand the structure of the code A common so ut on
n C++ s to d v de the c ass defin t on nto two parts a header fi e and a source fi e, as shown n the
fo ow ng figure

78  Microsoft Visual C++/CLI Step by Step

Note  You can use any file names you like for the header file and source file. Most developers use the same name as the class, with the standard file extensions .h (for the header file)
and .cpp (for the source file.)
The header fi e, Cred tCardAccount h, conta ns the class declaration Not ce that the c ass dec arat on now conta ns function prototypes rather than funct on bod es These prototypes make the header
fi e eas er to read because the funct on s gnatures are more prom nent
The source fi e, Cred tCardAccount cpp, conta ns the class definition, wh ch cons sts of a the funct on bod es for the c ass Each funct on must be prefixed by the name of the c ass to wh ch t be ongs,
fo owed by two co ons, as fo ows
void CreditCardAccount::PrintStatement()
{
... function body ...
}

The doub e-co on syntax ( ) s the C++ scope resolution operator In th s examp e, the scope reso ut on operator te s us that the PrintStatement funct on be ongs to the CreditCardAccount c ass
The reason for th s shou d be c ear How s the comp er to know that th s s the PrintStatement
funct on that s part of CreditCardAccount as opposed to some other PrintStatement funct on?

Note  You must provide an #include statement at the start of the source file to include the
header file for the class. For example, CreditCardAccount.cpp has an #include statement
to include CreditCardAccount.h. The compiler needs the information in this header file to
compile the function bodies in the source file, for example, to check that the spelling and
number of arguments in PrintStatement matches the declaration.

Declaring a class in a header file
In th s exerc se, you w create a new app cat on and define a CreditCardAccount c ass n a header
fi e  (You w mp ement the c ass n the exerc se that fo ows )
1. Start V sua Stud o 2012 and create a new CLR Conso e App cat on project named

CreditOrganizer
2. On the Project menu, c ck Add New Item
3. In the Add New Item d a og box, n the pane on the eft, se ect V sua C++ and then, n the

center pane, c ck Header F e ( h)
4. Toward the bottom of the d a og box, n the Name box, type CreditCardAccount.h, and then

c ck Add
V sua Stud o creates an empty header fi e

Chapter 6  More about c asses and objects   79

5. Type the fo ow ng code n the header fi e to define the CreditCardAccount c ass
ref class CreditCardAccount
{
public:
void SetCreditLimit(double amount);
bool MakePurchase(double amount);
void MakeRepayment(double amount);
void PrintStatement();
long GetAccountNumber();
private:
long accountNumber;
double currentBalance;
double creditLimit;
};

Every cred t card account has a un que account number, a current ba ance, and a cred t m t
The SetCreditLimit member funct on w be used to n t a ze the cred t m t for the account
You can use the MakePurchase member funct on to make a purchase on the cred t card Th s
funct on returns true f the purchase s a owed, or fa se f the purchase wou d cause the cred t
m t to be exceeded The MakeRepayment member funct on repays some or a of the outstand ng ba ance The PrintStatement member funct on d sp ays a statement for the account
And fina y, the GetAccountNumber member funct on returns the number for the account
6. Bu d the app cat on and fix any comp er errors

80  Microsoft Visual C++/CLI Step by Step

Implementing a class in a source file
In th s exerc se, you w

mp ement the CreditCardAccount c ass n a source fi e

1. Cont nue us ng the project from the prev ous exerc se
2. On the Project menu, c ck Add New Item
3. In the Add New Item d a og box, n the pane on the eft, se ect V sua C++ and then, n the

center pane, c ck C++ F e ( cpp)
4. Toward the bottom of the d a og box, n the Name box, type CreditCardAccount.cpp, and

then c ck Add
V sua Stud o creates an empty source fi e
5. Add two #include statements at the beg nn ng of the fi e, as fo ows
#include "stdafx.h"
#include "CreditCardAccount.h"

The fi e stdafx h s a header fi e that can nc ude other standard header fi es; you nc ude
stdafx h at the start of every source fi e n your project
Cred tCardAccount h conta ns the c ass defin t on for CreditCardAccount You nc ude th s
header fi e here so that the comp er can check your mp ementat on of the CreditCardAccount
c ass
6. Add the fo ow ng code so that you can use c asses and data types defined n the System

namespace
#using <mscorlib.dll>
using namespace System;

The #using <mscorlib.dll> preprocessor d rect ve mports the M crosoft Intermed ate Language (MSIL) fi e mscor b d so that you can use managed data and managed constructs
defined n th s brary fi e
The using namespace System statement he ps you to use c asses and data types defined n
the System namespace Spec fica y, you w use the Console c ass to d sp ay messages on the
conso e
7. Imp ement the CreditCardAccount::SetCreditLimit member funct on, as shown here
void CreditCardAccount::SetCreditLimit(double amount)
{
creditLimit = amount;
}

Chapter 6  More about c asses and objects   81

8. Imp ement the CreditCardAccount::MakePurchase member funct on as fo ows
bool CreditCardAccount::MakePurchase(double amount)
{
if (currentBalance + amount > creditLimit)
{
return false;
}
else
{
currentBalance += amount;
return true;
}
}

Th s funct on s ca ed when the card owner attempts to make a purchase by us ng the cred t
card The amount parameter nd cates the amount of the purchase The funct on tests whether
the purchase wou d exceed the creditLimit data member, return ng false f t wou d Otherw se,
the funct on adds the amount to the currentBalance data member and returns true

Note  Member functions have unrestricted access to all the members in the class,
including private members.
9. Imp ement the CreditCardAccount::MakeRepayment member funct on as fo ows
void CreditCardAccount::MakeRepayment(double amount)
{
currentBalance -= amount;
}

Th s funct on g ves the user the opportun ty to pay off some or a of the outstand ng ba ance
10. Imp ement the CreditCardAccount::PrintStatement member funct on as fo ows
void CreditCardAccount::PrintStatement()
{
Console::Write("Current balance: ");
Console::WriteLine(currentBalance);
}

Th s funct on d sp ays nformat on about the current state of the account
11. Imp ement the GetAccountNumber member funct on as fo ows
long CreditCardAccount::GetAccountNumber()
{
return accountNumber;
}

12. Bu d the app cat on and fix any comp er errors

82  Microsoft Visual C++/CLI Step by Step

Creating objects
After you have defined and mp emented a c ass, you are ready to beg n creat ng objects
The fo ow ng code shows how to create an object and ca
CreditCardAccount ^myAccount;
myAccount = gcnew CreditCardAccount;
myAccount->MakePurchase(100);

//
//
//
//
//

ts pub c member funct ons

Declare a handle
Create a new
CreditCardAccount object
Use the -> operator to invoke
member functions

myAccount->MakeRepayment(70);
myAccount->PrintStatement();
...

The gcnew operator creates a new object of the CreditCardAccount c ass and returns a hand e to
th s new object The hand e s used w th the -> operator to nvoke member funct ons on the new
object

Note  If you forget to delete an object of a managed class, the garbage collector is responsible for disposing of it. In Chapter 7, “Controlling object lifetimes,” you can see how this
works as well as how you can work with the garbage collector to ensure that your objects
are tidied up correctly at the end of their lives.
In th s exerc se, you w create a new CreditCardAccount object, nvoke ts member funct ons, and
de ete the object when t s no onger requ red
1. Cont nue us ng the project from the prev ous exerc se
2. If the fi e Cred tOrgan zer cpp s not v s b e n the ed tor w ndow, find the fi e n the So ut on

Exp orer, and then doub e-c ck the name to d sp ay t n the ed tor
3. Just after the #include “stdafx.h” ne, add another #include d rect ve as fo ows
#include "CreditCardAccount.h"

Th s ne makes t poss b e for you to create and use CreditCardAccount objects n th s source
fi e
Rep ace the body of the main funct on w th the fo ow ng code
CreditCardAccount ^myAccount;
// Declare a handle
myAccount = gcnew CreditCardAccount; // Create a new CreditCardAccount object
myAccount->SetCreditLimit(1000);
myAccount->MakePurchase(1000);
// Use the -> operator to invoke member functions
myAccount->MakeRepayment(700);
myAccount->PrintStatement();
long num = myAccount->GetAccountNumber();
Console::Write("Account number: ");
Console::WriteLine(num);

Chapter 6  More about c asses and objects   83

4. Bu d the app cat on and fix any comp er errors
5. Run the app cat on by press ng Ctr +F5

The app cat on creates a CreditCardAccount object, makes a purchase and a repayment, and
pr nts a statement However, the account number d sp ays as zero, as ustrated n the fo owng screen shot

The reason for th s s because the members of the CreditCardAccount object are n t a zed to zero
when t’s created However, t doesn’t rea y make sense to have an account w thout a number, so we’d
ke to ensure that every account s created w th an account number
You do th s by defin ng a constructor n the CreditCardAccount c ass The constructor s a member
funct on that n t a zes new objects when they’re created Chapter 7 shows you how to t dy up objects
just before they are destroyed

Initializing objects by using constructors
In th s sect on, you w

see how to define constructor funct ons for a c ass

Defining constructors
A constructor s a spec a member funct on that s ca ed automat ca y when an object s created The
purpose of the constructor s to n t a ze the object to br ng t nto an operat ona state You dec are
the prototype for the constructor n the c ass defin t on The fo ow ng examp e dec ares a s mp e
constructor for the CreditCardAccount c ass
ref class CreditCardAccount
{
public:
CreditCardAccount();
// ... Other members, as before
};

84  Microsoft Visual C++/CLI Step by Step

There are severa mportant po nts to not ce here F rst, a constructor must have the same name as
the c ass; th s s how the comp er recogn zes t as a constructor A so, a constructor cannot spec fy a
return type—not even void If you do spec fy a return type for a constructor, you w get a comp er
error
You can mp ement the constructor n the source fi e as fo ows
CreditCardAccount::CreditCardAccount()
{
accountNumber = 1234;
currentBalance = 0;
creditLimit = 3000;
}

Note  Although this example has set all three fields, the compiler will arrange for fields
to be set to a default value. This is zero for numeric types, false for Booleans, and a “null”
value for handles.
Th s s mp e constructor n t a zes every new CreditCardAccount object w th the same va ues A
more rea st c approach s to define a constructor that takes parameters so that each object can be
n t a zed w th d fferent va ues

Note  You can provide any number of constructors in a class, as long as each constructor
has a distinct parameter list. This is an example of function overloading.
In th s exerc se, you w add a constructor to the CreditCardAccount c ass The constructor takes
two parameters spec fy ng the account number and cred t m t for the new account The current ba ance s a ways n t a zed to 0 for each new account, so there s no need to supp y a parameter for th s
data member
1. Cont nue us ng the project from the prev ous exerc se
2. Open Cred tCardAccount h and dec are a pub c constructor as fo ows
ref class CreditCardAccount
{
public:
CreditCardAccount(long number, double limit);
// ... Other members, as before
};

Tip  Ensure that the constructor is public. If you make it private by mistake, you
won’t be able to create CreditCardAccount objects in your application.

Chapter 6  More about c asses and objects   85

3. Open Cred tCardAccount cpp and mp ement the constructor as fo ows
CreditCardAccount::CreditCardAccount(long number, double limit)
{
accountNumber = number;
creditLimit = limit;
currentBalance = 0.0;
}

4. Open Cred tOrgan zer cpp and mod fy the statement that creates the CreditCardAccount

object as fo ows
myAccount = gcnew CreditCardAccount(12345, 2500);

Th s statement creates a new CreditCardAccount object and passes the va ues 12345 and 2500
nto the CreditCardAccount constructor The constructor uses these parameter va ues to n t a ze the accountNumber and creditLimit data members, respect ve y
5. Bu d the app cat on, fix any comp er errors, and then run the app cat on

The app cat on now d sp ays mean ngfu nformat on for the account number, as demonstrated n the fo ow ng screen shot

Member initialization lists
There’s an a ternat ve syntax for n t a z ng data members n a constructor us ng a member n t a zat on st, as fo ows
CreditCardAccount::CreditCardAccount(long number, double limit)
: accountNumber(number), creditLimit (limit), currentBalance(0.0)
{
}

86  Microsoft Visual C++/CLI Step by Step

The co on on the second ne s fo owed by a comma-separated st of data members For each
data member, an n t a va ue s prov ded n parentheses Observe that the body of the constructor s
now empty because we have noth ng e se to do—th s s qu te norma
It s cons dered better pract ce to use a member n t a zat on st rather than n t a z ng members
n the constructor body There are a so some s tuat ons n wh ch you must use a member n t a zat on
st You’ see such an examp e n Chapter 8, “Inher tance,” when you de ve nto that subject

Defining class-wide members
The data members and member funct ons current y defined n the CreditCardAccount c ass are nstance members Each CreditCardAccount nstance has ts own accountNumber, currentBalance, and
creditLimit L kew se, when you nvoke member funct ons such as MakePurchase, MakeRepayment,
and PrintStatement, you must spec fy wh ch CreditCardAccount nstance you’re us ng, as shown n the
fo ow ng figure

W th C++, you can a so define c ass-w de members that og ca y be ong to the ent re c ass rather
than to a spec fic nstance For examp e, you can define a c ass-w de data member named interestRate
that ho ds the nterest rate for a accounts S m ar y, you can prov de c ass-w de member funct ons
ca ed SetInterestRate and GetInterestRate to work w th the nterest rate, as shown n the fo ow ng
figure

Chapter 6  More about c asses and objects   87

if you do not initialize numberOfAccounts explicitly. use the static keyword.. as before }. // . // Declare class-wide data member Th s dec arat on nforms the comp er that there s a c ass-w de data member named numberOf Accounts and n t a zes t to zero Note  Like any other member of a class. Cont nue us ng the project from the prev ous exerc se 2. Open Cred tCardAccount h and dec are the stat c numberOfAccounts data member as fo ows class CreditCardAccount { private: 88  Microsoft Visual C++/CLI Step by Step .Let’s see how to define c ass-w de data members and member funct ons Defining class-wide data members To define a c ass-w de data member. In th s exerc se. Other members. you w add a stat c numberOfAccounts data member to the CreditCardAccount c ass You w ncrement th s data member every t me a new CreditCardAccount object s created 1.. the default initial value will be 0. as demonstrated n the fo ow ng code ref class CreditCardAccount { private: static int numberOfAccounts = 0.

creditLimit = limit. } 4. Console::WriteLine(numberOfAccounts). CreditCardAccount ^account1. account1->PrintStatement().0. Bu d the app cat on.. Console::WriteLine("\nCreating second object"). 3. Other members. 5. Console::Write("This is account number "). Open Cred tCardAccount cpp and mod fy the CreditCardAccount constructor so that t ncre- ments numberOfAccounts every t me a new CreditCardAccount object s created CreditCardAccount::CreditCardAccount(long number. the app cat on ncrements numberOf Accounts and d sp ays ts atest va ue Chapter 6  More about c asses and objects   89 . account2 = gcnew CreditCardAccount(67890. as before }. CreditCardAccount ^account2. account2->PrintStatement(). currentBalance = 0. fix any comp er errors. 5000). numberOfAccounts++. account1 = gcnew CreditCardAccount(12345. account2->MakePurchase(750). 2000). and then run the app cat on Every t me a new CreditCardAccount object s created.. // .static int numberOfAccounts = 0. account1->MakePurchase(300). double limit) { accountNumber = number. Open Cred tOrgan zer cpp and mod fy the ma n funct on so that t creates and uses severa CreditCardAccount objects Console::WriteLine("Creating first object").

Defining class-wide member functions It can be dangerous to make data members pub c. use the static keyword n the funct on dec arat on ke th s ref class CreditCardAccount { public: static int GetNumberOfAccounts(). use the c ass name rather than a part cu ar nstance. To ca a stat c member funct on. currentBalance. as shown n th s examp e int n = CreditCardAccount::GetNumberOfAccounts(). Cont nue us ng the project from the prev ous exerc se 2... Open Cred tCardAccount h and dec are the GetNumberOfAccounts funct on as fo ows 90  Microsoft Visual C++/CLI Step by Step . Imp ement the funct on n the source fi e to match the code sn ppet that fo ows Keep n m nd that you don’t use the static keyword on the mp ementat on. preferab y. GetNumberOfAccounts can access numberOfAccounts. you use a statement such as Console::WriteLine(“Hello world”). The use of the c ass name emphas zes the fact that GetNumberOfAccounts s a c ass-w de member funct on rather than an nstance member funct on Note  You have seen the syntax ClassName::FunctionName before. For example. This statement calls the static member function WriteLine on the Console class. but it cannot access accountNumber. a static member function can only access static class members. // . you can define a stat c member funct on To define a c ass-w de member funct on. you w define a stat c GetNumberOfAccounts member funct on n the Credit CardAccount c ass You w then ca th s funct on severa t mes n main 1. or creditLimit. In th s exerc se. Other members. } Note  Because it is not associated with an instance but with the class as a whole. Every time you display a message on the console. as before }. because they are part of an instance. you want to g ve users access through member funct ons To g ve access to a stat c data member. but on y on the dec arat on ns de the c ass defin t on int CreditCardAccount::GetNumberOfAccounts() { return numberOfAccounts.

account1->PrintStatement(). 5. Console::Write("Number of accounts initially: "). account2->PrintStatement(). CreditCardAccount ^account1. Bu d the app cat on. Console::Write("\nNumber of accounts now: "). } 4. Console::WriteLine("\nCreating first object"). Console::WriteLine(n). account2->MakePurchase(750).. account1->MakePurchase(300). Console::WriteLine(n). fix any comp er errors. Other members. and then run the app cat on The app cat on d sp ays the messages dep cted n the fo ow ng screen shot Chapter 6  More about c asses and objects   91 . 3. Open Cred tCardAccount cpp and mp ement the GetNumberOfAccounts funct on as fo ows int CreditCardAccount::GetNumberOfAccounts() { return numberOfAccounts. account2 = gcnew CreditCardAccount(67890. 5000).. // . Open Cred tOrgan zer cpp and mod fy the ma n funct on so that t ca s GetNumberOf Accounts at var ous stages dur ng execut on int n = CreditCardAccount::GetNumberOfAccounts(). CreditCardAccount ^account2. as before }. account1 = gcnew CreditCardAccount(12345.ref class CreditCardAccount { public: static int GetNumberOfAccounts(). Console::WriteLine("\nCreating second object"). n = CreditCardAccount::GetNumberOfAccounts(). 2000).

.Class constructors Suppose that you have a c ass-w de member but you cannot g ve t a va ue unt run t me For examp e. a stat c constructor s used to do once-only initialization for a c ass You use them to do any setup that s needed before your c ass s used... C++/CLI embod es the concept of a static constructor An ord nary constructor s used to n t a ze nstance members when an object s created. 3. } . You can eas y rewr te the CreditCardAccount c ass so that s uses a stat c constructor to n t a ze an interestRate member 1.5. stat c constructors have the static mod fier and do not take any arguments ref class MyClass { public: static MyClass() { . and no return type In add t on. Add the dec arat on for a stat c constructor n the pub c sect on of the c ass dec arat on static CreditCardAccount(). } Be aware that you need the static keyword here You don’t norma y use static outs de the c ass dec arat on. but n th s case t s needed so that the comp er can determ ne that th s s the stat c constructor 92  Microsoft Visual C++/CLI Step by Step .. Open Cred tCardAccount h and add a dec arat on for a pr vate member ca ed interestRate static double interestRate. Console::WriteLine("Static constructor called"). and t s guaranteed to run before the c ass s used Th s means that t s ca ed before any objects of that type are created or before any stat c members of the c ass are used It s as f the comp er makes sure that the stat c constructor s ca ed the first t me t meets a ment on of the name CreditCardAccount A stat c constructor s ke a norma constructor t has the same name as the c ass. Open Cred tCardAccount cpp and add the mp ementat on of the stat c constructor The ca to WriteLine w he p you see when the constructor s ca ed static CreditCardAccount::CreditCardAccount() { interestRate = 4. }. Cont nue us ng the project from the prev ous exerc se 2. you want to set the nterest rate for the CreditCardAccount c ass to the current rate at the t me the app cat on starts Un ke standard C++. 4.

The output from runn ng the app cat on appears as fo ows Static constructor called Number of accounts initially: 0 You can see from th s that the stat c constructor s ca ed mmed ate y before the first object s created Using constants in classes You w often find that you need to represent constant va ues n your c asses. Console::Write("Number of account initially:"). account1 = gcnew CreditCardAccount(12345. a Car c ass m ght have a numberOfWheels member that s common to every Car nstance and wh ch has a fixed va ue of 4 Those that are constant. as shown here literal String ^name = "Super Platinum Card". so t og ca y be ongs to the c ass rather than each nstance Let us further suppose that the name assoc ated w th the card c ass sn’t go ng to change Th s makes t a cand date for a c ass-w de constant You can create a c ass-w de constant by us ng the literal keyword. 2000). A literal can have an n t a va ue p aced n the c ass defin t on If you do th s. CreditCardAccount ^account1. t can’t depend on someth ng that w on y be known at run t me Chapter 6  More about c asses and objects   93 . t must be a va ue that the comp er can ca cu ate In other words.5. Console::WriteLine("\nCreating first object"). members whose va ue cannot change as execut on proceeds These constants m ght be of two types ■ ■ Those wh ch are constant and common to every object n the c ass For examp e. a BankAccount object has an account number. Bu d and run the app cat on Here s the code that you shou d have at the top of main int n = CreditCardAccount::GetNumberOfAccounts(). Console::WriteLine(n). but m ght be d fferent for each object For examp e. suppose that th s k nd of cred t card account has a name. th s s nd v dua to each nstance but cannot be changed after t has been set Using class-wide constants A c ass-w de constant represents a va ue that s common to a nstances of a c ass For our Credit Account examp e. such as “Super P at num Card ” Th s name w app y to a cards of the same type.

before you create any CreditCardAccount objects Console::Write("Card name is "). Bu d and run the app cat on to see the va ue of the name pr nted out Literals and const In standard C++.n types. 2.Let’s see how to add the name to the CreditAccount c ass 1. ref types. as requ red by initonly 94  Microsoft Visual C++/CLI Step by Step . Open Cred tAccount h and add initonly to the dec arat on of accountNumber initonly long accountNumber. we can make t public because there s no danger that anyone can mod fy t You can dec are tera s of bu t. Bu d the app cat on It shou d run exact y the same as before because you are sett ng the va ue for accountNumber n the constructor. Because name s a constant. you wou d use a static const member to represent a c ass-w de constant A though C++/CLI supports th s. constants dec ared n th s way are not recogn zed as comp et me constants f the c ass s accessed v a a #using statement Therefore.nstance constant A data member marked as initonly can have ts va ue set n the constructor for the c ass but cannot be mod fied after that The fo ow ng short exerc se shows you how to use initonly n the CreditCardAccount c ass 1. and va ue types 3. you do not have to have any nstances n ex stence n order to use t 4. You can access the tera through the c ass name Add the fo ow ng code to d sp ay the name to the start of main. you are recommended to use literal. because members dec ared n th s way behave as expected Using instance constants You can use the initonly keyword to mark a data member as per. Cont nue us ng the project from the prev ous exerc se 2. Because the name be ongs to the c ass. Console::WriteLine(CreditCardAccount::name). Open Cred tAccount h and add the dec arat on of a literal to the pub c sect on of the c ass dec arat on literal String ^name = "Super Platinum Card".

Cont nue us ng the project from the prev ous exerc se 2. t doesn’t have a LoyaltyScheme object The LoyaltyScheme object s created when CreditCardAccount reaches 50 percent of ts cred t m t Subsequent y. every $10 spent us ng the cred t card w add one bonus po nt to the LoyaltyScheme object.h. you w define the LoyaltyScheme c ass n a new header fi e named Loya tyScheme h 1. you w comp ete the fo ow ng exerc ses ■ Define the LoyaltyScheme c ass ■ Imp ement the LoyaltyScheme c ass ■ Create and use LoyaltyScheme objects ■ Test the app cat on Defining the LoyaltyScheme Class In th s exerc se. Remove th s ne of code before cont nu ng! Defining object relationships For the rema nder of th s chapter. and f you hover over the var ab e name. such as SetCreditLimit 4. and these objects commun cate w th one another to ach eve the overa funct ona ty needed n the app cat on To ustrate object re at onsh ps. c ck Add New Item 3. On the Project menu. cred t card owners can co ect bonus po nts when they use the r cred t card These po nts act as a reward for the customer’s oya use of the cred t card When a CreditCardAccount object s first created. In the Add New Item d a og box. Not ce that accountNumber s under ned n red.3. as ong as the account stays above the 50 percent mark To ach eve th s funct ona ty. type LoyaltyScheme. Open Cred tAccount cpp and try to ass gn a new va ue to accountNumber n one of the other member funct ons. se ect the temp ate Header F e ( h) In the Name box. a Too T p appears. you w add a new c ass named LoyaltyScheme to your cred t card app cat on W th the LoyaltyScheme c ass. you w see how to define re at onsh ps between objects n a C++/ CLI app cat on App cat ons typ ca y conta n many objects. and then c ck Add Chapter 6  More about c asses and objects   95 . nform ng you that the var ab e cannot be mod fied here 5.

Add the fo ow ng code to expose the System namespace #using <mscorlib.4. as shown here #include "stdafx. // Constructor amountSpent). In the Add New Item d a og box. private: int totalPoints. type LoyaltyScheme. c ck Add New Item 3. On the Project menu. and then c ck Add V sua Stud o creates an empty source fi e 4. Type the fo ow ng code n the header fi e to define the LoyaltyScheme c ass ref class LoyaltyScheme { public: LoyaltyScheme(). } 96  Microsoft Visual C++/CLI Step by Step .h" 5. you now qualify for" " bonus points").dll> using namespace System. void EarnPointsOnAmount(double void RedeemPoints(int points). 6. }. you w Loya tyScheme cpp mp ement the LoyaltyScheme c ass n a new source fi e named 1.h" #include "LoyaltyScheme. Bu d the app cat on and fix any comp er errors Implementing the LoyaltyScheme class In th s exerc se. se ect the temp ate C++ F e ( cpp) In the Name box. // Earn one point per $10 spent // Redeem points // Return the value of totalPoints // Total points earned so far 5. totalPoints = 0. Imp ement the LoyaltyScheme constructor as fo ows LoyaltyScheme::LoyaltyScheme() { Console::WriteLine("Congratulations. Cont nue us ng the project from the prev ous exerc se 2. Add two #include statements at the beg nn ng of the fi e. int GetPoints().cpp.

Imp ement the RedeemPoints member funct on as fo ows void LoyaltyScheme::RedeemPoints(int points) { if (points <= totalPoints) { totalPoints -= points. } else { totalPoints = 0. totalPoints += points. Cont nue us ng the project from the prev ous exerc se 2.7. Console::WriteLine(points). Imp ement the EarnPointsOnAmount member funct on as fo ows void LoyaltyScheme::EarnPointsOnAmount(double amountSpent) { int points = (int)(amountSpent/10). Open Cred tCardAccount h At the beg nn ng of the fi e. you w funct ona ty extend the CreditCardAccount c ass to support the oya ty scheme 1. Bu d the app cat on and fix any comp er errors Creating and using LoyaltyScheme objects In th s exerc se. Console::Write("New bonus points earned: "). Imp ement the GetPoints member funct on as fo ows int LoyaltyScheme::GetPoints() { return totalPoints. } } Th s funct on makes t poss b e for the user to redeem some or a of the accrued bonus po nts 9. add an #include d rect ve as fo ows #include "LoyaltyScheme. } The syntax (int)(amountSpent/10) d v des the amount spent by 10 and converts the va ue to an int 8. } 10.h" Th s makes t poss b e for you to use the LoyaltyScheme c ass n th s header fi e Chapter 6  More about c asses and objects   97 .

the scheme object won’t be created unt the cred t card ba ance reaches 50 percent of the cred t m t Note  There is a big difference between not initializing the scheme handle at all and initializing it to nullptr. 6. you ca RedeemLoyaltyPoints on your CreditCard Account object Th s funct on ca s RedeemPoints on the under y ng LoyaltyScheme object to do the work Note  Relying on another object to do some work for you is an example of delegation. // If current balance is 50% (or more) of credit limit. it is good practice to explicitly initialize handles to null. The CreditCardAccount object delegates the management of loyalty points to the LoyaltyScheme object. Open Cred tCardAccount cpp and find the CreditCardAccount constructor Add the fo ow ng statement n the constructor body scheme = nullptr. Although the compiler is good at detecting attempts to use uninitialized variables. Add a pr vate data member to the CreditCardAccount c ass as fo ows LoyaltyScheme ^scheme. Mod fy the MakePurchase funct on to match the code that fo ows to co ect bonus po nts when the cred t card ba ance reaches 50 percent of the cred t m t bool CreditCardAccount::MakePurchase(double amount) { if (currentBalance + amount > creditLimit) { return false. Th s funct on acts as a wrapper to the RedeemPoints funct on n the LoyaltyScheme c ass When you want to redeem oya ty po nts. } else { currentBalance += amount. Th s statement sets the n t a va ue of the scheme hand e to nullptr Th s s a spec a va ue for a hand e. // Handle to a LoyaltyScheme object Th s hand e represents an assoc at on between a CreditCardAccount object and a LoyaltyScheme object 4. Add a pub c member funct on to the CreditCardAccount c ass as fo ows void RedeemLoyaltyPoints(). if (currentBalance >= creditLimit / 2) 98  Microsoft Visual C++/CLI Step by Step .. 5. nd cat ng that the hand e doesn’t yet po nt to an object In our app cat on.3..

} else { // Tell the user how many points are currently available Console::Write("Points available: "). } } return true. if (scheme == nullptr) { // Display an error message Console::WriteLine("Sorry. } } Chapter 6  More about c asses and objects   99 . Console::Write(". you do not have a " "loyalty scheme yet").. // Tell the user how many points are left Console::Write("Points remaining: "). if (scheme == nullptr) { // Create it scheme = gcnew LoyaltyScheme(). int points = Convert::ToInt32(input). Console::WriteLine( scheme->GetPoints() ). // Redeem the points scheme->RedeemPoints(points). Imp ement the RedeemLoyaltyPoints funct on as shown n the code that fo ows Redeem LoyaltyPoints s a new member funct on by wh ch the user can redeem some or a of the oya ty po nts n the assoc ated LoyaltyScheme object void CreditCardAccount::RedeemLoyaltyPoints() { // If the LoyaltyScheme object doesn't exist yet. // Ask the user how many points they want to redeem String ^input = Console::ReadLine().. Console::Write( scheme->GetPoints() ). // so accrue bonus points scheme->EarnPointsOnAmount(amount).. } else { // LoyaltyScheme already exists.{ // If LoyaltyScheme object doesn't exist yet.. How many points do you want " " to redeem? "). } } 7.

Cont nue us ng the project from the prev ous exerc se 2. account1->MakePurchase(500). 2000). account1->RedeemLoyaltyPoints(). Console::WriteLine("\nMaking a purchase (300)").Note  It’s important to check the value of the scheme handle before you use it. your application will crash at run time. account1->MakePurchase(700).000. Console::WriteLine("\nMaking a purchase (500)"). 8. a LoyaltyScheme object s created Subsequent purchases co ect a oya ty po nt for every $10 spent When you try to redeem oya ty po nts. This is a very common error in C++ applications. account1 = gcnew CreditCardAccount(12345. Console::WriteLine("\nRedeeming points"). CreditCardAccount ^account1. Console::WriteLine("\nMaking a purchase (700)"). Bu d the app cat on and fix any comp er errors 4. Bu d the app cat on and fix any comp er errors Testing the application In th s exerc se. 3. account1->MakePurchase(300). Open Cred tOrgan zer cpp and mod fy the main funct on as fo ows Console::WriteLine("Creating account object"). If you forget to check the value and the handle is still null. Run the app cat on The app cat on creates a CreditCardAccount object and makes var ous purchases When the cred t card ba ance reaches $1. you w mod fy the code n Cred tOrgan zer cpp to test the oya ty scheme funct ona ty 1. the app cat on nforms you of how many po nts are ava ab e and asks how many you want to redeem Type a va ue such as 36 and press Enter The app cat on d sp ays how many po nts are eft The fo ow ng screen shot shows the messages d sp ayed on the conso e dur ng the app cat on 100  Microsoft Visual C++/CLI Step by Step .

}. Add a header fi e to your project. n the source fi e. Then mp ement the member funct ons n the source fi e. Define the c ass n the header fi e. } Chapter 6  More about c asses and objects   101 . mp ement a c ass. and mp ement t n the source fi e. } Prov de a constructor for a c ass. use a #include statement to nc ude the header fi e that con ta ns the c ass defin t on. . // Source file MyClass::MyClass(int n) { myData = n. }. For examp e: #include "MyHeader. private: int myData..Quick reference To Do this Define a c ass.h" void MyClass::MyFunction() { myData = myData * 2. a constructor can take parameters. Add a source fi e to your project. The constructor must have the same name as the c ass and cannot return a va ue. Dec are the constructor n the header fi e. For examp e: // Header file ref class MyClass { public: MyClass(int n). However. For examp e: ref class MyClass { public: void MyFunction()..

.

the runt me s respons b e for ensur ng that memory from dead objects s rec a med The component that does th s s ca ed the garbage collector The runt me keeps track of hand es to objects. t’s t me to earn how to contro object fet mes as we as another way to create and use objects The . you w ■ be ab e to Descr be how M crosoft NET memory management d ffers from trad t ona C++ memory management ■ Prov de fina zers and destructors for your c asses ■ Create objects by us ng stack semant cs N ow that you know how to create objects n C++/CLI by us ng the gcnew operator. th s s up to the garbage co ector 103 . but what happens when an object s no onger requ red? There are two th ngs that need to happen when an object comes to the end of ts fe ■ ■ You m ght want to do some c ean-up before the object s destroyed. and when an object can no onger be referenced through any hand e. such as wr t ng data back to a database The object’s memory needs to be rec a med by the runt me Let’s see how th s s done n C++/CLI In NET. because that’s the way that the system keeps track of them ■ An object w a ways be ava ab e as ong as there s at east one hand e to t ■ You cannot te when an object’s memory w be rec a med.CHAPTER 7 Controlling object lifetimes After comp et ng th s chapter.NET approach to object lifetimes We’ve seen what happens at the start of an object’s fe. ke Java and many other modern anguages. t s unreachab e and s a cand date for garbage co ect on Th s means that programmers need to keep severa th ngs n m nd ■ Objects are a ways used through hand es.

fo ow any hand es to other objects that they m ght have Th s repeats to the end of each cha n of objects When a the ve objects have been marked. t’s not qu te that s mp e Garbage co ect on s expens ve and affects the operat on of your app cat ons. compact ng them to create the max mum amount of free space ■ F x up the hand es to the ve objects so that they po nt to new ocat ons Th s shou d exp a n why you refer to objects by us ng hand es not on y does t et the runt me track what s us ng an object. and t’s poss b e that at some po nt heap memory w be exhausted. an area of memory that the NET runt me uses to store dynam ca y a ocated objects Every a ocat on takes some space from the heap.. and others that ve for a ong t me Th s ed them to the dea of generations Every dynam ca y created NET object be ongs to a generat on.NET garbage collection The garbage co ect on mechan sm n the NET Framework s very soph st cated. t a so so ates the user from where exact y n memory the object s r ght at the moment In rea ty. the garbage co ector w be nvoked to see f there are any unreferenced objects whose memory can be rec a med to free up some heap memory The bas c process s as fo ows ■ ■ F nd a the objects that are st a ve Th s means start ng w th hand es to objects n the code Then. f generat on 0 fi s up. the onger t s ke y to ve In other words.ved objects can be eft a one 104  Microsoft Visual C++/CLI Step by Step . f you’re nterested to know a tt e more about what’s happen ng. but you don’t need to know much about the deta s to use C++/CLI In fact. t’s des gned to work fine w thout any ntervent on from you at a However. the garbage co ector runs on the generat on 0 objects on y Any objects that surv ve th s co ect on are promoted to generat on 1. and generat on 0 s c eared ready for more new objects M crosoft’s observat on was that many objects ve and d e n generat on 0. app cat ons tend to have a ot of objects that come and go rap d y. so t’s best to not run a co ect on on the who e of memory f you don’t have to When des gn ng NET. or (more ke y) there won’t be a p ece arge enough for the new a ocat on If a request for memory fa s. M crosoft d scovered an nterest ng fact the onger an object ves. no more new objects can be created At th s po nt. and each generat on has ts own area of the managed heap Objects be ong to generat on 0 when they are created. so onger. read on Memory for objects s a ocated from the managed heap. assume that a the rest of memory s garbage ■ Move the ve objects.

as you w see n the fo ow ng sect ons Destructors A destructor s executed when you no onger need an object To prov de a destructor for a c ass. thus. you can run a defau t co ect on or spec fy a part cu ar generat on If you’re nterested n find ng out to wh ch generat on a part cu ar object be ongs to. 1. f you are work ng w th a Customer object.At present. but you can use the System::GC::Collect stat c method to force a co ect on f you know you’ have a ot of rec a mab e objects n your code W th Collect. et’s ntroduce two new terms Finalization s what happens when an object’s memory s about to be rec a med and s under the contro of the garbage co ector You can prov de code to be executed at th s po nt. n the form of a finalizer method on your c ass But t m ght be that you know defin te y at some po nt n the code that you no onger need the object. and you can prov de a destructor method n your c ass W th C++/CLI. you m ght want the object to save ts data back to the database when you’ve finshed w th t Th s s ca ed destruction. At th s po nt n the code the destructor s ca ed. the NET garbage co ector has three generat ons (0. and 2) You usua y et the garbage co ector dec de when to perform a co ect on and wh ch generat on to co ect. and you wou d ke t to t dy tse f up there and then For examp e. ~MyClass(). pass ng n an object reference Destruction and finalization Before we can start ook ng at code. // constructor // destructor You can s gna that you no onger need an object by ca ng delete on a hand e to the object // Create an Account Account ^acc = gcnew Account(). you can prov de code to be executed at both these po nts n an object’s fecyc e. add a member funct on that has the same name as the c ass but s preceded by a t de character (~) ref class MyClass { public: MyClass(). }. you can use the System::GC::GetGeneration method. // Use the Account // We no longer need the Account delete acc. you know exact y where and when the object has ceased to operate Chapter 7  Contro ng object fet mes   105 .

objects that don’t have the r fina zers ca ed m ght not get a chance to c ean up proper y 106  Microsoft Visual C++/CLI Step by Step . no guarantee s made as to the order n wh ch fina zers w run. both have a fina zer. add ng an empty funct on to a c ass w have tt e effect. they have the same name as the c ass and don’t have a return type or take arguments A few points about finalizers There are three th ngs that you shou d be aware of when us ng fina zers F rst. w ndow hand es. }. you m ght not be ab e to destroy objects of that type Finalizers F na zers are ca ed when the garbage co ector fina y rec a ms the object’s memory You w need a fina zer f you have unmanaged resources.Here are three po nts you shou d note about destructors ■ L ke the constructor. wh ch means they cannot be over oaded ■ Destructors are usua y pub c members of a c ass If you make them pr vate. wh ch cou d cause a prob em And th rd. and t s an error to g ve them one ■ They do not take any arguments. don’t define a fina zer for your c ass f you don’t have anyth ng for t to do In most cases. such as po nters to unmanaged c asses. t knows that t has to run th s before rec a m ng objects of that type. // constructor // finalizer You can see that fina zers obey the same ru es as destructors. they have no return type. !MyClass(). fina zers aren’t ca ed dur ng app cat on term nat on for objects that are st ve. A and B. and so on If you don’t have any of those—and you’ on y tend to do that when you are work ng w th unmanaged code—you probab y don’t need a fina zer A fina zer s a member funct on that has the same name as the c ass but s preceded by an exc amat on mark (!) ref class MyClass { public: MyClass(). graph c dev ce contexts. such as those be ng used by background threads or those created dur ng the execut on of a fina zer A though a system resources w be freed up when the app cat on ex ts. but that sn’t the case for fina zers If the garbage co ector sees that your c ass mp ements a fina zer. fi e hand es. wh ch can be prob emat c f objects have dependenc es on one another Suppose that two objects. but you can’t know wh ch one w be ca ed first Th s means that you can’t determ ne n what order data w be wr tten to the data resource. and that both of them update a data resource Both fina zers w be ca ed when the objects are destroyed. and th s s ows down the co ect on process Second.

and then.h #include "stdafx. On the Project menu. in the shortcut menu that appears. c ck Header F e ( h) 4. n the center pane. you w find that you can norma y do whatever c eanup you requ re n the destructor Implementing the destructor and finalizer for a class In th s exerc se. Toward the bottom of the d a og box. In the Add New Item d a og box. type MyClass. a destructor.h.Th s m ght g ve you the mpress on that fina zers shou d be avo ded A though they are usefu n some s tuat ons. n the Name fie d. but th s t me add a source fi e ca ed MyClass. } Chapter 7  Contro ng object fet mes   107 . a fina zer. and then c ck Add Note  Another way that you can open the Add New Item dialog box is to right-click the project name in Solution Explorer and then. Imp ement the constructor so that t stores the name n the data member and pr nts a mes- sage to show that has been ca ed MyClass::MyClass(String ^objectName) { name = objectName. name). point to Add. }. n the pane on the eft.h" using namespace std. Open the header fi e and add the dec arat on for a c ass that has a constructor. Console::WriteLine("Constructor called for {0}". void DoSomething(). ~MyClass(). and then click New Item. #include "MyClass. c ck Add New Item 3. // // // // constructor destructor finalizer 'work' method 6.h and MyClass. you w see how to create and use the fina zer and destructor for a c ass 1.cpp to the project Open the fi e and add #include statements for stdafx. wh ch you w ca to show that the object can be used using namespace System. Repeat steps 2 through 4. ref class MyClass { String ^name. Start V sua Stud o 2012 and create a new CLR Conso e App cat on ca ed Lifetimes 2.h" 7. 5. and a s ng e work method. public: MyClass(String ^objectName). se ect V sua C++. !MyClass().

as shown here #include "MyClass. name). The string should be followed by a list of items that you want to print out. name).h. Imp ement the fina zer to pr nt a message to show that t has been ca ed MyClass::!MyClass() { Console::WriteLine("Finalizer called for {0}". such as {0} and {1}. Console::WriteLine().h" int main(array<System::String^>^ args) { MyClass ^m1 = gcnew MyClass("m1"). create an object by us ng gcnew. and then ca DoSomething Remember to add a #include for MyClass. The first item will be output in place of {0}. Cont nue us ng the project from the prev ous exerc se 2. and so on. Console::WriteLine(). you have used multiple Write and WriteLine statements to build up a line of output. Imp ement the DoSomething method to pr nt out a message Th s s to show that the object has been used between creat on and destruct on void MyClass::DoSomething() { Console::WriteLine("DoSomething called for {0}". the second in place of {1}. Open L fet mes cpp and n the main method of the app cat on. } 10. Console::WriteLine("End of program"). This exercise introduces a more efficient way: call WriteLine or Write with a string that contains text and markers that consist of a number in braces. } 11. Imp ement the destructor to pr nt a message to show that has been ca ed MyClass::~MyClass() { Console::WriteLine("Destructor called for {0}". m1->DoSomething(). } 108  Microsoft Visual C++/CLI Step by Step . return 0. We will use this from now on to save typing (and paper!).Note  Up to this point. name). 8. } 9. Bu d the project and fix any comp er errors Using the finalizer In th s exerc se you w see how the fina zer for a c ass s ca ed 1.

and t s the bas s of many common C++ cod ng d oms You shou d make a hab t of ca ng delete on your object hand es when you no onger need them We a so saw that as a resu t of ca ng delete. the fina zer wasn’t executed The garbage co ector dec des that you have dea t w th the d sposa of an object f ts destructor has been executed. Cont nue us ng the project from the prev ous exerc se 2. ts constructor s ca ed If the app cat on fin shes and the object hasn’t been destroyed. you shou d ca t from the destructor to ensure that a unmanaged resources are freed up no matter how your objects ex t Chapter 7  Contro ng object fet mes   109 . Ed t the code so that you exp c t y de ete the object after us ng t Do th s by nsert ng a ca to delete after the ca to DoSomething MyClass ^m1 = gcnew MyClass("m1"). Bu d and run the app cat on Output s m ar to the fo ow ng appears Constructor for m1 DoSomething called End of Program Finalizer called for m1 When you create an object. the fina zer was not ca ed at the end of the app cat on The destructor be ng ca ed when you ca delete means that you have comp ete contro over when objects t dy themse ves up Th s deterministic destruction s a ha mark of trad t ona C++. Bu d and run the app cat on Output s m ar to the fo ow ng appears Constructor called for m1 DoSomething called for m1 Destructor called for m1 End of Program Not ce that two th ngs have happened first. and so t doesn’t need to execute ts fina zer Th s means that f you do have a fina zer. m1->DoSomething(). delete m1. the destructor has been ca ed at the po nt where you ca ed de ete.3. second. the garbage co ector w ca the fina zer to c ear up any unmanaged resources assoc ated w th the object Using the destructor In th s exerc se you w see how the destructor for a c ass s ca ed 1. 3.

m.MyClass::~MyClass() { // Free up managed resources: this will be done anyway by the runtime // Now call the finalizer to free unmanaged resources this->!MyClass() } Objects and stack semantics It m ght seem rather ted ous to have to create objects by us ng gcnew and then ca delete on the hand es when you have fin shed us ng them After a .DoSomething(). ts destructor s ca ed automat ca y at the end of the b ock of code Th s s shown n the fo ow ng code samp e { } MyClass m("m3"). but the mechan sm s very s m ar There s. wh ch you can then ca by us ng delete Traditional C++ object creation and destruction Trad t ona C++ objects can a so have destructors and be dynam ca y created and destroyed n a manner very s m ar to the one to wh ch you have become accustomed They use new nstead of gcnew. You can see two d fferences from C++/CLI code here The more obv ous of them s that you don’t use gcnew and you don’t create a hand e Th s syntax creates an object ca ed m. another way by wh ch objects can be created n standard C++. m. such as ustrated n the fo ow ng MyClass m("m3"). the two are ndependent of one another You m ght want to say what an object does to t dy up when you have fin shed w th t but not rea y care when the garbage co ector dec des to rec a m ts memory In th s case. you wou d mp ement a destructor.DoSomething(). and that s to create them on the stack as oca objects. apart from t tak ng s ght y ess typ ng When you create an object n th s manner. wasn’t the dea of garbage co ect on supposed to be that you d dn’t have to keep track of your objects when you fin shed w th them? It s mportant not to confuse the concept of an object t dy ng up after tse f w th the runt me rec a m ng the object’s memory. // Destructor for m is called here Such objects are somet mes ca ed automatic objects because they are automat ca y destroyed when they go out of scope 110  Microsoft Visual C++/CLI Step by Step . however. and the constructor parameters are passed after the object name n the same way as they were passed to gcnew when creat ng an object dynam ca y The second obv ous d fference s that members of the object are accessed by us ng the dot operator ( ) rather than -> There s one mportant consequence to creat ng objects n th s way.

Note  In C++. you shou d see output s m ar to the fo ow ng Constructor called for m2 DoSomething called for m2 End of Program Destructor called for m2 You create and use the object. Th s s a huge benefit to programmers you can create an object and then know exact y where and when t w be destroyed and t dy tse f up w thout the need for you to ca delete In standard C++ these objects are created n an area of memory ca ed the stack. Ed t the main funct on by add ng code to create and use another object.DoSomething(). This notation is a convenience that makes it possible for you to work with objects in the traditional C++ way. so it goes out of scope at the final brace. For those types you must use gcnew to get a handle. In this case. you can create your objects n the same way. Chapter 7  Contro ng object fet mes   111 . 3. but you cannot do this for Strings or arrays. and so we say that these objects exh b t stack semantics Creating objects with stack semantics In C++/CLI. It is often related to an object’s lifetime. scope refers to where in the code an object is visible. and you access the objects by using the -> operator. our objects are still created and managed by using handles. these objects are not actually declared on the stack. Cont nue us ng the project from the prev ous exerc se 2. m2. as you w see n the next exerc se Note  In C++/CLI. p ac ng t before the “end of program” WriteLine ca s Ensure that you create th s object by us ng stack semant cs MyClass m2("m2"). but do not manua y de ete t The destructor s ca ed automat ca y when execut on passes the end cur y bracket n the funct on Note  You can create most types of objects by using stack semantics. m cannot be seen outside the block. 1. but under the hood. Bu d and run the app cat on After the output for m1.

You can now recode DoLongOperation to match the fo ow ng void DoLongOperation() { BusyCursorHelper bch().. you can be certa n that the match ng act on w be performed w thout you hav ng to remember to do t Here’s an examp e suppose that you want to change the cursor to an hourg ass before startng a ong-runn ng operat on and then revert to the arrow cursor upon comp et on You cou d code t up ke th s void DoLongOperation() { SetCursorToHourglass(). // Lots of complex code. one that s usefu n many c rcumstances You w find that you often want an object to do someth ng when you create t and then do a match ng act on when the object d es For examp e. and the user becomes annoyed One so ut on s to create a sma he per c ass Th s carr es out one task t sets the cursor to an hourg ass n ts constructor and then sets t back to the arrow n ts destructor ref class BusyCursorHelper { public: BusyCursorHelper { SetCursorToHourglass(). SetCursorToArrow(). } That s fine. } 112  Microsoft Visual C++/CLI Step by Step ... } }. what happens f an error occurs and the SetCursorToArrow ne s never executed? You are eft w th the cursor stuck as an hourg ass. open a fi e and then ensure that t s c osed. but what f you forget to sw tch the cursor back? Or more ke y. you can pa r up these act ons by perform ng the act on n a constructor and then perform ng the match ng act on n the destructor In th s way.The Resource Acquisition Is Initialization idiom Resource Acqu s t on Is In t a zat on (RAII) s an awkward phrase that s used to descr be a very common programm ng sty e n C++. } ~BusyCursorHelper { SetCursorToArrow(). or read data from a database and then ensure that t s updated In C++. // Lots of complex code..

} }. so f you want to prov de copy construct on for your c asses. Chapter 7  Contro ng object fet mes   113 . means that you don’t need copy constructors near y as often n C++/CLI In standard C++ the comp er w g ve you a defau t copy constructor f you do not prov de one Th s s not the case n C++/CLI. you can create an object as a copy of another one In th s sect on you’ see how to wr te and use a copy constructor. } String ^getString() { return str. but you’ a so earn about two other mportant concepts dereferenc ng and track ng references Do I need a copy constructor? Standard C++ makes heavy use of copy constructors because they are needed to support proper memory management Referr ng to ref objects through hand es. t s destroyed. you w need to wr te a copy constructor Let’s start by ana yz ng what happens n the fo ow ng p ece of code ref class MyClass { int value.The object s created and sets the cursor At the fina brace. coup ed w th garbage co ect on. “Except on hand ng”) th s even happens f there s an error Th s examp e of the RIAA d om—do ng someth ng n the constructor and undo ng t n the destructor—shows how somet mes you m ght create a c ass s mp y for the s de-effects you get when us ng t Copy constructors A copy constructor s a spec a k nd of constructor funct on that takes an object of the same type as ts argument In other words. public: MyClass(int v. str(s) {} int getValue() { return value. int main(array<System::String ^> ^args) { Console::WriteLine("Copy Construction"). String ^str. String ^s) : value(v). and that sets the cursor back to an arrow Important y (and as s demonstrated n Chapter 11.

because they are referr ng to the same object Suppose. as we . } If you run th s code. f you mod fy the va ue member of two. to managed objects. str = other. two->getString()). but t s d fficu t to create an un n t a zed reference You can have references to bu t. two->getValue(). we wou d prov de a copy constructor for the c ass.str. t po nts to the same object as one Copy ng a hand e doesn’t copy the object to wh ch t po nts And. str: abc The hand e one po nts to a new MyClass object created through gcnew The hand e two s s mp y a copy of one. even f the garbage co ector moves th ngs around Note  In the same way that a handle is the C++/CLI version of a standard C++ pointer.n types. // ri is a tracking reference Pr nt ng out ri pr nts “5”. MyClass ^one = gcnew MyClass(3. and you use the -> operator to access members A track ng reference s rea y an a as. wh ch wou d ook ke th s MyClass(const MyClass %other) { value = other. } The constructor takes another MyClass object and cop es ts members The value s an int. MyClass ^two = one. str: {1}". return 0. that we d d want to make two a copy of one In that case. t doesn’t matter that we’re po nt ng to the same one But. though. so a copy of the va ue s made The str member s a hand e to a str ng. int %ri = i. but because str ngs are mmutab e. Console::WriteLine("Value: {0}. a tracking reference is the C++/CLI version of a standard C++ reference. It differs from a standard reference because the garbage collector can relocate the object being referred to during memory compaction. "abc"). the runt me ensures that t a ways refers to the r ght ocat on n memory. ook more c ose y at the dec arat on of the argument What s a const MyClass%? The percent (%) symbo ntroduces what s ca ed a tracking reference A hand e ets you refer to an object nd rect y. another name for a var ab e Cons der th s code fragment int i = 5. because ri and i refer to the same var ab e In many ways references are safer than hand es because t s poss b e to have a hand e that hasn’t been ass gned. t pr nts out Value: 3. the va ue for one w be changed. n other words. 114  Microsoft Visual C++/CLI Step by Step . and to hand es When you have a track ng reference to a managed object.value.

value. Create a new CLR Conso e App cat on named CopyCon 2. and the code s say ng “create me a new object. String ^str.str. and you can use the s mp e getter funct ons to retr eve the va ues ater on Chapter 7  Contro ng object fet mes   115 . what about th s code? referr ng to the same object n memory MyClass mm = *m. MyClass has two data members an int and a String hand e The norma constructor n t a zes these two from the va ues passed n. String ^s) : value(v). } String ^getString() { return str. } void setValue(int v) { value = v. as a copy of the one to wh ch m s po nt ng ” It s at th s po nt that the copy constructor s nvoked Th s exerc se shows you how to mp ement a copy constructor for a c ass 1. MyClass %rm = *m. mm. “*” (the aster sk character) You can read *m as “what m po nts to ” However. } }. wh ch the comp er otherw se wou d not a ow The other construct that we need to cover s dereferencing Here’s another code fragment MyClass ^m = gcnew MyClass(). we now know that the copy constructor takes a track ng reference to an object rather than a hand e The reference s marked as const because t ets us make cop es of constant MyClass objects. Add the fo ow ng c ass defin t on before the main funct on ref class MyClass { int value. } int getValue() { return value. The first ne creates a MyClass object by us ng gcnew and returns a hand e to t The second ne returns a reference to m by us ng the dereference operator.So. th s st hasn’t created a copy m and rm are st But. mm s a MyClass w th stack semant cs. public: MyClass(int v. str(s) {} MyClass(const MyClass %other) { Console::WriteLine("copy con called"). str = other. value = other. Here.

three. return 0. or a Rectangle m ght be composed of two Points Cons der the Rectangle as an examp e Because the Points are part of the Rectangle. Create a new CLR Conso e App cat on project w th a su tab e name 2. MyClass ^two = one. you can eas y ensure that th s happens In th s exerc se. Add a header fi e ca ed Geometry h to the project 3.setValue(4). MyClass three = *one. a Person m ght have an Address. "abc"). Bu d and run the app cat on Check that you understand the output Relating objects with stack semantics It s common for objects to be composed of other objects For examp e. three. two->getValue(). Console::WriteLine("Value of one: {0}". Ed t the header fi e to define two c asses Rectangle and Point Note that a Rectangle s com- posed of two Points using namespace System. Console::WriteLine("Value of three: {0}". ref class Point { public: Point(). as we If you dec are the objects by us ng stack semant cs. } The hand e one s created to po nt to a MyClass object. ~Point(). ts Points are destroyed. }. str: {1}". one->getValue()). two->getString()). wh ch creates a copy You can ver fy that th s s the case by chang ng the data n three and show ng that t hasn’t changed the data n one 4. 116  Microsoft Visual C++/CLI Step by Step . MyClass ^one = gcnew MyClass(3. you w see how to compose objects so that they are destroyed correct y 1.3. and the hand e two s a copy of one You can ver fy th s by pr nt ng out the data by us ng the two hand e The object three s created by dereferenc ng one. Console::WriteLine("Value: {0}. Imp ement the ma n funct on to create and use MyClass objects int main(array<System::String ^> ^args) { Console::WriteLine("Copy Construction"). t s reasonab e to expect that when a Rectangle object s destroyed.getValue()).

p2. return 0. public: Rectangle(). Ed t main to create a Rectangle object by us ng stack semant cs Remember to add a #include for Geometry. Console::WriteLine("End of program"). } Rectangle::Rectangle() { Console::WriteLine("Rectangle constructor called").h. 4. #include "Geometry.ref class Rectangle { Point p1. Add a source fi e ca ed Geometry cpp to the project and mp ement the Point and Rectangle c ass members #include "stdafx. }. Console::WriteLine().h" int main(array<System::String^>^ args) { Rectangle r. } 5.h" Point::Point() { Console::WriteLine("Point constructor called"). } Chapter 7  Contro ng object fet mes   117 . as shown n the fo ow ng #include "Geometry. } Point::~Point() { Console::WriteLine("Point destructor called"). } Rectangle::~Rectangle() { Console::WriteLine("Rectangle destructor called").h" using namespace System. Console::WriteLine(). ~Rectangle().

Bu d and run the app cat on You shou d see output s m ar to the fo ow ng Point constructor called Point constructor called Rectangle constructor called End of program Rectangle destructor called Point destructor called Point destructor called You can see from th s output that the Point members of the Rectangle are constructed before the Rectangle’s constructor s ca ed If you th nk about t. It is not helpful behavior. as you d d n the exerc se.6. Rectangle r(). do not put empty parentheses after the variable name. }. and why m ght you choose one over the other? 118  Microsoft Visual C++/CLI Step by Step . you will get a warning (C4930) and the application will not give the correct output when you run it. When to use handles? If you want a c ass to conta n another object—as n the preced ng Rectangle/Point exerc se—you have a cho ce of how to represent the composed object You cou d use an object. What s the d fference between these two. t makes sense for the composed objects to be constructed before the constructor for the outer object s executed The destructors are ca ed n reverse order.. w th the Rectangle destructor be ng ca ed before the destructors for the Points The Point objects are not destroyed unt you can be sure that the Rectangle no onger needs them Note  If you want to create an object that takes no arguments in the constructor. th s s qu te og ca when n t a z ng tse f. . but has been a part of traditional C++ since the earliest implementations. The reason is that the compiler takes this as a function prototype declaration rather than a variable declaration. // This won't work If you do this. such as ts area or d agona ength So. the Rectangle m ght want to use the Points to set some other propert es.. or you cou d use a hand e to an object. as n the fo ow ng code ref class Rectangle { Point ^p1. Point ^p2.

For examp e: MyClass::~MyClass() { . delete m. how many peop e t can ho d. For examp e: MyClass ^m = gcnew MyClass().. but here are a coup e of examp es to ntroduce you to the deas The quest ons you need to ask are the fo ow ng ■ Is the conta ned object a part of ts conta ner... } Define a fina zer for a c ass. Ca delete on the hand e to the object. Add a member funct on that has the same name as the c ass but prefixed w th a t de (~). cons der the Rectangle/Point exerc se aga n The Points are parts of the Rectangle. whether t has conference fac t es. . date and t me. but t a so has a ocat on. and so t makes sense that Points are conta ned w th n the Rectangle Quick reference To Do this Define a destructor for a c ass. } Destroy a dynam ca y created object. they w d sappear when the Rectangle object reaches the end of ts fe There s no way that we are go ng to share a Point w th anyone e se. Chapter 7  Contro ng object fet mes   119 . so you need to be ab e to change the Location And obv ous y..The one you choose depends on the nature of the re at onsh p between the two objects It s beyond the scope of th s book to g ve a fu exp anat on of object-or ented des gn. Add a member funct on that has the same name as the c ass but prefixed w th an exc amat on mark (!). For examp e: MyClass::!MyClass() { . and so on Obv ous y many meet ngs can use the same Location at d fferent t mes. wh ch s represented by a Location object The Location object ho ds a the deta s about a meet ng room where t s. such that t has no ndependent ex stence? ■ Is the conta ned object shared w th anyone e se? ■ Cou d you swap the conta ned object for another one? ■ Can the conta ned object ve on after ts conta ner? Cons der the case of an object that represents a bus ness meet ng Th s has propert es such as descr pt on. the Location doesn’t cease to ex st when a meet ng s over Th s makes t a sens b e dea to use a hand e to a Location object n the Meeting c ass As a second examp e. so they w have a reference to the same Location object It s a so poss b e that the meet ng can be moved. the phone number...

.

you w earn how to use a aspects of nher tance n C++/CLI You w see how to define base c asses and der ved c asses. a sav ngs account s an account. and buses A of these are types of veh c es we can say that a car “ s a” veh c e and that a sports car “ s a” car We tend to c ass fy the wor d n terms of more genera and more spec fic types a the t me A manager s a so an emp oyee. trucks.CHAPTER 8 Inheritance After comp et ng th s chapter. As an examp e. he p ng us re ate and c ass fy types n a way that makes our app cat ons more type-safe. and it’s easy for the compiler to spot any mistakes that you make. cons der cars. and you w find out how to use these c asses effect ve y n your app cat on What is inheritance? Inher tance s an mportant concept n object-or ented programm ng. and so on 121 . and extens b e Note  Type-safe means that the type system makes it easy to use the correct type in the correct place. you w be ab e to ■ Descr be the mportance of nher tance n object-or ented programm ng ■ Define a base c ass ■ Define a der ved c ass ■ Access base-c ass members from the der ved c ass ■ Use the virtual keyword to ach eve po ymorph sm ■ Define abstract c asses and abstract methods ■ Define sea ed c asses ■ Use nterfaces I n th s chapter. flex b e.

otherw se. resu t ng n better-structured code that s eas er to work w th and ma nta n Inheritance terminology When you use nher tance you are dea ng w th an “ s a” re at onsh p between a parent c ass and one or more ch d c asses You w find that there are severa terms used to descr be th s re at onsh p. trucks. so I can pass a of those to the funct on The advantages of nher tance are we documented. you r sk bu d ng ncorrect nher tance mode s 122  Microsoft Visual C++/CLI Step by Step . the ma n reason why you want to use nher tance s to define re at onsh ps between types If you happen to a so ga n the benefit of code reuse. I m ght have a funct on to count the number of veh c es pass ng a g ven po nt Us ng nher tance. they wou d not be Vehicles Th s means that after you have mp emented funct ona ty n the Vehicle c ass. you don’t have to dup cate t n the der ved c asses It s very mportant to understand that code reuse s not the ma n reason for nher tance A though t s usefu . a sports car won’t do I need to be more spec fic Inher tance ets you use th s c ass ficat on mechan sm n your code If I am wr t ng an app cat on to mon tor traffic flow. of course.How we v ew th ngs depends on the job we need to do If I just need to dr ve down the b ock. a sports car wou d do. us ng the der ved c asses to mp ement those features that make them un que The der ved c asses nher t the funct ona ty of the Vehicle c ass They have to. and buses are a veh c es. th s s a bonus If you use nher tance so e y for code reuse. the comp er knows that cars. nc ud ng the fo ow ng ■ C++ tends to use the term base and derived c asses ■ Java uses superclass and subclass ■ Other anguages m ght use parent and child Us ng the correct terms for your anguage s. not as mportant as gett ng the re at onsh ps correct Inheritance and code reuse Suppose that you are des gn ng a Vehicle c ass and some c asses that der ve from t You w put the th ngs that are common to a veh c es n the Vehicle c ass. for examp e. as wou d an SUV—as ong as t s a car But. f I need to take my fam y to the a rport. I cou d use any k nd of car.

you shou d spend some t me des gn ng the nher tance h erarchy Ident fy c asses that have common behav or. you w define and mp ement an nher tance h erarchy represent ng d fferent types of bank accounts The fo ow ng ustrat on shows how the c asses w be arranged n the nher tance h erarchy Note  This illustration uses Unified Modeling Language (UML) notation to represent inheritance. and as a m n mum does everyth ng that a veh c e can do Chapter 8  nher tance   123 . CurrentAccount and SavingsAccount can overr de the CanDebit method to perform the requ red process ng for each type of account You w define and mp ement a three of these c asses dur ng th s chapter Let’s beg n w th the base c ass.Designing an inheritance hierarchy Before you start wr t ng any code to use nher tance n C++. the BankAccount c ass m ght have a method named CanDebit to nd cate whether a certa n amount of money can be deb ted from the account The po cy ru es for a ow ng deb ts are d fferent for each type of account. f I ask you to br ng me a veh c e (base c ass). and they can add extra data members and member funct ons. BankAccount A word on substitutability Substitutability means that everywhere you want a base c ass object. therefore. as requ red CurrentAccount and SavingsAccount can a so overr de member funct ons defined n BankAccount For examp e. however. Each box in this diagram is a class. BankAccount s the base c ass It defines common data members and member funct ons that are common to a k nds of bank accounts CurrentAccount and SavingsAccount are der ved c asses. The arrow pointing to BankAccount denotes inheritance in UML. you can use a der ved c ass object For examp e. represent ng spec fic types of bank account These der ved c asses nher t a the data members and member funct ons from BankAccount. that anyth ng you br ng me s a veh c e. and cons der whether these c asses wou d benefit from us ng nher tance In th s chapter. a car or a truck (der ved c ass) w suffice because I wasn’t spec fic I expect.

type BankAccount. and then think about what data members are needed to support these operations. and the nher tance re at onsh p s not proper Defining a base class When you define a base c ass.For th s reason. but they are not a owed to remove funct ona ty You can regard the funct ona ty prov ded by the base c ass as a contract that the der ved c ass must honor If t doesn’t. Toward the bottom of the d a og box. t s not subst tutab e for the base c ass. se ect V sua C++. n the Name box.h. c ck Header F e ( h) 4. point to Add. and can redefine operat ons that they nher t. Define the BankAccount c ass as fo ows #pragma once using namespace System. Start V sua Stud o 2012 and create a new CLR Conso e App cat on project named BigBank 2. n the pane on the eft. and then c ck Add Note  Another way that you can open the Add New Item dialog box is to right-click the project name in Solution Explorer and then. 124  Microsoft Visual C++/CLI Step by Step . in the shortcut menu that appears. 5. On the Project menu. In th s exerc se. and then. n the center pane. der ved c asses can add funct ona ty over and above the r base c ass. c ck Add New Item 3. and then click New Item. prov de one or more constructors to n t a ze these data members Tip  Always start by deciding what it is that a class must do. you w create a new app cat on and define the BankAccount c ass The BankAccount c ass w be the base c ass for a types of bank accounts n the app cat on In BankAccount. add data members to support the r mp ementat on Then. you can start t by defin ng the common member funct ons that w be requ red by a the der ved c asses After you have defined these member funct ons. In the Add New Item d a og box. you w define the common member funct ons and data members that app y for a types of bank accounts You w a so define a constructor and destructor for th s c ass 1.

wh ch prov des an exact representat on of float ng-po nt va ues and s not subject to round ng errors The downs de s that operat ons are ess effic ent than those us ng float or double Chapter 8  nher tance   125 . you wou d never use a double n any p ace where a float ng-po nt va ue needs to be exact. void Credit(double amount). and the compiler will generate an error if it sees the BankAccount class declaration more than once. 0 33333….ref class BankAccount { public: BankAccount(String ^holder). but n some app cat ons they are s gn ficant Not on y m ght va ues be nexact. Working with floating-point values In th s s mp e examp e. some va ues cannot be represented exact y It s s m ar to the way n wh ch 1/3 cannot be exact y represented as a dec ma ( t s a repeat ng va ue.h will be included in several different places in the application. such as those containing base-class definitions. This directive is particularly useful for frequently included header files. void Debit(double amount). t m ght not be poss b e to compare va ues exact y Two var ab es that ought to have the same va ue m ght be s ght y d fferent because of accumu ated errors dur ng the r ca cu at on In more ser ous code. the code uses a double to ho d the ba ance A though th s s fine n th s case because we’re not actua y concerned that the ba ance s accurate. such as n bank ng ca cu at ons The reason for th s s that ar thmet c on float and double va ues s subject to round ng errors Because of the way n wh ch these types are mp emented. If you omit the #pragma once directive. you shou d use the System::Decimal type. double GetBalance(). you will almost certainly get a compiler error when you try to build the application later on because BankAccount. double balance. but because of th s. }. private: String ^accountHolder. wh ch never term nates) Th s means that ar thmet c on such va ues ends up accumu at ng errors due to the approx mat ons nvo ved These can be very sma . Tip The #pragma once compiler directive specifies that this header file will be processed only once by the compiler during a build.

}. balance(0. } double BankAccount::GetBalance() { return balance. } Note  The constructor uses a member initialization list to initialize the BankAccount data members. Repeat steps 2 through 4.0) { } void BankAccount::Credit(double amount) { balance += amount.cpp to the project 7. but th s t me add a new C++ source fi e named BankAccount. which will become apparent when you define the CurrentAccount and SavingsAccount classes shortly. you spec fy the name of the base c ass 126  Microsoft Visual C++/CLI Step by Step .h" BankAccount::BankAccount(String ^holder) : accountHolder(holder). Furthermore. } void BankAccount::Debit(double amount) { balance -= amount. Type the fo ow ng code n the source fi e to mp ement the BankAccount c ass #include "stdafx.. which is the preferred syntax for initializing data members in a constructor. 8. The co on n the c ass defin t on nd cates nher tance Fo ow ng the co on. it’s the only way to invoke base-class constructors. use the fo ow ng syntax ref class MyDerivedClass : MyBaseClass { .h" #include "BankAccount.. Bu d the app cat on and fix any comp er errors Defining a derived class To define a der ved c ass n C++/CLI.6.

It is not an error if you use it. Cont nue us ng the project from the prev ous exerc se 2. double limit).h 3. every c ass der ves u t mate y from the System::Object c ass If you don’t spec fy a base c ass.NET languages) only support public inheritance. such as the ToString funct on In th s exerc se. so you do not need to use the public keyword. double GetOverdraftLimit(). private: double overdraftLimit. Type the fo ow ng code n the header fi e to define the CurrentAccount c ass #pragma once #include "BankAccount. you w define and mp ement the CurrentAccount and SavingsAccount c asses CurrentAccount w nher t from BankAccount. Inheritance and System::Object In NET.h" ref class CurrentAccount : BankAccount { public: CurrentAccount(String ^holder. and a so that a c asses nher t the common funct ona ty that Object prov des. protected. t makes sense to make t a stat c member of the c ass 1. C++/CLI (and all other Microsoft . there s no need to redefine nherted data members such as accountHolder and balance A you need to define n CurrentAccount are add t ona member funct ons and data members. the c ass you create w mp c t y have “: System::Object” added to ts dec arat on Th s means that every object you create “ s a” System::Object. Add a new header fi e to the project named CurrentAccount. or private after the colon and before the base class name.h” d rect ve Th s d rect ve s requ red because BankAccount s the base c ass of CurrentAccount The comp er needs to know how BankAccount s defined to comp e the CurrentAccount c ass Chapter 8  nher tance   127 .Note  In standard C++ you would put one of the keywords public. Not ce the #include “BankAccount. wh ch means that there s no need to re mp ement nher ted member funct ons such as Credit and Debit L kew se. wh ch app y spec fica y to current accounts SavingsAccount w have an nterest rate assoc ated w th t Because the nterest rate s common to a SavingsAccount objects. void ChangeOverdraftLimit(double newLimit). but be aware that it is not required. }.

A so not ce that the CurrentAccount constructor takes two parameters. you’ see that the BankAccount constructor requ res a String^ parameter to set the account ho der’s name The ba ance s a ways set to 0 n t a y Note  The derived-class constructor must call the base-class constructor by using the member initialization list syntax. static double GetInterestRate(). double limit) : BankAccount(holder). and the second n t a zes the overdraftLimit (defined n CurrentAccount) 4. you’ll get a compiler error.h" ref class SavingsAccount : BankAccount { public: SavingsAccount(String ^holder). if there isn’t a no-argument constructor in the base class. Type the fo ow ng code n the source fi e to mp ement the CurrentAccount c ass #include "stdafx. } The most mportant th ng to note about th s code s the CurrentAccount constructor The member n t a zat on st nc udes the syntax BankAccount(holder) Th s ca s the constructor n the base c ass. static void SetInterestRate(double rate). Add a header fi e to the project named SavingsAccount. overdraftLimit(limit) { } void CurrentAccount::ChangeOverdraftLimit(double newLimit) { overdraftLimit = newLimit.cpp 5. Add the fo ow ng dec arat on for the SavingsAccount c ass to the fi e #pragma once #include "BankAccount. the first parameter n t a zes the account ho der’s name (defined n BankAccount).h" #include "CurrentAccount. 128  Microsoft Visual C++/CLI Step by Step . to n t a ze nher ted data members If you take a ook n BankAccount cpp. Add a new C++ source fi e to the project named CurrentAccount. 6. If you forget to call the base-class constructor. BankAccount.h 7.h" CurrentAccount::CurrentAccount(String ^holder. } double CurrentAccount::GetOverdraftLimit() { return overdraftLimit. the compiler will attempt to call a no-argument constructor in the base class on your behalf.

GetOverdraftLimit().0). Open B gBank cpp and add #includes for the CurrentAccount and SavingsAccount header fi es #include "CurrentAccount.h and SavingsAccount. you w see how to create and use objects of a der ved c ass 1. Console::WriteLine("Balance: {0}". overdraft). double overdraft = acc. } 10.h" #include "SavingsAccount. Cont nue us ng the project from the prev ous exerc se 2.private: static double interestRate.h” because this header file is already included in CurrentAccount. double balance = acc.Credit(100. 3.h.cpp 9.h" SavingsAccount::SavingsAccount(String ^holder) : BankAccount(holder) { } void SavingsAccount::SetInterestRate(double rate) { interestRate = rate. balance).h" #include "SavingsAccount. acc.0). Chapter 8  nher tance   129 .GetBalance(). 2000. Add the fo ow ng code to the fi e to mp ement the SavingsAccount c ass #include "stdafx. De ete the “He o Wor d” ne from main Add code to create a CurrentAccount object and exerc se t CurrentAccount acc("Me". } double SavingsAccount::GetInterestRate() { return interestRate. Console::WriteLine("Overdraft: {0}". Bu d the app cat on and fix any comp er errors Creating derived class objects In th s exerc se.h" Note  There is no need to explicitly write #include “BankAccount. Add a source fi e to the project named SavingsAccount. 8. }.

rate). when programm ng. dec are the BankAccount c ass as an abstract c ass.5 Concrete and abstract classes When you define an nher tance h erarchy. the base c ass often doesn’t represent a rea object Cons der the bank account examp e we’ve been deve op ng n th s chapter When you wa k nto a bank to open an account. SavingsAccount sacc("You").. as before }. It a so g ves you access to ts own GetOverdraftLimit funct on 4. Class body.GetInterestRate(). double rate = sacc. 5. Bu d and run the app cat on You shou d see the nterest rate pr nted. you w mod fy the BankAccount c ass as just descr bed to make t an abstract c ass You w then wr te some code n the main funct on n the app cat on to create and use CurrentAccount and SavingsAccount objects 130  Microsoft Visual C++/CLI Step by Step . you have to spec fy what type of account you want (check ng account or sav ngs account) You can’t just open a “bank account ” In s m ar fash on.. Add code to main to create a SavingsAccount SavingsAccount::SetInterestRate(2. show ng that you can access a stat c member through e ther the c ass name or through an object 6.5). Console::WriteLine("Interest rate: {0}". Observe how the abstract mod fier appears after the c ass name In th s exerc se. as demonstrated n the fo ow ng ref class BankAccount abstract { // . the base c ass acts as a repos tory for the common member funct ons and data members requ red by der ved c asses However. you shou d prevent gener c BankAccount objects from be ng created You shou d a ow on y der ved c asses such as CurrentAccount and SavingsAccount to be nstant ated To accomp sh th s n C++/CLI.You can see that the CurrentAccount object g ves you access to the Credit and GetBalance member funct ons from Account. Bu d and run the app cat on You shou d see output s m ar to th s Balance: 100 Overdraft: 2000 Interest Rate: 2.

Open BankAccount h and change the BankAccount c ass defin t on by add ng the abstract keyword ref class BankAccount abstract { . there are three poss b t es ■ The base-c ass funct on s su tab e for a der ved c asses Der ved c asses w never need to overr de the member funct on w th custom zed behav or The Credit and GetBalance member funct ons n BankAccount fit th s scenar o These funct ons w work the same way for a der ved c asses Here’s an examp e ref class BankAccount abstract { public: void Credit(double amount).. but der ved c asses m ght need to overr de the funct on to prov de custom zed behav or To make t poss b e to overr de a base-c ass funct on. }. as shown n th s examp e ref class BankAccount abstract { public: virtual String ^ToString() override. 3. double GetBalance(). .. Cont nue us ng the project from the prev ous exerc se 2. // This function can be overridden Chapter 8  nher tance   131 . Ins de the main funct on. you must cons der whether der ved c asses w need to overr de any of your base-c ass member funct ons For each member funct on n the base c ass. try to create a BankAccount object as fo ows BankAccount genericAccount("Fred"). ■ // This function cannot be overridden // Neither can this one The base-c ass funct on performs some task. . }..1. Open B gBank cpp to ed t the main funct on for the app cat on 4. wh ch confirms the fact that you cannot create nstances of an abstract c ass 5... }. De ete the statement you created n Step 4 Overriding member functions When you define a base c ass. Inte Sense flags an error.. you must dec are the funct on by us ng the virtual keyword n the base-c ass defin t on.

In th s exerc se. .Th s funct on dec arat on uses both the virtual and override keywords We have seen how virtual nd cates that a der ved c ass can overr de th s funct on The override keyword must be used when you are overr d ng a funct on from a base c ass. // Declare a pure virtual function using C++/CLI syntax virtual void Debit(double amount) abstract. but each der ved c ass needs to perform the operat on n a s gn ficant y d fferent way There s no sens b e common behav or you can define n the base c ass To do th s. you wou d use the new mod fier // This function does not override ToString virtual String ^ToString() new. ■ The base-c ass funct on spec fies some operat on that s requ red by a der ved c asses. although the opposite is not necessarily true: a class can be abstract without having any pure virtual functions. ToString s defined n the u t mate base c ass. n th s case.. System::Object. ntroduced by C++/CLI. and so we use override to show that we are ntend ng to overr de th s funct on and haven’t just added a funct on that ooks exact y the same If by some chance you want to add a funct on that ooks ke a base c ass funct on but does not overr de t. it too must be abstract. Cont nue us ng the project from the prev ous exerc se 132  Microsoft Visual C++/CLI Step by Step . you w define a ToString member funct on n the BankAccount c ass You w dec are th s funct on as v rtua to g ve der ved c asses the opportun ty to overr de the funct on f they want to You w a so mod fy the way n wh ch deb ts are hand ed so that der ved c asses dec de whether a w thdrawa can be made 1. Note  Including a pure virtual function in a class means that it must be abstract.. If a derived class does not implement the function. }. you dec are the basec ass member funct on as abstract C++ ca s these pure virtual functions There are two ways to denote a pure v rtua funct on The first comes from standard C++ and nvo ves putt ng “= 0” at the end of the funct on dec arat on The second way. s to add the abstract keyword Here’s an examp e ref class BankAccount abstract { public: // Declare a pure virtual function using standard C++ syntax virtual void Debit(double amount) = 0.

wh ch s used for jo n ng str ngs together 4. Open BankAccount h and add the fo ow ng pub c funct on dec arat ons to the BankAccount c ass // Derived classes can override this function virtual String ^ToString() override. // Have to override CanDebit virtual bool CanDebit(double amount) override. ". } } Not ce that Debit now ca s CanDebit to ver fy that the deb t s a owed CanDebit sn’t mp emented n BankAccount. 3. balance.ToString()). return true. but a der ved c asses are ob ged to prov de th s funct on At run t me. Chapter 8  nher tance   133 . accountHolder). Open BankAccount cpp and mp ement the ToString funct on as fo ows String ^BankAccount::ToString() { String ^result = gcnew String("Account holder: "). result = String::Concat(result. result = String::Concat(result. } Observe the use of the String::Concat funct on. Balance: "). the correct vers on of CanDebit s ca ed depend ng on the type of bank account be ng used for the deb t operat on—po ymorph sm n act on! We have a so changed the return type of Debit so that ca ng code can determ ne whether the deb t worked 5. Change the prototype for Debit n BankAccount h so that t returns a bool 6. } else { return false. // Derived classes must override this function // You can use '=0' instead of 'abstract' virtual bool CanDebit(double amount) abstract. return result.2. result = String::Concat(result. Open CurrentAccount h and add the fo ow ng pub c funct on dec arat ons to the Current Account c ass // Choose to override ToString virtual String ^ToString() override. Mod fy the Debit member funct on as fo ows bool BankAccount::Debit(double amount) { if (CanDebit(amount)) { balance -= amount.

You are ob ged to overr de CanDebit because t’s a pure v rtua funct on However. } The BankAccount::ToString() syntax ca s the ToString funct on n the base c ass (BankAccount) Th s ca returns a str ng conta n ng the account ho der’s name and ba ance We concatenate the overdraftLimit va ue to th s str ng and return t 8. return result.ToString()). } Th s funct on makes t poss b e for the user to w thdraw one-tenth of the current ba ance 134  Microsoft Visual C++/CLI Step by Step . but th s code s shorter wh e be ng no ess readab e. return ng the resu t of the express on d rect y We cou d have used an if statement to check the cond t on and return true or fa se. Open Sav ngsAccount h and add the fo ow ng pub c funct on dec arat on to the Savings Account c ass virtual bool CanDebit(double amount) override. Overdraft Limit: "). Open Sav ngsAccount cpp and mp ement the CanDebit funct on as fo ows bool SavingsAccount::CanDebit(double amount) { return (amount <= GetBalance() / 10). St n CurrentAccount cpp. overdraftLimit.Not ce the use of the override keyword Th s nstructs the comp er that you are ntend ng to overr de a funct on from the base c ass and haven’t just added a funct on that happens to ook exact y the same 7. Open CurrentAccount cpp and mp ement the ToString funct on as fo ows String ^CurrentAccount::ToString() { String ^result = BankAccount::ToString(). } There are two th ngs to note about th s code F rst. mp ement the CanDebit funct on as fo ows bool CurrentAccount::CanDebit(double amount) { return (amount <= GetBalance() + overdraftLimit). and that s someth ng that C++ coders ke 9. you do not have to overr de ToString. result = String::Concat(result. because the base c ass (BankAccount) prov des a defau t mp ementat on of th s funct on The SavingsAccount c ass chooses not to overr de ToString 10. not ce the way n wh ch the return statement s wr tten. ". we need to ca the GetBalance funct on to get the current ba ance Just because we nher t from BankAccount doesn’t mean that we can access ts pr vate balance member Second. result = String::Concat(result.

} else { Console::WriteLine("Debit(100) failed"). savings.Debit(550) == true) { Console::WriteLine("Debit(550) OK").11. Console::WriteLine("\nTesting the SavingsAccount"). Chapter 8  nher tance   135 . Open B gBank cpp and rep ace the ex st ng code n the main funct on w th the fo ow ng Console::WriteLine("Testing the CurrentAccount"). SavingsAccount savings("Fred").Debit(50) == true) { Console::WriteLine("Debit(50) OK"). } else { Console::WriteLine("Debit(50) failed"). return 0.ToString()).Credit(500). current. } // Should be declined if (current. 100).ToString()). } Console::WriteLine(current. } else { Console::WriteLine("Debit(46) failed"). // Should be accepted if (savings.Credit(500).Debit(46) == true) { Console::WriteLine("Debit(46) OK"). } // Should be declined if (savings. // Should be accepted if (current. } else { Console::WriteLine("Debit(550) failed"). } Console::WriteLine(savings. CurrentAccount current("Jane".Debit(100) == true) { Console::WriteLine("Debit(100) OK").

and there s a need for an access eve that grants access to der ved c asses The protected access eve s ess restr ct ve than private but more restr ct ve than public Any members that are defined as protected can be used n the base c ass. however. not data members. } 136  Microsoft Visual C++/CLI Step by Step . private. Open BankAccount cpp and add the defin t on of RoutingInstructions String ^BankAccount::RoutingInstructions(double amount) { return "Some string…". ntroduces a re at onsh p between two c asses. Note  The order in which you specify the public. you w add a protected member funct on to the BankAccount c ass Suppose that BankAccount has a RoutingInstructions funct on that deta s how a g ven s ze of deb t or cred t shou d be hand ed for a part cu ar account Th s funct on s not to be accessed by users of the c ass but m ght be of use to der ved c asses 1. and n any c ass that der ves from t Tip  You should only make member functions protected. Create a breakpo nt on the first statement n the main funct on and then start the app cat on n the debugger Step through the app cat on one statement at a t me. The data belonging to a class is the responsibility of that class. and it should not allow direct modification by derived classes. 3. Bu d and run the app cat on Check that the output s what you expect 13. Cont nue us ng the project from the prev ous exerc se 2. although many people will put the public section first because that is the most important section from the point of view of users of the class. whereas public members can be used by anyone Inher tance. Open BankAccount h and add the fo ow ng protected funct on dec arat on to the BankAccount c ass protected: String ^RoutingInstructions(double amount). In th s examp e.12. and protected sections of a class declaration does not matter. stepp ng nto each funct on to see wh ch vers on s ca ed dur ng execut on Protected access You have used two access eve s for c ass members so far private and public You know that private members cannot be used outs de the defin ng c ass.

Open B gBank cpp and try add ng a ca to RoutingInstructions on e ther the SavingsAccount or CurrentAccount objects Inte Sense flags an error because you are not a owed to ca th s funct on from an unre ated c ass If you bu d the project. you can define a c ass as sealed.. Chapter 8  nher tance   137 . wh ch sealed does Note  You can specify the sealed and abstract modifiers in any order. Class body. the comp er m ght be ab e to generate more effic ent code To mark a c ass as sea ed. Abstract and sealed It m ght appear at first s ght that abstract and sealed are oppos tes one means that a c ass has to have der ved c asses to be usefu . you m ght want to prevent anyone from add ng extra funct ons to your c ass. use the sealed keyword n the c ass defin t on as fo ows ref class MyClass sealed { // . you w get error C3767 (‘BankAccount Rout ngInstruct ons’ cand date funct on(s) not access b e) Defining sealed classes In C++/CLI. wh ch means that the c ass cannot be used as a base c ass Defin ng a c ass as sea ed s usefu f t performs operat ons that you don’t want custom zed n der ved c asses. however. return (amount <= GetBalance() + overdraftLimit). poss b e to use abstract and sealed together on a c ass Suppose that you have a c ass that on y conta ns stat c (c ass. the comp er knows that t w not have any der ved c asses Because th s means that there w be no ca s to v rtua funct ons. Open CurrentAccount cpp and mod fy the CanDebit funct on so that t ca s RoutingInstructions You shou d not see any warn ngs from the comp er. } 5. whereas the other means that you can’t der ve c asses It s. ess obv ous way If a c ass s sea ed. because CurrentAccount s a owed to ca th s funct on bool CurrentAccount::CanDebit(double amount) { String ^details = RoutingInstructions(amount).eve ) members It wou d make sense to say that you do not want objects of th s type.4. but t s a so usefu n another.eve funct ons Mak ng the c ass abstract prevents nstant at on In add t on. as before }.. because there are no object.

therefore. virtual void WriteToXmlFile(String ^filename) = 0. The defin t on of the der ved c ass a so needs to be changed You need to spec fy the nterface name. Th s c ass spec fies how to convert data to and from XML. and t s mp emented by der ved c asses to su t the r part cu ar data You cou d use the fo ow ng ref class MyData : XmlWriter { public: void ReadFromXmlFile(String ^filename) override { // Read my data } void WriteToXmlFile(String ^filename) override { // Write my data } }. 138  Microsoft Visual C++/CLI Step by Step . such as the fo ow ng ref class XmlWriter { public: virtual void ReadFromXmlFile(String ^filename) = 0. and you cou d rewr te the XmlWriter c ass as fo ows interface class IXmlWriter { void ReadFromXmlFile(String ^filename). you need to be ab e to use them n C++/CLI You have a ready earned about pure v rtua funct ons. An nterface s s m ar.Defining and using interfaces Interfaces are an mportant programm ng construct n NET. }. wh ch are spec fied n a base c ass but mp emented by a der ved c ass Imag ne that you have a c ass that on y conta ns pure v rtua funct ons. void WriteToXmlFile(String ^filename). and dec are the funct ons as virtual ref class MyData : IXmlWriter { public: virtual void ReadFromXmlFile(String ^filename) { // Read my data } virtual void WriteToXmlFile(String ^filename) { // Write my data } }. }.

For examp e: ref class MyDerived : MyBase { . For ex amp e: ref class MyBase abstract { . derivedData(ddata) { . not east of wh ch because they are cross.. there are a number of d fferences between a c ass and an nterface ■ A c ass can conta n mp ementat on and data members. int ddata) : MyBase(bdata). use a member n t a za t on st to ca the base c ass constructor. but they can commun cate because they both know about and use the nterface contract You w see many examp es of nterfaces as you progress through the rest of the book Quick reference To Do this Define an abstract base c ass. }.. use a co on fo owed by the name of the base c ass.. but because you can mp ement as many nterfaces as necessary.You can see that you nher t from an nterface n the same way that you nher t from a c ass However.. and another uses Ne ther c ass m ght have know edge of the other... you can get the benefits of mu t p e nher tance Interfaces are very mportant n NET. wh ch one c ass mp ements. Construct der ved objects. } Chapter 8  nher tance   139 . n the der ved c ass constructor. Use the abstract keyword n the c ass defin t on. n the der ved c ass defin t on. they prov de a way to spec fy a contract. Define a der ved c ass. For examp e: MyDerived::MyDerived(int bdata. you m ght know that a c ass can nher t from many base c asses Th s feature s ca ed multiple inheritance NET on y a ows you to nher t from one base c ass. }. an nterface cannot ■ A members of an nterface are public and abstract by defin t on ■ Interface names shou d start w th an “I” (cap ta ) by convent on ■ A c ass can on y nher t from one base c ass.anguage You can define an nterface n C++ and mp ement t n C# More mportant than that. but t can mp ement as many nterfaces as t wants If you have used standard C++.

.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 CHAPTER 10 Operator over oad ng 159 CHAPTER 11 Except on hand ng . . . . . . . . . . . . . .NET programming basics CHAPTER 9 Va ue types . . . . . . 245 CHAPTER 15 The NET Framework c ass brary 263 141 . . . . . . . .PAR T I I Microsoft . . . . . . . . . . . . . . . . . . . . . . 229 CHAPTER 14 De egates and events . . . . . . . . . . . . . . . . 175 CHAPTER 12 Arrays and co ect ons 197 CHAPTER 13 Propert es . . . . . . . . . . .

.

In th s examp e. and now you’re go ng to meet the other fundamenta bu d ng b ock of NET types— the va ue type In th s chapter. you w be ab e to ■ D st ngu sh between reference and va ue types ■ Work w th structures ■ Work w th enumerat ons I n preced ng chapters. pc s a reference var ab e by wh ch we can refer to the MyClass object created by the gcnew operator Access ng objects by us ng references n th s way makes t poss b e for the NET garbage-co ect on mechan sm to rec a m the resources used by an object when there are no onger any references to t Th s feature of NET makes for effic ent memory usage and means that you won’t suffer from one of the trad t ona prob ems of C++ app cat ons memory eaks 143 . known as handles Cons der the fo owng ne of code MyClass ^pc = gcnew MyClass(). not every data type n NET s a c ass. and you’ve earned how to create and use your own c asses However. you earned about object-or ented programm ng and how to app y t w th n the M crosoft NET Framework You’ve seen how many data types w th n NET are represented by c asses.CHAPTER 9 Value types After comp et ng th s chapter. wh ch w be usefu n your own code Reference types and value types Let’s summar ze what you’ve earned about c asses so far C asses are known as reference types because you a ways access objects by us ng reference var ab es. structures and enumerat ons. you’ d scover what va ue types are and how they d ffer from the reference types you’ve a ready met You w a so earn about two mportant va ue types.

.

.

Structures Structures (common y referred to as structs) prov de a way to create the compound data or record types that you m ght have come across n other programm ng anguages S m ar to c asses. y.NET (managed) structs rather than the traditional struct. such as a po nt w th X and Y coord nates. At the top of the Structs cpp fi e. but there’s one mportant d fference structures are va ue types. so t has two nteger data members represent ng the X and Y coord nates 146  Microsoft Visual C++/CLI Step by Step . mmed ate y be ow the using namespace System. and you’ not ce that structures ook very s m ar to c asses n the way that they are defined The body of the structure s enc osed n braces and fin shes w th a sem co on. ne. The value and struct keywords start a structure defin t on. and how to use the nstances n code Note  Both standard C++ and C++/CLI use the struct keyword to define structures.NET languages. not reference types Therefore. }. and the public and private keywords can be used to set the access eve for structure members Not ce the use of the value keyword here Th s keyword nstructs the comp er that th s s a NET va ue type and not a trad t ona C++ structure It’s mportant that you remember to use value when defin ng your structures Th s s mp e structure represents a po nt on a graph. data members. and other NET features that you’ earn about n ater chapters. add the fo ow ng structure defin t on // The Point structure definition value struct Point { int x.NET world and also makes it possible for you to exchange structures with other . how to create nstances of the structure. This chapter discusses the use of . 1. Declaring . you can mp ement t by us ng a struct Creating and using a simple struct The fo ow ng exerc se shows how to create a structure represent ng a po nt w th X and Y coord nates. structures can conta n member funct ons.NET structures has the advantage of working within the . Start M crosoft V sua Stud o 2012 and create a new CLR Conso e App cat on project named Structs 2. f you have a va ue type that needs to have some nterna structure.

x = 10. a Point has been created on the program stack. and va ue types aren’t accessed by reference Instead. open t aga n and open the source fi e Structs cpp 2. p1.Note  In standard C++ the only difference between a struct and a class is in the default access level.y = 20. 3. // Initialize its members p1. you shou d see the output “p1 x s 10” Investigating the structure In th s exerc se. Insert a debug breakpo nt by c ck ng n the gray border to the eft of the code C ck next to the dec arat on of p1 A red dot appears n the border. 5. add the fo ow ng nes to the main funct on of your app cat on // Create a Point Point p1. Members of a class are private by default. If you c osed the Structs project. unless marked otherwise. To create and n t a ze a Point object. whereas members of a struct are public. Add two nes to pr nt out the va ue of one of the structure members. Comp e and run the app cat on At th s po nt. ke th s Console::WriteLine("p1.x is {0}". as ustrated n the screen shot that fo ows Chapter 9  Va ue types   147 . you w run the app cat on under contro of the debugger so that you can ook at the structure of the va ue type you have created 1. p1. so there is no need to make structure members public. Not ce that the code doesn’t use the gcnew operator The gcnew operator s used to create references to objects. This has been carried over into C++/CLI. and you access t d rect y as p1 Because the data members are pub c at th s po nt. you can access them by us ng the fam ar dot notat on 4.x).

t executes and stops at the breakpo nt You can now use the Loca s pane at the bottom of the w ndow to ook at the structure of the Point type You shou d see an entry for the var ab e p1 Any type that has nterna structure—such as Point— s nd cated by a p us s gn (+) to the eft of the var ab e name 4. the structure hasn’t been fu y n t a zed. wh ch are both 32-b t ntegers At th s po nt n n the code. Press F10 three t mes to n t a ze p1 and execute the next two ass gnment statements Th s act on resu ts n p1 be ng n t a zed. Press F5 to start the debugg ng sess on After the app cat on oads. C ck the p us s gn to expand the structure The Loca s pane opens. so they don’t conta n sens b e va ues 5.3. and you w see the va ues of x and y change to reflect the va ues you set The va ues a so change from b ack to red n the Loca s pane. show ng that they were changed n the prev ous execut on step 148  Microsoft Visual C++/CLI Step by Step . appear ng s m ar to the one shown n the fo ow ng screen shot You can see that p1 has three entr es be ow t The first shows that t’s der ved from System::ValueType. wh ch s n turn der ved from System::Object The other two are the x and y members.

Point(int xVal. } } The constructor takes two int va ues and uses them to n t a ze the x and y data members In th s case. or press ng Sh ft+F5 The differences between structures and classes Structures and c asses have severa fundamenta d fferences ■ ■ ■ ■ ■ You can’t n t a ze members n a structure defin t on If you need to prov de n t a zat on for a structure type. but t wou d be s mp e to add some check ng to ensure that the data passed n s correct Note  Anyone who has used C++ before will be familiar with the use of default arguments on constructors. d scont nue debugg ng by c ck ng the Stop Debugg ng button on the too bar (the dark-red square). exam n ng the changes that occur to p1 as you execute each ne When you’re done. because they aren’t garbage co ected Inher tance sn’t app cab e to structures. y = yVal. Cont nue us ng the project from the prev ous exerc se 2. so you need to provide an explicit default constructor. c ck ng the Stop Debugg ng command on the Debug menu. you w zed on creat on add a constructor to the Point structure so that nstances can be n t a - 1.6. so they can’t nher t from anyth ng e se and you can’t use them as a base c ass Structures can mp ement nterfaces Implementing constructors for a structure In th s next exerc se. Chapter 9  Va ue types   149 . you must prov de a constructor You can’t overr de the defau t no-argument constructor for a structure Th s s because the runt me automat ca y sets a members of a structure to the r defau t va ues 0 for numer c types. the arguments are s mp y be ng cop ed nto the data members. and fa se for Boo eans Structures can’t have destructors or fina zers. Add a constructor to your Point structure so that the code ooks ke th s value struct Point { int x. y. int yVal) { x = xVal. You can’t use default arguments on managed types in C++/ CLI. Cont nue press ng F10 to s ng e-step through the code.

mmed ate y be ow the using namespace System.yyyy = 1960. but you cou d a so make the date entr es nto another structure and refer to t ns de Person Here’s an examp e // A Date structure containing day.20).mm = 3. add the structure defin t ons for Date and Person 3. p1.DOB. month and year value struct Date { int dd. }. create a Person object Remember that you don’t use gcnew. In the main funct on. }. // use the second constructor to set x // to 10 and y to 20 Console::WriteLine("p2.dd = 10. you’ use these two c asses to nvest gate how structure data members work 1. and year Th s structure s qu te genera . p1. ne. and a Date object to ho d the date of b rth In th s exerc se. so you cou d use t n other app cat ons The Person structure conta ns a String reference to ho d the name. F n the va ues for the fie ds // Fill in the name p1. Bu d and run the app cat on Check that the resu t s what you expect Using one structure within another It’s poss b e—and often usefu —to use one structure w th n another Imag ne that you have a structure named Person for descr b ng a person The structure conta ns the name and date of b rth. You can now add extra code to your main funct on to create n t a zed Points Point p2(10. 4. Date DOB. // A Person structure containing a Date member value struct Person { String ^name.name = "Fred". because structures are va ue types // Create a Person Person p1. p1. You can see how the Date structure conta ns three members represent ng the day. month. among other data You cou d use separate fie ds for each tem. Create a new CLR Conso e App cat on project named Person 2. yyyy. p2. 150  Microsoft Visual C++/CLI Step by Step .DOB.x is {0}". 4. At the top of the fi e.3.x). mm.DOB.

Can you see what s go ng on here? The data n the braces—ca ed an aggregate initializer— prov des data for the n t a zat on of the structure The Person structure conta ns two tems a String and a Date Therefore. such as n the fo ow ng // Create a new Date Date newDOB = {1.DOB = newDOB. t executes and stops at the breakpo nt You can now use the Loca s pane at the bottom of the w ndow to ook at the structure of the Person type 9. 3. you s mp y extend the dot notat on to another eve to access ts members You can cont nue th s nest ng to as many eve s as you ke. You can see the configurat on of the Person structure by runn ng the app cat on under contro of the debugger P ace a breakpo nt n the app cat on at the ne where p1 s created by c ckng n the gray marg n to the eft of the code 8. Press F10 to step through the code unt a the members are n t a zed The members of p1 d sp ay n red as each va ue changes Chapter 9  Va ue types   151 . Press F5 to start the debugg ng sess on After the app cat on oads. If you dec de that the date of b rth s wrong. {10. 4. a though t s unusua to go much deeper than you’ve done here 5. you can expand ts structure. The new Date takes the va ues spec fied n the n t a zer and then cop es t nto the Person object. and f you c ck the p us s gn to the eft of DOB. you can s mp y create a new Date and copy t nto the Person object. ts entr es are a so enc osed n braces Note  Use of an aggregate initializer is an alternative to using a constructor and can be handy where there’s no checking to be done on the data. as we 10. overwr t ng the va ues n the Date that s a ready there 7. 1955}.Not ce how structure data members are accessed Because the DOB member has members of ts own. 6. You can a so n t a ze a the members of Person n one ne Remove the four n t a zat on nes you entered n step 4 and then change the ne where you create the Person Person p1 = {"Fred". C ck the p us s gn to the eft of p1 n the Loca s pane to expand the structure of Person Observe that t has Name and DOB members. p1. 1960}}. there are two tems n the st Because Date has members of ts own.

as shown here // A Person structure containing a Date structure value struct Person { String ^name. so you can’t create Date var ab es on the r own Copying structures Because structures are va ue types. . }. et’s cons der nested structure defin t ons If you don’t want to use the Date structure anywhere except ns de your Person structure.. p2 = p1.. c ck the Stop Debugg ng button F na y. yyyy. 152  Microsoft Visual C++/CLI Step by Step . a reference member would have to take part in garbage collection. you can define Date ns de Person. value struct Date { int dd.11. Date DOB. for wh ch copy ng objects resu ts n references be ng cop ed Person p1. // No data is copied. m2 = m1. When you’ve fin shed. // m2 and m1 now refer to the same object. MyClass m2.. }. mm. because structures aren’t garbage-collected. press Sh ft+F5 to stop debugg ng or. copy ng them makes a copy of the va ues they conta n Contrast th s behav or w th c asses. .. Note  You can’t use a reference type as a member of a structure. Person p2. You create Person var ab es and access the r members exact y the same as before The b g d fference s that the Date structure s now a part of Person. on the too bar. // p1's data is copied into p2 MyClass m1.

Thursday. At the top of the Enums cpp fi e. each of wh ch represents an nteger constant 3. enums are defined s m ar y to c asses The body of the enumerat on s enc osed n braces and fin shes w th a sem co on The use of the enum and class keywords nd cates to the comp er that th s s a va ue type and not a trad t ona C++ enumerat on The enumerat on tse f cons sts of a comma-separated set of names. and they der ve from the abstract System::Enum c ass. Saturday. unlike in standard C++. Chapter 9  Va ue types   153 . ne. once aga n. mmed ate y be ow the using namespace System. you w create an enumerat on to ho d va ues represent ng the days of the week and then use t n an app cat on 1. and you access t d rect y as w Not ce how the enumerat on var ab e s n t a zed w th one of the members of the enumerat on Th s syntax s how you n t a ze enumerat on var ab es and how you can change the r va ues ater on Note  In C++/CLI. As w th structures. Sunday }. add the fo ow ng nes to the main funct on of your app cat on // Create a WeekDay WeekDay w = WeekDay::Monday. You create enumerat on var ab es the same as you create any other type To create and n t a - ze a WeekDay object. add the fo ow ng structure defin t on // The Weekday enum definition public enum class WeekDay { Monday.Enumerations An enumerat on (common y referred to as enum) s a set of named nteger constants Enumerat ons are espec a y su tab e for represent ng types that can take one of a set of fixed va ues such as the days of the week or the months of the year Enumerat ons are va ue types. Friday. The enum class keywords start an enumerat on defin t on. Wednesday. Create a new CLR Conso e App cat on project named Enums 2. and you’ not ce that. Tuesday. enumeration members must be qualified with the name of their type. It is an error to just say Monday rather than WeekDay::Monday. the code doesn’t use the gcnew operator An enumerat on var ab e of type WeekDay has been created on the program stack. wh ch n turn der ves from System::ValueType Creating and using an enumeration In the fo ow ng exerc se.

you will get an error (C2664) when you try to use Enum::Format. WeekDay::Saturday When you run the code aga n. you’ understand why //** This code won't compile! **// // '1' would mean Tuesday w = 1. Format needs to be nformed as to the type of the enumerat on. This is because the new C++ standard (C++11. wh ch means a str ng Note  Ensure that you qualify your enumeration with either public or private. it assumes that you have declared a C++11 enumeration. s). these va ues start from 0 and ncrease by one for each subsequent member of the enumerat on You can test th s output by chang ng the va ue that you n t a y ass gned to w. More about enumerations Even though the va ue g ven to an enumerat on s an nteger. you need to use an exp c t cast to nform the comp er as to what you want to do. If you don’t. Console::WriteLine("The day is {0}". w. which this version of Microsoft C++ supports) has a new enumeration type.4. "G"). 154  Microsoft Visual C++/CLI Step by Step . If convert ng between ntegers and enumerat ons were a owed. if the compiler does not see public or private on an enumeration declaration. there’s no mp c t convers on between enumerat ons and ntegers If you cons der the fo ow ng nes of code. wh ch you do t by us ng Enum::typeid and the va ue tse f The “G” nd cates the format for the convers on th s s genera format. t wou d be poss b e to put nva d va ues nto the enumerat on If you do want to convert between ntegers and enumerat on va ues. Try pr nt ng out the va ue of the WeekDay object ke th s Console::WriteLine("Value of w is {0}". as n the fo ow ng examp e String ^s = Enum::Format(WeekDay::typeid. // What would '8' mean? w = 8. you w you try to pr nt the enumerat on w thout cast ng t get an error f 5. It wou d be good to be ab e to pr nt out the symbo assoc ated w th the enumerat on as we as ts numer c va ue You can do th s us ng the Format member of the Enum base c ass. such as n the fo ow ng examp e int day = static_cast<int>(w). the va ue 5 shou d pr nt You must cast the enumerat on to an int n order to be ab e to pr nt t. The va ue 0 shou d be pr nted Each of the named constants mak ng up the enumerat on represents an nteger va ue By defau t. for examp e. (int)w).

The enumerat on now starts w th 1. as shown here public enum class WeekDay { Monday = 1. s mp y ass gn 1 to the Monday member. InvalidHandle=6. a Wednesday!").. Chapter 9  Va ue types   155 . Friday. AccessDenied=5. you’ see how to use an enumerat on to contro app cat on execut on by us ng t n a sw tch statement 1."). and because you haven’t g ven any other va ues for the rema n ng members. case WeekDay::Wednesday: Console::WriteLine("It's break. Thursday. add the fo ow ng switch statement code // Switch on the weekday switch(w) { case WeekDay::Monday: Console::WriteLine("It's break. Sunday }. as n th s examp e public enum class StatusCodes { OK=0. but that sn’t good pract ce You don’t have to re y on the defau t numer c va ues that are ass gned to the enumerat on members Suppose that you want the nteger equ va ents of the weekdays to range from 1 through 7 nstead of 0 through 6. OutOfMemory=8 }. Wednesday. Cont nue us ng the project from the prev ous exerc se If you’ve c osed t. on the F e menu.You can a so use a cast to go the other way. case WeekDay::Tuesday: Console::WriteLine("It's break. some other day. default: Console::WriteLine("It's } a Monday!"). Saturday. After the WriteLine statements. you can g ve a comp ete y d scont nuous ser es of va ues for the enumerat on members. a Tuesday!"). c ck Open So ut on to open the project aga n 2. Tuesday. from nteger to enumerat on. FileNotFound=2. Using enumerations in applications In th s exerc se. they are numbered 2 through 7 If you want..

or the app cat on won’t behave as you expect Using memory efficiently By defau t. a our va ues can qu te happ y fit nto 1 byte Thus. memory w be wasted f each var ab e takes up 32 b ts For th s reason. z=zVal. Create a constructor. You can a so use an aggregate n t a zer: Point3D p1 = { 10. int zVal) { x=xVal. int yVal. }. wh ch g ves you a range of va ues of –2. z. For examp e: p1. an enum s an int. fo owed by the name of the structure and the body n braces. you cou d base the enum on a char. Tuesday. 30 }. Thursday. and therefore. For examp e: value struct Point3D { int x. Quick reference To Do this Create a structure. z.147. t’s poss b e to base an enumerat on on any nteger type In the case of our WeekDay examp e. } }.483. n t a ze structure members.x = 10. everyth ng e se s hand ed by the defau t case Remember to put the break statements n after the code for each case.483. Friday.dd = 20.648 through 2. For examp e: value struct Point3D { int x. y. Point3D(int xVal. y. 20. Saturday. fo owed by a sem co on. y=yVal. Use value struct. Sunday }. wh ch s a funct on that has the same name as the structure.DOB. you can use the names of enumerat on members as sw tch case abe s because they’re a so ntegers The examp e code has cases for Monday through Wednesday. 156  Microsoft Visual C++/CLI Step by Step . Access structure members.147. enumerat ons are 32 b ts n s ze.You are a owed to use an enumerat on var ab e as a sw tch contro var ab e because t’s bas ca y an nteger L kew se. Use the dot notat on. myPerson. as shown here // WeekDay variables are one byte in size public enum class WeekDay : char { Monday = 1. Wednesday.647 If you’re go ng to use on y sma va ues for enumerat on members.

.

.

n types. you’re start ng to use c asses and structures to define your own data types Th s means that f you want to add or compare objects of types that you’ve created. you’re go ng to find out about a spec a category of member funct ons ca ed over oaded operator funct ons. so read carefully! What is operator overloading? Chapter 3. There are also a number of differences. w th wh ch you can add extra funct ona ty so that your types can be used more natura y and ntu t ve y Note  If you’ve encountered operator overloading in C++ before.CHAPTER 10 Operator overloading After comp et ng th s chapter. you can’t use the + and == operators because the comp er doesn’t know how to app y them to your objects 159 . prov de member funct ons n your types.” ntroduces the operators prov ded by the C++ anguage The prob em s that those operators work on y w th the bu t. you will find that there are many similarities when using C++/CLI. and now. “Var ab es and operators. you w be ab e to ■ Descr be what operator over oad ng s ■ Dec de wh ch c asses shou d support operator over oad ng ■ Recogn ze what you can and can’t over oad ■ Descr be gu de nes for prov d ng over oaded operators ■ Exp a n how to mp ement operator over oads Y ou’ve a ready seen how to construct c asses and structures. and use these funct ons n app cat ons In th s chapter.

.

so some ru es are needed to mpose a few m ts and to prevent creat ng an mposs b e job for the comp er ■ ■ ■ You cannot define any new operators Even f you th nk that %% wou d make a neat new operator. Th s s mp e struct s the one you’ use throughout these exerc ses It s mp y wraps an int and then prov des a constructor for creat ng and n t a z ng IntVal objects and a get funct on for access ng the data member Chapter 9. “Va ue types. At the top of the Over oad cpp fi e. } }. regard ess of what they are actua y mp emented to mean for a type Overloading operators in managed types Let’s start by add ng operator over oad ng to va ue types and then move on to reference types You a ready know that va ue types are the types most ke y to need operator over oad ng Overloading arithmetic operators In th s exerc se. add the fo ow ng struct defin t on // The IntVal struct definition value struct IntVal { private: int value. the number of operands taken by an operator You m ght th nk t wou d be rea y usefu to create a unary / operator. you can’t add t You can’t change the arity. * (mu t p cat on) a ways takes precedence over + (add t on). but the d v s on operator a ways has to have two operands You can’t change the precedence or assoc at v ty of operators So. ne. public: IntVal(int v) : value(v) { } int getVal() { return value. Start M crosoft V sua Stud o 2012 and create a new CLR Conso e App cat on project named Overload 2. mmed ate y be ow the using namespace System. you’ see how to mp ement operators n a va ue type The exerc se a so ntroduces many of the techn ques you’ need to use when add ng operator over oad ng to your own types 1.” exp a ns that the keyword value makes IntVal a NET va ue type rather than a trad t ona C++ structure Chapter 10  Operator over oad ng   161 .Rules of overloading Severa ru es app y when over oad ng operators The prob em s that you can mp ement operators to mean whatever you ke.

ke th s one. the r ght-hand s de of the + operat on A unary operator (one that takes a s ng e operand. } Let’s ana yze th s funct on An over oaded operator s represented by a funct on whose name starts w th operator. you get an error (C2676).operator+(two) Thus. we create a new object that s n t a zed w th the sum of the two va ues and return t 6. such as the “–“ n –1) s represented by a funct on that takes no arguments Now. you shou d see the va ue “3” pr nted out 162  Microsoft Visual C++/CLI Step by Step . fo owed by a WriteLine statement to pr nt the va ue of three three = one + two. Try add ng one and two and ass gn ng the resu t to three. IntVal two(2). p ac ng t after the getVal funct on IntVal operator+(IntVal rhs) { IntVal result(value + rhs. wh ch a so has the operator symbo appended to t So. nform ng you that the comp er can’t find a “+” operator that works w th your objects 5. Imp ement the “+” operator for IntVal by add ng the fo ow ng funct on to the struct defin t on. Console::WriteLine(three. Bu d the app cat on aga n You shou d find that the comp at on s successfu because the comp er can find a “+” that works w th IntVal objects If you run the app cat on. a b nary operator (one that takes two operands) s represented by a member funct on that takes one argument.3. the > operator by operator>. Create three IntVal objects. the == operator wou d be represented by a funct on ca ed operator==. rep ac ng the body of the main funct on w th the fo ow ng code IntVal one(1). IntVal three. When you bu d the app cat on. three w be n t a zed to zero 4. and so on When the comp er sees the code one + two t s actua y ca ng the funct on you define. but a new va ue that represents the r sum In the code. therefore. // will get zero value Because va ue types a ways have a defau t constructor. et’s ook at how the operator s mp emented The resu t of one + two s not one or two.getVal()).value). return result.

Now that you’ve seen how to mp ement add t on. however. because th s c ass represents a s mp e nteger va ue. you probab y shou d mp ement them so that they are cons stent w th the behav or of ntegers Tip  The last sentence in the previous paragraph introduces a very important point: It is up to you to define all the operators that make your type work properly. t w not work. If you try th s. because the comp er cannot find a funct on that takes an int as ts eft operand But you cannot add such a funct on to IntVal. t wou d seem reasonab e to want to do th s three = one + 2. Add a ne to the main funct on that tr es to use an int as the eft operand Ver fy that t doesn’t comp e three = 2 + one. because such funct ons a ways have to have an object as the r eft operand The so ut on s to create a stat c operator over oad n the IntVal c ass. See the section “Guidelines for providing overloaded operators” at the end of the chapter for more details. Cont nue us ng the project from the prev ous exerc se 2. such as n the fo ow ng IntVal operator+(int rhs) { IntVal result(value + rhs). Using static operator overloads Becasue IntVal s bas ca y just an int wrapped up n a struct. } How about th s next examp e? The ru es of bas c add t on d ctate that th s shou d be equ va ent three = 2 + one. You can eas y add an over oad of operator+ that takes an int. return result. t shou d be easy for you to mp ement the other ar thmet c operators Indeed. and you wou d do th s for any b nary operator that s symmetr ca (for examp e. Chapter 10  Operator over oad ng   163 . you wou d expect a == 3 to be the same as 3 == a) Th s exerc se shows you how to add a stat c add t on operator to the IntVal c ass 1.

one for (IntVal. IntVal rhs) { IntVal result(lhs + rhs. and one for (int. int). but t a so copes w th an int as e ther the r ght or eft operand because we’ve now nstructed the comp er that t can convert between int and IntVal 164  Microsoft Visual C++/CLI Step by Step . return result. a funct on that d rects the comp er how to convert to and from a type Th s funct on nstructs the comp er how to get from an int to an IntVal by creat ng an IntVal and n t a z ng t w th the int In effect. you have to prov de a convers on operator to s gna the comp er that t can perform the convers on Th s next exerc se shows you how the convers on operator makes t poss b e to use a s ng e operator+ funct on that works w th a comb nat ons of IntVal and int 1. } Th s s an examp e of a conversion operator. } Th s funct on adds two IntVals. wh ch you w see n the exerc se that fo ows th s one 4. t turns out that there s a much neater so ut on. you are say ng to the comp er. you can mp ement three over oads of the stat c operator. Add a stat c vers on of operator+ to IntVal static IntVal operator+(int lhs.3. and not have the non-stat c vers on at a But. one for (IntVal. Add the fo ow ng funct on to the struct.value). here’s what to do ” If you don’t have such a convers on operator. De ete any ex st ng operator+ funct ons and rep ace them w th th s s ng e one static IntVal operator+(IntVal lhs. “If you see an int but you want an IntVal. the comp er won’t be ab e to perform the convers on Conversions and C++/CLI Standard C++ embod es the concept of converting constructors If you defined IntVal as a standard C++ structure. p ac ng t after the getVal funct on static operator IntVal(int v) { return IntVal(v). IntVal).value + rhs.value). IntVal). } Remember that stat c members be ong to a c ass (or structure) as a who e rather than to any one object Th s means that they aren’t assoc ated w th an object. the constructor that takes an int wou d a ow the comp er to mp c t y convert ints to IntVals wherever t s needed M crosoft dec ded to d sa ow th s mp c t convers on n C++/CLI. IntVal rhs) { IntVal result(lhs. return result. and so they need to be passed to both operands If you want. so even f you have a su tab e constructor.

d scont nue the debugg ng sess on e ther by press ng the dark-red square on the Debug too bar. Press F5 to start the debugg ng sess on After the app cat on oads. show ng that the int has been converted for you You can see that—prov ded that your types mp ement the correct constructors and convers on operators—you can somet mes use one operator over oad to perform a fam y of operat ons 6. P ace a breakpo nt n the code by c ck ng n the gray marg n to the eft of the three = 2 + one ne 4.value). Console::WriteLine("three is {0}". the compound ass gnment operators are synthes zed for you Th s means that x += 2 s rewr tten as x = x + 2 so that your over oaded “+” operator can be used Chapter 10  Operator over oad ng   165 . by c ck ng Stop Debugg ng on the Debug menu. such as “+=” and “–=”. three. When you are done. You can ver fy that the convers on s occurr ng by us ng the debugger 3. three.2. w th wh ch you can use x += 2 as shorthand for x = x + 2 In standard C++. three. you don’t get “+=” just because you have over oaded the “+” and “=” operators In C++/CLI.value). or by press ng Sh ft+F5 Overloading compound assignment operators C++ has a number of compound ass gnment operators. Press F11 Th s br ngs you to the operator+ funct on at the breakpo nt At the bottom of the w ndow. they are cons dered comp ete y separate operators.value). n the Loca s pane. three = one + 2. Ed t the code n main to test a the poss b e opt ons three = one + two. scro up and p ace another breakpo nt at the first ne of the operator+ funct on 5. three = 2 + one. Console::WriteLine("three is {0}". t executes and stops at the breakpo nt At th s po nt. Console::WriteLine("three is {0}". ook at the va ues Observe that both lhs and rhs are IntVals.

.

.

Bu d and run the app cat on to ver fy that the operator s work ng as you expect 4. and t makes ts dec s on based on the nterna structure of ts two operands 2. <=. } The funct on fo ows the same pattern as the operator+ It s a stat c member of the IntVal structure. but th s t me t returns a Boolean. so add a defin t on for operator!= to IntVal static bool operator!=(IntVal lhs. you on y have to change the operator== funct on and you have automat ca y updated operator!=. If you mp ement equa ty you need to mp ement nequa ty.1. IntVal rhs) { return lhs. Us ng the same project as n the prev ous exerc ses. 6. but f the nterna structure of IntVal were to change. and >=) can be over oaded n a s m ar way. just as you’d expect a og ca operator to do. >. 3. else Console::WriteLine("Inequality working OK").value. and you can make use of the same shortcut when mp ement ng them 168  Microsoft Visual C++/CLI Step by Step . IntVal rhs) { return !(lhs == rhs). else Console::WriteLine("Something is very wrong!"). Bu d and run the app cat on to ensure that a s work ng correct y The other og ca operators (<. Add some test code to main to test the new operat on if (three == 3) Console::WriteLine("All is OK"). Add some test code for th s new operator if (three != 3) Console::WriteLine("Something is wrong!"). as we 5.value == rhs. find the operator+ funct on n your code and add the fo ow ng funct on after t static bool operator==(IntVal lhs. as we . } Not ce how th s s mp emented t uses operator== to compare the two objects and then uses the og ca NOT operator to negate the resu t De egat ng the compar son to operator== rather than compar ng the nterna s of the objects themse ves s not on y s ght y ess typ ng.

value2) < 0. remember that test ng for equa ty can pose prob ems for float ng-po nt va ues It s we known that computat ons on these types can ntroduce round ng errors n the fina dec ma p aces. t’s up to you to choose one and document t There m ght a so be c asses for wh ch any not on of equa ty s art fic a Cons der a Bank Account c ass what wou d equa ty mean? Two accounts can’t be comp ete y dent ca because they have d fferent. and the one that s part cu ar y re evant to our d scuss on of equa ty s the Equals funct on Chapter 10  Operator over oad ng   169 . and t m ght not be a s mp e dec s on For some types the cho ce s obv ous cons der a Point type that has x and y coord nates In th s case. thus. two Points are equa f the r x and y members have the same va ue What about a Currency c ass that has a va ue and a currency type? You m ght say that two Currency objects are the same f both the va ue and the currency are dent ca L kew se. un que account numbers You m ght choose someth ng that counts as equa ty (such as hav ng the same ba ance) but there s no obv ous mean ng You m ght we dec de that equa ty s not mean ngfu for such types As a fina po nt. two va ues wh ch shou d be dent ca m ght not test as equa One way around th s s to define such va ues as be ng equa f they are w th n a to erance. you m ght dec de that two objects are the same f the r va ues are the same when converted to a common base currency such as do ars or Euros Both approaches are equa y va d.What is equality? Dec d ng whether to mp ement == and != depends on the type you’re wr t ng. for examp e if (Math::Abs(value1 .00001) // they are equal else // they are not The Math::Abs funct on s a stat c member of the Math c ass that returns the abso ute va ue of ts operand Implementing Equals A types n NET u t mate y nher t from the System::Object c ass Th s c ass prov des severa funct ons that a NET types nher t.

you need to mp ement the Equals funct on In th s exerc se.. returning a nullptr if the types don’t match.W th Object::Equals. anotherFour(4). as opposed to compar ng references Th s s the same job that you’ve been do ng by mp ement ng the == operator.. we have an IntVal Compar son s then s mp y a case of compar ng the fie ds of the two objects to see f they are the same 2. types can prov de a way to compare content. five(5). Test the Equals funct on by creat ng some IntVal objects and check ng f they are equa IntVal four(4). 170  Microsoft Visual C++/CLI Step by Step . Cont nue us ng the same project Add the fo ow ng funct on to the end of the IntVal structure defin t on virtual bool Equals(Object ^other) override { IntVal ^obj = dynamic_cast<IntVal^>(other). but t works for anguages that don’t support operator over oad ng Th s means that f your types are go ng to be used from other NET anguages. return value == obj->value. else Console::WriteLine("All is OK"). so you need to use both the virtual and override mod fiers to show that you are overr d ng a base c ass v rtua funct on Equals takes a hand e to an Object as ts argument because t s nher ted by a c asses and so can be used to compare any type at a The first th ng you need to do s to use dynamic cast to convert the Object hand e nto an IntVal hand e Note  dynamic cast is a C++ casting mechanism that performs a cast at run time. if (four. the cast w return nu You know that two objects of d fferent types can’t be equa . so you can return false mmed ate y If the resu t s not nu . so you m ght want to comp e the code to ensure that you haven’t made any cod ng errors Let’s exam ne the code ne by ne The funct on s nher ted from System::Object. } Th s funct on s more comp ex than the others you’ve ooked at.Equals(anotherFour)) Console::WriteLine("All is OK")."). you w mp ement Equals for the IntVal structure 1. if (four.Equals(five)) Console::WriteLine("Something is very wrong!"). if (obj == nullptr) return false. If the hand e passed n wasn’t an IntVal. else Console::WriteLine("Something is wrong.

you cou d over oad ++ and –– to add or subtract a day from the current date.value++. wh ch s d scussed n more deta n Chapter 22 “Work ng w th unmanaged code ” 3. and the va ue adjusted after t has been used In standard C++.ncrement and post. you mp ement the over oad of each operator as a s ng e stat c member. and compare them If you find that the performance of Equals s a concern. Cont nue w th the same project Add the fo ow ng method to the IntVal structure static IntVal operator++(IntVal i) { i.You m ght wonder how an IntVal object s turned nto an Object hand e n the ca to Equals If the comp er sees a va ue type be ng used where a reference type s wanted. } Chapter 10  Operator over oad ng   171 . one each for the pre. find the r data members. you now know how to prov de your own vers on If you do overr de Equals.n ++ and –– operators are used to ncrement and decrement the va ue of nteger var ab es You can over oad them for your own types. but you m ght want to because the nher ted vers on can be very s ow It uses a feature ca ed reflection to exam ne objects at run t me. t automat ca y wraps t n an object wrapper.” they shou d have the same hashcode Ca cu at ng hashcodes s beyond the scope of th s book Implementing increment and decrement As a fina examp e. you wou d prov de two operator over oads each for ++ and ––.ncrement cases In C++/CLI. a process ca ed boxing. return i. f you had a Date type. the base type for a structures. and th s does for both cases 1. mp ements a vers on of Equals Th s means that you don’t actua y need to prov de your own. and t makes sense to use them wherever you have the dea of ncrement ng or decrement ng For examp e. the va ue w be adjusted before the var ab e s used n the express on If p aced after (post-increment and post-decrement). as we A hashcode s an nteger va ue that represents an object It s used when stor ng data n d ct onar es If two objects are “equa . the bu t. you shou d a so cons der overr d ng the GetHashCode funct on. th s sect on shows you how to over oad the ncrement and decrement operators (++ and ––) As s d scussed n Chapter 3. Bu d and run the app cat on to ensure the resu ts are what you expect Points about Equals System::ValueType. the or g na va ue s used n the express on. adjust ng the month and year as appropr ate You a so saw how these operators can be p aced before or after the var ab e If p aced before (ca ed pre-increment and pre-decrement).

value. IntVal next = ++first. first = 5. // pre-increment Console::WriteLine("pre-inc. // post-increment Console::WriteLine("post-inc. first. next. and then returns t 2. next. next = 4. next = {0}.ncrement changed t to 4 and then used t n the ass gnment The post. next = {0}. IntVal(int v) : value(v) { } static operator IntVal^(int v) { return gcnew IntVal(v).mp emented as a ref type rather than a value type ref struct IntVal { int value. first. t w same way be s mp e to emp oy decrement n the Operators and reference types Imp ement ng operators for reference types s very s m ar to mp ement ng them for va ue types. ncrements ts va ue. } static IntVal^ operator+(IntVal ^lhs. next = 4. The var ab e first started w th the va ue 3 The pre. return result.value). } }. next = first++. Test out the operator n code.The stat c funct on takes a s ng e IntVal as ts argument. IntVal ^rhs) { IntVal^ result = gcnew IntVal(lhs->value + rhs->value). the ma n d fference be ng that you need to dea w th hand es to objects As an examp e. first = {1}". first = 4.value.value). Bu d and run the app cat on The fo ow ng output d sp ays. post-inc. such as the fo ow ng IntVal first(3). re. here s part of the IntVal structure. 3. 172  Microsoft Visual C++/CLI Step by Step . show ng that your operator s work ng n both pre and postncrement s tuat ons pre-inc. first = {1}".ncrement d d the ass gnment and then ncreased the va ue After you have mp emented the ncrement operator.

and objects are created by us ng gcnew Apart from that. as we The same goes for < and >. us ng + to concatenate the Strings s pretty ntu t ve You m ght get some agreement that –. as n s2 – s1. the who e of the express on w have to be eva uated. ensure that you over oad !=. can cause prob ems In ear er chapters. } You can see how objects and the dot operator have been rep aced by hand es and ->. three->value). return 0. wou d mean “ ook for s1 w th n s2. some express ons n an if statement m ght never be eva uated If you over oad the AND and OR operators. so t sn’t a good dea to over oad them Other operators. and you’re on y go ng to confuse peop e f you prov de t So. IntVal ^two = gcnew IntVal(2). f you have a String c ass. such as the og ca AND and OR operators (&& and ). IntVal ^anotherThree = 1 + two. the code s substant a y the same Guidelines for providing overloaded operators The most mportant gu de ne to keep n m nd s that overloaded operators must make intuitive sense for a class For nstance. IntVal ^three = one + two. and few peop e know how they work. remove t ” However. you earned about the if statement and how express ons jo ned by && and are on y eva uated f necessary As a resu t. Console::WriteLine("Three is {0}".int main(array<System::String ^> ^args) { IntVal ^one = gcnew IntVal(1). ensure that the operators you prov de for your types are the ones that peop e expect to find The second gu de ne s operator usage must be consistent In other words. ++ and ––. f you over oad ==. anotherThree->value). and f you find t. wh ch changes the way the if works Chapter 10  Operator over oad ng   173 . what cou d the * operator mean when app ed to two Strings? There’s no obv ous mean ng. Console::WriteLine("anotherThree is {0}". and so on The th rd gu de ne s don’t overload obscure operators or ones that change the semantics of the language Operators such as the comma are obscure.

Quick reference To Do this Over oad operators. 174  Microsoft Visual C++/CLI Step by Step . } Over oad operators for va ue types. mp ement a funct on hav ng the name operator w th the operator symbo appended. Over oad operators for reference types. For examp e: IntVal operator+(IntVal other) { . Pass arguments and return va ues as va ue objects. Over oad == and != and prov de an over oad of Equa s for the benefit of other .. Pass arguments and return va ues as hand es.. mp ement equa ty tests.NET anguages.

you w be ab e to ■ Exp a n what except ons are ■ Recogn ze the d fferent types of except ons that can be used n C++/CLI ■ Descr be how to generate except ons ■ Exp a n how to hand e except ons ■ Create your own except on c asses N ow that you know how to construct c asses and va ue types and use them n programm ng.CHAPTER 11 Exception handling After comp et ng th s chapter. th s chapter ntroduces you to except on hand ng. 175 . a powerfu way of manag ng errors w th n C++ app cat ons What are exceptions? Except ons are an error-hand ng mechan sm emp oyed extens ve y n C++ and severa other modern programm ng anguages Trad t ona y. in the same way that “%” denotes a tracking reference in C++/CLI. &status). doSomething(arg1. Note  The “&” (ampersand character) denotes a reference in standard C++. arg2. error and status nformat on s passed around by us ng funct on return va ues and parameters. // Pass status back in a parameter int status. as demonstrated n the fo ow ng // Pass status back as return value bool bOK = doSomething().

the app cat on term nates In NET.A though th s s a tr ed-and-tested way of pass ng status nformat on around. and there m ght not be a way to fix the prob em at the po nt at wh ch the error occurs Except ons make t poss b e for you to hand e the error anywhere up the ca stack (See the upcom ng s debar “The ca stack and except ons ”) Exceptions provide a useful way to signal errors when a return value can’t be used  There are two part cu ar p aces n C++ where return va ues can’t be used constructors don’t use them. each rout ne n the ca stack s checked to see f t mp ements a su tab e hand er If noth ng su tab e has been found by the t me the top of the stack has been reached. and over oaded operators can’t have the r return va ue over oaded to use for error and status nformat on Except ons are part cu ar y usefu n these s tuat ons because they g ve you a means to s destep the norma return-va ue mechan sm The call stack and exceptions At any po nt n an app cat on. you must set each status flag and back out manua y It’s very d fficu t to pass back status nformat on from someth ng that doesn’t take arguments or return a va ue Except ons prov de an a ternat ve error-hand ng mechan sm. t suffers from severa drawbacks ■ You can’t force the programmer to do anyth ng about the error ■ The programmer doesn’t even have to check the error code ■ ■ If you’re deep w th n n a ser es of nested ca s. wh ch g ves you three ma n advantages over trad t ona return-va ue error hand ng ■ ■ ■ Exceptions can’t be ignored  If an except on sn’t hand ed at some po nt. t’s poss b e to throw an except on n C++/CLI code and catch t n M crosoft V sua Bas c NET. by the debugger. someth ng that sn’t poss b e outs de the NET env ronment 176  Microsoft Visual C++/CLI Step by Step . the app cat on w term nate. at run t me. and. except ons have one other s gn ficant advantage They can be used across anguages Because except ons are part of the under y ng M crosoft NET Framework. the ca stack ho ds nformat on about wh ch funct ons have been ca ed to get to the current po nt The ca stack s used n three ma n ways by app cat ons dur ng execut on to contro ca ng and return ng from funct ons. wh ch makes except ons su tab e for hand ng cr t ca errors Exceptions don’t have to be handled at the point where the exception occurs  An error can occur many eve s of funct on ca deep w th n an app cat on. and dur ng except on hand ng The hand er for an except on can occur n the rout ne n wh ch the except on was thrown It can a so occur n any rout ne above t n the ca stack.

result). int bottom = 0. the programmer can generate an except on by us ng the throw keyword. as you’ see ater n the chapter Chapter 11  Except on hand ng   177 . n the main funct on at ne 13 n the Except onTest cpp fi e) System::DivideByZeroException denotes the k nd of object that was passed n the except on A ot of except on c asses are prov ded n the System namespace. presents an error message. and the fina output never makes t to the screen Not ce the form of the standard message t nforms you as to what happened (a System::DivideByZeroException error). and when t s executed. norma execut on stops and the except on-hand ng code bu t n to the app cat on beg ns ook ng for a hand er It ooks n the current y execut ng rout ne. you see the resu t shown n the fo ow ng screen shot You can see that the d v de-by-zero has resu ted n an except on be ng generated Because I d dn’t hand e t n the code. as you’ see short y How do exceptions work? When an error cond t on occurs.As s the case w th any other error mechan sm. the app cat on term nates w th an “unhand ed except on” message Here’s an examp e of how an unhand ed except on appears to you You’ve probab y seen a ot of these a ready! Look at the fo ow ng s mp e code fragment Console::WriteLine("Exception Test"). and then g ves you a stack trace that d rects you to where the error occurred ( n th s case. you’ tend to tr gger except ons by mak ng errors n your code However. and f t finds a su tab e hand er. and the except on s tagged w th a p ece of data that dent fies exact y what has happened At th s po nt. int result = top / bottom. the app cat on has been term nated. Console::WriteLine("Result is {0}". It’s easy to see that th s code s go ng to cause a d v de-by-zero error. int top = 3. you can a so generate except ons yourse f f necessary. the except on-hand ng code moves one eve up the ca stack and checks for a su tab e hand er there Th s process carr es on unt e ther the app cat on finds a hand er or t reaches the top eve n the ca stack—the main funct on If noth ng has been found by th s t me. the hand er s executed and the app cat on cont nues If t doesn’t find a hand er n the current rout ne. and t’s a so ke y that you’ make up your own based on the System::Exception base c ass.

throw ng an except on because your code can’t find a fi e that ought to be present s fine. because that s a norma and expected occurrence. s a form of except on hand ng bu t n to W ndows operat ng systems that s ndependent from C++ I won’t ta k any more about SEH here. SEH. so you can use bu t. except to note that you can nteract w th t from C++ Throwing exceptions Let’s start our exp orat on of except ons by d scuss ng how to generate. or throw. and you can m x them w th trad t ona except ons C++/CLI a so extends except on hand ng by add ng the concept of a finally b ock. not an except ona one How do you know what to throw? There are a arge number of except on c asses n the System namespace. s tuat ons that are unusua . you usua y throw and catch them by reference NET anguages throw and catch objects that are of types nher t ng from the System::Exception base c ass. a of wh ch der ve from Exception A number of those you’ common y encounter are sted n the fo ow ng tab e You shou d be ab e to find the except on c ass to su t your purposes. ref c asses and value types) n except ons. so a though you can throw bu t. you can attach any type of object to an except on. and M crosoft W ndows Structured Except on Hand ng (SEH) Trad t ona C++ except ons form the bas s of a except on hand ng n C++ C++/CLI adds the ab ty to use managed types (for examp e.Exception types Except on hand ng s s ght y comp cated n that you m ght encounter three d fferent types of except on hand ng when us ng C++/CLI trad t ona C++ except ons.n types (such as int and double) as we as structures and objects If you throw objects n C++. wh ch I d scuss n the sect on “The finally b ock” ater n the chapter The th rd sort of except on hand ng. you shou d use Exception-der ved objects when you’re wr t ng NET code When should you throw? You shou d use except ons to s gna cond t ons that are n some way except ona . and wh ch defin te y need attent on by the ca er Don’t use except ons for norma flow of contro n your app cat on For examp e. them You’ end up generat ng far more except ons by acc dent than by des gn. and f you can’t. C++/CLI except ons. us ng an except on to s gna that you’ve read to the end of a fi e sn’t. t’s a ways poss b e to der ve your own except on c asses from System::Exception 178  Microsoft Visual C++/CLI Step by Step . but you need to know how to generate your own when errors occur n your app cat on What can you throw? In trad t ona C++. n other words.n types.

.

Insert code to test the behav or by add ng the fo ow ng code to the main funct on Console::WriteLine("Throw Test"). func(3). et’s move on to hand ng them Using the try and catch construct You catch except ons and process them by us ng the try/catch construct. Handling exceptions Now that you’ve seen how to generate except ons. you get a message and a stack trace Th s t me the message s the str ng used to n t a ze the except on object and the stack trace has two eve s. but the second ca has tr ggered an except on As before. Comp e and run the app cat on. func(0). wh ch was ca ed from the main funct on at ne 20 Note  The precise line number you see reported in the exception stack trace depends on exactly how you typed in and formatted your code. Console::WriteLine("Calling with a=0"). once w th a va d va ue and once w th 0. Console::WriteLine("Calling with a=3"). wh ch shou d tr gger the except on 4. wh ch has the fo ow ng form try { // code that may fail } catch(TypeOne ^one) { // handle this exception } 180  Microsoft Visual C++/CLI Step by Step . and you shou d see someth ng s m ar to the fo ow ng screen shot The app cat on has ca ed the funct on once w thout nc dent. The code ca s the funct on tw ce.3. show ng that the except on was tr ggered at ne 10 n the func funct on. Console::WriteLine("All done").

the first catch b ock hand es except ons tagged w th a TypeOne^ object. wh ch represents the type that w be caught and processed by the catch b ock In the preced ng code. Cont nue us ng the project from the prev ous exerc se 2. func(a). whereas the second b ock hand es those tagged w th a TypeTwo^ object Note  try and catch blocks form a single construct. us ng the examp e from the prev ous exerc se as a bas s 1. The ca s to the funct on are enc osed n a try b ock. ex). Console::WriteLine("Calling with a=0"). Console::WriteLine("Calling with a=3"). w th catch fo owed by a type n parentheses. so t wa ks one eve up the ca stack and comes out n the try b ock Chapter 11  Except on hand ng   181 . as ong as you have at east one The fo ow ng exerc se shows you the bas cs of hand ng except ons. } catch(System::ArgumentException ^ex) { Console::WriteLine("Exception was {0}". a = 0. You can’t have a try block without at least one catch block. You can cha n as many catch b ocks together as there are except on types to catch. } Console::WriteLine("All done"). func(a). try { int a = 3. the except on-hand ng mechan sm takes over It can’t find a hand er n the funct on where the error or g nated.catch(TypeTwo ^two) { // handle this exception } Code that you suspect m ght fa s enc osed n a try b ock that s fo owed by one or more hand ers n the form of catch b ocks Each catch b ock ooks a tt e ke a funct on defin t on. you can’t have a catch block without a try block. wh ch s fo owed by a s ng e catch b ock When the second ca to the funct on fa s. and you can’t put anything in between them. Mod fy the main funct on to ook ke the fo ow ng Console::WriteLine("Throw Test").

.

Bu d and run the app cat on You shou d see a resu t ke th s Exception was Aaargh! In a s m ar way. Chapter 11  Except on hand ng   183 . you need to rank the catch b ocks from most spec fic to most genera Tip  The compiler will give you warning C4286 if you have the catch blocks in the wrong order. a DivideByZeroException s an ArithmeticException. so the type of the first catch b ock matches To get the behav or you expect when us ng more than one catch b ock. you cou d use StackTrace to retr eve and pr nt the stack trace nformat on Using the exception hierarchy The except on c asses form a h erarchy based on System::Exception. This works for both managed and unmanaged code. and you can use th s h erarchy to s mp fy your except on hand ng As an examp e. cons der System::ArithmeticException. ook at the fo ow ng code try { // do some arithmetic operation } catch(System::ArithmeticException ^aex) { // handle this exception } catch(System::DivideByZeroException ^dex) { // handle this exception } Suppose that a DivideByZeroException s thrown You m ght expect t to be caught by the second catch b ock. but t w . be caught by the first one Th s s because accord ng to the nher tance h erarchy. } 3. ex->Message). Ed t the catch statement n the main funct on to read as fo ows catch(System::ArgumentException ^ex) { Console::WriteLine("Exception was {0}". Cont nue us ng the project from the prev ous exerc se Ed t the main funct on to set a back to zero before the second ca to func 2.Here’s a br ef exerc se that demonstrates the use of Exception c ass propert es 1. wh ch nher ts from System::Exception and has subc asses that nc ude System::DivideByZeroException and System::OverflowException Now. n fact.

f you just want to catch a ar thmet c except ons. wh ch. and you’ a so see how to check for except ons when creat ng objects of th s type 1. you’ see how to define a s mp e c ass that uses an except on to report errors from ts constructor. as you now know. add the fo ow ng c ass defin t on ref class Test { String ^str. construct on cont nues Note The nullptr keyword represents a null value for a handle. Create a new CLR Conso e App cat on project named CtorTest 2. don’t have a return va ue In the fo ow ng exerc se. The ref keyword makes th s c ass managed. 184  Microsoft Visual C++/CLI Step by Step . ne and mmed ate y before main. in which you can use a numeric “0” to represent a null pointer. a hand e to a managed String At construct on t me. so the constructor checks the hand e and throws an except on f the test fa s If the hand e passes the test. and a except ons from der ved c asses w be caught In the most genera case. and th s managed c ass has one s mp e data member. and a managed except ons w be caught Using exceptions with constructors In the sect on “What are except ons?” ear er n th s chapter. This is in contrast to standard C++. I ment oned one of the advantages of except ons s that they make t poss b e for you to s gna an error where there’s no way to return a va ue They’re very usefu for report ng errors n constructors. it must be used where a null value is required.So. you can s mp y add a hand er for Exception. you can s mp y put n a hand er for ArithmeticException. Immed ate y after the using namespace System. else str = s. th s hand e must not be nu or po nt to a b ank str ng. } }. public: Test(String ^s) { if (s == nullptr || s == "") throw gcnew System::ArgumentException("Argument null or blank").

“he o”) to check that the except on s thrown correct y Nesting and rethrowing exceptions Now that you’ve seen how to use the try/catch construct. Try creat ng an object n the main funct on. // Try creating an object try { t = gcnew Test(s). the Test constructor w throw an except on that w be caught by the catch b ock 4. and you w see the output from the catch b ock Try mod fy ng the dec arat on of the str ng so that t po nts to a b ank str ng ( n t a ze t w th “”).3. } catch(System::ArgumentException ^ex) { Console::WriteLine("Exception: {0}". } Not ce that the ca to gcnew s enc osed n a try b ock If someth ng s wrong w th the String hand e (as t s here). and then try a nonb ank str ng (for examp e. nest ng except ons means nc ud ng one try/catch construct w th n another. Test ^t = nullptr. } Console::WriteLine("Object construction finished"). et’s move on to cover some more advanced uses The first of these are nest ng and rethrow ng except ons As the name mp es. wh ch can prov de a usefu way to hand e error cond t ons It works as you m ght expect try { // outer try block try { // inner try block // Do something } catch(SomeException ^ex1) { Console::WriteLine("Exception: {0}". as shown n the fo ow ng int main() { Console::WriteLine("Exceptions in Constructors"). ex1->Message). // Create a null handle to test the exception handling String ^s = nullptr. } } Chapter 11  Except on hand ng   185 . ex->Message). Bu d and run the app cat on. return 0.

Create a new CLR Conso e App cat on project named Rethrow 2. t w be hand ed by the nner catch b ock and execut on w cont nue after the end of the nner catch b ock. where t s processed by the outer catch b ock Note  You can nest try and catch constructs to several levels. ex2->Message). so t w be passed to the outer try and catch construct. but it’s unusual to go more than two levels deep because it can overcomplicate the structure of the code. ne and mmed ate y before main.catch(OtherException ^ex2) { Console::WriteLine("Exception: {0}". Rethrow ng an except on means just that—hand ng an except on n a catch b ock and then throwng t aga n so that t can be hand ed somewhere e se The fo ow ng exerc se shows how to catch an except on and rethrow t 1. } catch(ArgumentException ^ex) { Console::WriteLine("Exception caught in func()"). add the fo - ow ng funct on defin t on void func(int a) { try { if (a <= 0) throw gcnew ArgumentException("Aaargh!"). as usua The outer catch b ock w not be executed n th s case because the error has a ready been adequate y hand ed If an except on occurs w th n the nner try b ock that s of type OtherException^. } If an except on occurs w th n the nner try b ock that s of type SomeException^. Immed ate y after the using namespace System. } } Th s funct on s bas ca y the same s mp e funct on to wh ch you were ntroduced at the start of the chapter It throws a System::ArgumentException when t has passed a negat ve argument The d fference here s that the except on s be ng caught w th n the funct on 186  Microsoft Visual C++/CLI Step by Step . t won’t be hand ed by the nner catch b ock.

you’ find that the except on s caught oca y n func and the catch b ock n main doesn’t execute 4. try { int n = 0. and t can be used n th s way on y w th n a catch b ock At th s po nt. If you run th s code. Mod fy the defin t on of func so that t rethrows the except on after hand ng t void func(int a) { try { if (a <= 0) throw gcnew ArgumentException("Aargh!").3. wh ch means mov ng up the ca stack to the main funct on. hand e t. Mod fy the main funct on so that t ooks ke th s Console::WriteLine("Throw Test"). the runt me goes off ook ng for another hand er. t’s qu te usua to catch one type of except on. // rethrow the exception } } Us ng throw w thout an argument rethrows the current except on. } catch(ArgumentException ^ex) { Console::WriteLine("Exception caught in func()"). func(n). } Console::WriteLine("All done"). demonstrat ng that the except on has been hand ed tw ce Note that you don’t have to rethrow the same except on. where the except on s caught a second t me 5. } catch(ArgumentException ^ex) { Console::WriteLine("Exception caught in main()"). Console::WriteLine("Calling with n=0"). Bu d and run th s app cat on The “Except on caught n func()” and “Except on caught n ma n()” messages pr nt. and then rethrow an except on of another type You’ see an examp e of th s n the sect on “Creat ng your own except on types” ater n th s chapter Chapter 11  Except on hand ng   187 . throw.

} catch(System::ArgumentException ^ex) { Console::WriteLine("Exception was {0}". func(n). If you try execut ng the code. } finally { Console::WriteLine("This is the finally block"). try { int n = 3. Mod fy the main funct on so that the second ca doesn’t cause an except on. add ng a finally b ock after the catch b ock Console::WriteLine("Throw Test"). even though there was no error The purpose of th s b ock s to ensure that f you do someth ng n the try b ock—such as open ng a fi e or a ocat ng some memory—you’ be ab e to t dy up whether an except on occurs or not because the finally b ock s a ways executed when execut on eaves a try b ock Th s construct g ves you a way to c ean up what m ght otherw se requ re dup cate code 188  Microsoft Visual C++/CLI Step by Step . e ther by chang- ng the va ue or by comment ng t out When you run the app cat on aga n. Console::WriteLine("Calling with n=0"). Cont nue us ng the project from the prev ous exerc se 2. and the fo ow ng short exerc se shows how t works 1. n = 0. you’ find that the finally b ock s executed after the catch b ock 3. Console::WriteLine("Calling with n=3"). Mod fy the ma n funct on so that t ooks ke the fo ow ng. ex).The finally block C++/CLI adds a new construct to trad t ona C++ except on hand ng the finally b ock The purpose of th s b ock s to et you c ean up after an except on has occurred. func(n). you’ see that the finally b ock s st executed. } Console::WriteLine("All done").

you can eas y der ve your own c ass from Exception and use t n your code The fo ow ng exerc se shows you how to der ve a new except on c ass and how to use t n code 1. t w be caught by the second one. If you want th s funct ona ty when us ng C++/CLI.) b ock doesn’t have an argument Note  Even though you can’t tell what kind of exception you are handling inside a catch(…) block. because the catch(. Chapter 11  Except on hand ng   189 .. Create a new CLR Conso e App cat on project named OwnException 2.. if you rethrow from within the block. no matter what type t s The prob em s that you ose any nformat on about the except on.. MyException(String ^msg.) { // handle any exception } If an except on doesn’t match the first catch b ock. errNo(num) {} }. use a catch b ock that has an Exception^ as ts argument..The catch(…) block Standard C++ has a construct that can be used to catch any except on that goes past Here’s how t works try { // do some arithmetic operation } catch(System::ArithmeticException ^pex) { // handle this exception } catch(. ne // User-defined exception class ref class MyException : System::Exception { public: int errNo. wh ch w catch any managed except on object Creating your own exception types You’ve a ready seen how a the except on types are der ved from the System::Exception c ass If you can’t find one that su ts your needs n the standard except on h erarchy. int num) : Exception(msg). Add the fo ow ng c ass defin t on mmed ate y after the using namespace System. a properly typed object will be thrown to handlers higher in the call stack.

} catch(System::ArgumentException ^ex) { Console::WriteLine("Caught ArgumentException in func()"). and t extends Exception by add ng a s ng e fie d to ho d an error number The c ass constructor takes a message and a number. n t a z ng t w th the message from the or g na ArgumentException 4. so I create a new MyException object and throw t. Add the fo ow ng funct on defin t on mmed ate y after the c ass defin t on void func(int a) { try { if (a <= 0) throw gcnew ArgumentException("Argument <= 0"). you can make a case for having public data members in certain circumstances. ex->Message). try { func(0). throw gcnew MyException(ex->Message. and a message s pr nted Now. I dec de that I rea y want to hand e the except on e sewhere. } catch(MyException ^ex) { Console::WriteLine("Caught MyException in main()"). 3. After you’ve created an Exception object and passed it back to the client. } return 0. Although you’re normally advised to make all data members of classes private. and you’re normally not concerned with the integrity of their state after they leave your code in a throw statement. ex->errNo). and passes the message str ng back to the base c ass Note  I’ve made the errNo field public. Test the except on hand ng by ca ng the funct on n the app cat on s main rout ne int main() { Console::WriteLine("Custom Exceptions"). Console::WriteLine("ErrNo is {0}". } } The funct on checks ts argument and throws a System::ArgumentException f t finds a negat ve va ue Th s except on s caught oca y. 1000).Th s custom except on c ass s a managed c ass that nher ts from System::Exception. do you care what the client does with it? Exceptions are “fire and forget” objects. } 190  Microsoft Visual C++/CLI Step by Step . Console::WriteLine("Message is '{0}'".

such as n the fo ow ng try { Car ^pc2 = safe_cast<Car^>(pv). t can a so be dangerous because you’re overr d ng what the code wou d natura y d rect the comp er to do The safe cast keyword was ntroduced n C++/CLI to he p make the operat on safer The fo ow ng code fragment shows how some convers on operat ons can be unsafe // Define the Vehicle and Car classes ref class Vehicle {}. wh ch s when you nstruct the comp er to convert one type to another for use n an express on A though cast ng can be usefu . the cast works. safe cast checks the object on the other end of the hand e to see f t has the same type as the object to wh ch you’re try ng to cast If t does..OK . // Create a Car Vehicle ^pv = pc. Car ^pc = gcnew Car(). } At run t me. f t doesn’t. // Point to it using a Vehicle handle . comp a n ng that t can’t convert a Vehicle^ to a Car^ The prob em s that a Vehicle hand e cou d po nt to any object der ved from Vehicle such as a Truck or a Bus Imp c t y cast ng from a Car to a Vehicle s fine because a Car s a Vehicle. ref class Car : Vehicle {}...Ca ng the funct on w th a 0 va ue tr ggers the except on. // Copy pv into another Car^ handle . and the except on s then rethrown to be hand ed n the main funct on You can see n the fo ow ng screen shot how the except on has been caught n both p aces Using safe_cast for dynamic casting C++ supports cast ng. } catch(System::InvalidCastException ^pce) { Console::WriteLine("Cast failed"). . an Invalid CastException s thrown Chapter 11  Except on hand ng   191 . ref class Bus : Vehicle {}. go ng the other way doesn’t work because not every Vehicle s a Car One way around th s ssue s to use the safe cast construct..not OK! The comp er ra ses an error on the ast ne. Car ^pc2 = pv. ref class Truck : Vehicle {}. wh ch s hand ed n the funct on tse f.

you can name t what you ke. The difference is that safe cast throws an exception if the cast fails. If you do this and the exception is thrown to non-C++ code. for examp e. your value will be wrapped in a RuntimeWrappedException object. whereas dynamic cast returns a null value. add ng a method that can be ca ed from a V sua Bas c c ent 2.nk brary (DLL) and then use the c ass n a V sua Bas c NET app cat on Note  You will need to have Visual Basic. wh ch are used to ho d the defin t on and mp ementat on of the Class1 c ass Open MyC ass h and add the Test funct on so that t ooks ke the fo ow ng code // MyClass.NET installed to complete the second part of this example. In the fina examp e n th s chapter. such as ints and doubles. and th s ab ty to harmon ze error hand ng across code wr tten n d fferent anguages makes m xed. but make a note of the name You’ find that you’ve created a project that defines a namespace ca ed MyClass.NET you should throw exception objects that derive from System::Exception. so now you can. The project w conta n a number of fi es. 192  Microsoft Visual C++/CLI Step by Step .Note  Experienced C++ programmers will realize that safe cast is very similar to the dynamic cast construct supported by standard C++. among them MyC ass h and MyC ass cpp. you w create a C++ c ass n a dynam c. 1.anguage programm ng much eas er than t has been n the past Note  In . choose a C ass L brary project from the CLR sect on th s s used when you want to create a DLL rather than an EXE I ca ed the project MyC ass. Standard C++ allows you to throw and catch any kind of value. Using exceptions across languages One of the great th ngs about managed except ons n C++/CLI s that they work across anguages. Start V sua Stud o 2012 and open a new V sua C++ project Th s t me. throw an except on n C++/CLI and catch t n a V sua Bas c app cat on No onger are except ons s mp y a C++ feature. conta n ng a s ng e c ass ca ed Class1 It’s th s c ass that you’ ed t.h #pragma once using namespace System.

namespace MyClass { public ref class Class1 { public: void Test(int n) { if (n < 0) throw gcnew ArgumentException( "Argument must be positive"). } }. On the shortcut menu that appears. Bu d the project You end up w th a DLL ca ed MyC ass d be ng created n the project’s Debug d rectory 4. you have to add a reference to t to the project To do so. c ck Browse and search for the DLL you bu t n step 3 Ensure that t’s added to the Se ected Components pane and then c ck OK Chapter 11  Except on hand ng   193 . c ck Add Reference In the Reference Manager d a og box that opens. C ose the project (by c ck ng C ose So ut on on the F e menu) and create a new V sua Bas c Conso e App cat on project named Tester Before you can use the DLL you just created. open So ut on Exp orer (us ng the So ut on Exp orer tem on the V ew menu f t sn’t v s b e) and r ght-c ck the project name 5. } The Test method shou d ook fam ar by now t s mp y checks ts argument and throws an except on f t’s ess than 0 3.

so you don’t have to fu y qua fy the name Class1 when t appears The first ne n the Main funct on creates a new Class1 object.WriteLine("Exception: " & ex.Message) End Try Console. th s s equ va ent to creat ng an object n C++ by us ng gcnew The ca to the Test funct on s enc osed n a Try and Catch construct.WriteLine("All done") End Sub End Module The first ne mports the MyClass namespace nto the app cat on Th s ne does the same job as using namespace does n C++.Test(-1) Catch ex As ArgumentException Console. Add the code to the project Open Modu e1 vb and ed t the Main funct on so that t ooks ke the fo ow ng code ' Application to demonstrate cross-language exception handling Imports [MyClass] Module Module1 Sub Main() Dim obj As New Class1() Try obj. and you can see the s m ar ty between the way except ons are hand ed n V sua Bas c and C++ The ma n d fference s that n V sua Bas c.6. the Catch b ocks are ns de the Try b ock 194  Microsoft Visual C++/CLI Step by Step .

add ng your own members.NET Framework types. Use a catch b ock that takes Exception^ as a parameter. and you are using exactly the same . us ng a hand e to a managed type as the argument. Use throw to rethrow except ons from one catch b ock to another. For examp e: try { // code that might fail } catch(SomeException ^se) { // handle the exception } Catch more than one except on. so you must use a hand e. Catch an except on. For examp e: catch(SomeException ^ex) { // handle the exception } catch(SomeOtherException ^ex2) { // handle the exception } Catch a fam y of except ons. Remember that you catch except ons by refer ence. Use the try/catch construct. ArithmeticException w catch DivideByZero­E xception and severa others. Der ve from the Exception c ass. surround ng the code that m ght fa w th a try b ock. wh ch w catch every type that s der ved from Exception. 7. fo owed by one or more catch b ocks. Create your own except ons. Use the base c ass of the except ons that you want to catch n the catch b ock.Note  Even if you don’t know Visual Basic. Use the throw keyword. Chapter 11  Except on hand ng   195 . Cha n catch b ocks together. For examp e: throw gcnew SomeException(). Catch every except on. and you shou d see the message pr nted out n the Catch b ock Quick reference To Do this Generate an except on. for examp e. it should be obvious that the structure of the code is quite similar to C++/CLI. Hand e except ons at more than one po nt n a program. Bu d the app cat on and execute t Pass ng –1 through as the argument tr ggers the except on.

.

and the M crosoft NET managed arrays. wh ch use funct ona ty nher ted from the NET Framework The second part of the chapter ooks more w de y at the range of co ect on c asses prov ded by the NET Framework. you w be ab e to ■ Imp ement arrays n C++ ■ Create s ng e-d mens ona and mu t d mens ona arrays ■ Create and use managed arrays ■ Understand what gener c types are ■ Use the features of the System::Array c ass ■ Use the co ect on c asses prov ded by the NET Framework ■ Descr be what the STL/CLR brary s T h s chapter concerns tse f w th data structures You’ earn about arrays and other co ect on c asses. and you’ earn how to use them n your app cat ons In the first part of the chapter. and they are based on the arrays that C++ nher ted from C A though nat ve arrays are des gned to be fast and effic ent. Start M crosoft V sua Stud o 2012 and create a new CLR Conso e App cat on project named TradArray 197 .CHAPTER 12 Arrays and collections After comp et ng th s chapter. as you’ see short y Th s first exerc se ntroduces you to C++ nat ve arrays by show ng you how to create an array of va ue types and how to use the array 1. there are drawbacks assoc ated w th us ng them. you’re go ng to earn about two sorts of arrays the nat ve arrays prov ded by the C++ anguage. d scuss ng the r character st cs and show ng you how and when to use them The chapter conc udes w th a br ef ntroduct on to the STL/CLR brary Native C++ arrays Nat ve arrays are those prov ded as part of the C++ anguage.

and a s ze enc osed n square brackets ([]) Here. return 0. and t ho ds ten int va ues A arrays are created by us ng the same syntax. // Create an array int arr[SIZE]. Console::WriteLine("Size in main: {0}". i<SIZE. you m ght be better off us ng a NET co ect on. int main(array<System::String ^> ^args) { Console::WriteLine("Traditional Arrays"). Here’s the first mportant po nt about nat ve arrays after you’ve created an array. so you need to know how many e ements you requ re before you start If you don’t know how many e ements you’re go ng to need. but shou d you want to change the s ze of the array. as shown here // Create an array of six doubles double arr[6]. so. Open the source fi e Trad cpp and ed t the main funct on to match the fo ow ng const size_t SIZE = 10. a name. // Create an array of two char*'s char* arr[2]. you can’t ask the user for a value and then use that value to specify an array dimension at run time. // Fill the array for(size_t i=0. you on y have to change the va ue n one p ace The type size t s a typedef for unsigned int Th s s used where you want to denote s zes. and using them to specify array dimensions. or quant t es It s good pract ce to use size t rather than int A so note the w despread convent on of us ng cap ta zed names for constants The array s created by spec fy ng a type. wh ch s d scussed ater n th s chapter Note  The array size has to be known at compile time. you can’t res ze t.2. for example. it’s common to create constants. } The first ne dec ares a constant that represents the s ze of the array Us ng symbo c constants n th s fash on s preferab e to us ng the nteger tera “10” n the code Not on y does t make exp c t just what the 10 represents. d mens ons. However. sizeof(arr)). 198  Microsoft Visual C++/CLI Step by Step . the array s named arr. either by using preprocessor #define declarations or by declaring const variables. i++) arr[i] = i*2.

j++) Console::WriteLine(arr[j]). Add a second oop to pr nt out the array’s contents after fi ng t // Print its contents for(size_t j=0. array e ements are accessed by us ng square brackets that conta n the ndex Here’s the second mportant po nt about nat ve arrays ndex ng starts at zero rather than one. j<=10. Bu d and run the app cat on The va ues pr nt. you r sk corrupt ng data or crash ng your app cat on Chapter 12  Arrays and co ect ons   199 . one to a ne. A ter the code n the second oop to ook ke the fo ow ng // Print its contents for(size_t j=0. va d nd ces are [0] to [9] 3. represent ng 10 ints of 4 bytes each What happens f you change the range of the second oop so that t tr es to pr nt the e ement at [10]? 5. j++) Console::WriteLine(arr[j]). j<10. so the va d range of nd ces for an array s from zero to one ess than the s ze of the array In other words. as shown n the fo ow ng screen shot. 4. and you a so see that the s ze of the array s 40. f you don’t. Not ce the ess-than-or-equa -to (<=) cond t on The effect of th s cond t on s to try to pr nt 11 e ements rather than 10 Comp e and run the program. for a 10-e ement array. and you shou d see output s m ar to the fo ow ng Not ce the random va ue that’s been pr nted at the end of the st Here’s the th rd mportant po nt about nat ve arrays bounds aren’t checked Nat ve arrays n C++ aren’t objects.As you can see from the oop n the preced ng code. and therefore they have no know edge of how many e ements they conta n It’s up to you to keep w th n the bounds of the array.

t’s s mp y a co ect on of va ues strung together n memory So. t works from that po nt forward re at ve to th s start ng address When you prov de an offset n terms of an array ndex. one after the other. a 10-e ement array of ntegers cons sts of 10 ntegers. t s— n fact. when you pass an array to a funct on. the comp er generates code to access that p ece of memory And. wh ch means that you have to figure out some way of pass ng the s ze nformat on a ong w th the array when you ca the funct on Norma y th s s accomp shed n one of two ways ■ ■ Pass the s ze as an exp c t parameter to the funct on ca Ensure that the array s a ways term nated by a un que marker va ue so that the funct on can determ ne when the end of the data has been reached How do native arrays work? A nat ve array n C++ sn’t an object. but they can’t catch everyth ng. n memory The name of the array represents the address of the first e ement. you can end up read ng or wr t ng somewhere nappropr ate A though th s m ght seem dangerous—and ndeed. and use what s stored there ” Th s exp a ns why array ndex ng starts from 0 an ndex of 0 denotes an offset of zero from the start address. and so you have to be very carefu to check your use of array nd ces 200  Microsoft Visual C++/CLI Step by Step . you pass on y the start ng address. so when you dec are an array ke th s int foo[10]. f you have t wrong and stepped outs de the bounds of the a ocated memory. for reasons that unfortunate y I have ne ther the t me nor space to exp a n n proper deta here Try ng to read or wr te off the end of an array s ca ed a buffer overrun Th s has been the cause of many ser ous bugs n C and C++ app cat ons Some ma c ous nd v dua s have used these bugs to create attacks aga nst app cat ons. you’re nstruct ng the comp er to reserve memory arge enough to ho d 10 ntegers and return you the address as foo When you access an array e ement.Passing arrays to functions Pass ng arrays to funct ons ntroduces a comp cat on because the funct on has no know edge about the s ze of the array t has been passed As you’ see short y. thus. t s somet mes both des rab e and necessary behav or. foo[1] means “offset one int from the address foo. you’re actua y spec fy ng the offset from th s address. and there are many we -documented exp o ts that use buffer overruns Too s do ex st to check that app cat ons aren’t m sbehav ng. so t means the first e ement As soon as the comp er has a ocated the space.

as shown here func(arr. i<size. Add the fo ow ng funct on defin t on mmed ate y after the using namespace System. ke th s func(arr. ne void func(int arr[]. sizeof(arr)/sizeof(arr[0])). where the argument can be a var ab e name or a type name Us ng sizeof on an array returns the tota s ze of the array n bytes. Ca the funct on from the main rout ne. sizeof(arr)). } The first argument to the funct on a erts the comp er that the address of an array s go ng to be passed. n th s case. The sizeof operator returns the s ze of ts argument n bytes. Cont nue w th the project from the prev ous exerc se 2. What f the array s ze needs to be changed at some po nt? You can make your code more robust by ca cu at ng the number of e ements n the array automat ca y by us ng the sizeof operator. wh ch s equ va ent to pass ng a po nter It’s very common to see int* used. the amount of memory po nted to by the first argument The funct on pr nts out the array by us ng the s ze. size_t size) { Console::WriteLine("Size in func: {0}". i++) Console::WriteLine(arr[i]). Bu d and run the app cat on The r ght va ues pr nt out as we as the fact that the array s of s ze 4 bytes Th s reflects the fact that t s passed to the funct on as a po nter Chapter 12  Arrays and co ect ons   201 . just as before 3. 10). nstead The second argument passes the s ze of the array— n effect. 40 bytes When d v ded by the s ze of one e ement—4 bytes—you’re eft w th the number of e ements n the array 4. for(size_t i=0.Let’s nvest gate pass ng an array to a funct on 1.

and the rema n ng e ements w be set to zero Multidimensional arrays Mu t d mens ona arrays n C++ are an extens on of the s ng e-d mens ona var ety The fo ow ng short exerc se shows how to create and use a two-d mens ona array 1. and for h gher-order arrays. If you g ve a d mens on and then prov de too many va ues. Create a new CLR Conso e App cat on project named MultiD 2. as you do n many other anguages. The va ues to be used for n t a zat on are prov ded as a comma-separated st n braces ({}) on the r ght s de of an ass gnment. j<3. j++) arr[i][j] = (i+1)*(j+1). } Observe that a two-d mens ona array s dec ared by us ng two sets of square brackets You don’t put the two va ues ns de one set of brackets. 4 }. // Fill the array for(int i=0. as shown n the fo ow ng syntax fragment int arr[4] = { 1. you s mp y add more sets of square brackets As w th s ng ed mens ona arrays. 3. return 0. 3. 2. and the nd ces of each d mens on vary from zero to one ess than the dec ared s ze Array e ements are a so accessed by us ng two sets of square brackets 202  Microsoft Visual C++/CLI Step by Step .Initializing arrays It’s poss b e to n t a ze arrays at the po nt of dec arat on. these va ues are known as an aggregate n t a zer The comp er s c ever enough to figure out how many va ues are n the st. you have to prov de the s ze at comp e t me. i<2. 4 }. the n t a va ues you g ve w be used to n t a ze the array start ng from e ement zero. you’ get a comp er error If you don’t prov de enough va ues. and t w d mens on the array to fit f you don’t prov de a va ue // Dimension the array automatically int arr[] = { 1. Open the source fi e Mu t D cpp and add the fo ow ng code to the main funct on int main(array<System::String ^> ^args) { Console::WriteLine("Multidimensional Arrays"). // Create a 2D array int arr[2][3]. i++) for(int j=0. 2.

// Print the array content for(size_t j=0. Console::WriteLine(). i<SIZE. i++) pa[i] = i*2. int main(array<System::String ^> ^args) { Console::WriteLine("Dynamic Arrays"). as before Dynamic allocation and arrays So far. j<SIZE. j<3. as fo ows // Print the array content for(int i=0. int arr[][]) and spec fy the d mens on nformat on. i++) { for(int j=0. use two empty sets of square brackets (for examp e. j++) Console::Write("{0} ". a ca to Console::WriteLine outputs a new ne To pass a mu t d mens ona array to a funct on. // Fill the array for(size_t i=0. // Get rid of the array once we're finished with it delete [] pa. but th s s ze can be spec fied at run t me when you know how many e ements you need The fo ow ng exerc se shows how to create an array dynam ca y and then use t 1. a arrays n th s chapter have had a fixed s ze a ocated at comp e t me It s poss b e—and very common—to create arrays dynam ca y at run t me by us ng the new operator The array you create st has a fixed s ze. Open the source fi e Dynam c cpp and ed t the main funct on as shown const size_t SIZE = 10.3. i<2. // Create an array dynamically int *pa = new int[SIZE]. } Chapter 12  Arrays and co ect ons   203 . arr[i][j]). } Not ce that one row of the array s pr nted on one ne The nner oop pr nts a s ng e row by us ng repeated ca s to Console::Write After each row has been output. Create a new CLR Conso e App cat on project named Dynamic 2. j++) Console::WriteLine(pa[j]). Pr nt out the array by us ng an extens on of the method for pr nt ng out the e ements of the s ng e-d mens ona array. return 0.

to use memory effic ent y. the resu t of ca ng s ng e-e ement delete on an array s undefined Str ct y speak ng. you can expect to get a run-time error. because the memory it points to is no longer allocated to you. you need to manage your memory carefu y to ensure that a memory s freed up at an appropr ate po nt Note  After you’ve called delete on a pointer. and one for arrays (delete []) When de et ng an array. you must not use the pointer again. you must remember to dea ocate memory as soon as you’ve fin shed w th the array There are two vers ons of delete one to de ete s ng e objects (delete). If you try to use a pointer after freeing up the memory it points to. you’re returned a po nter to the start of the array Po nters work n a s m ar way to hand es. n any rea -wor d app cat on. but they use an aster sk (*) nstead of a caret You can see that dynam c arrays are accessed n exact y the same way as stat ca y a ocated arrays. your app cat on m ght we st run. so there s no garbage co ect on assoc ated w th th s array Therefore. 204  Microsoft Visual C++/CLI Step by Step . as exp a ned n the s debar “How do nat ve arrays work?” ear er n th s chapter Not ce the ca to delete just before the program ex ts A ocat ng an array dynam ca y n trad t ona C++ doesn’t create a managed object.You’ve prev ous y used the gcnew operator to create NET reference types. the ca s unnecessary here because a a ocated memory s freed up when the app cat on ex ts However. you need to use the delete [] vers on If you forget the square brackets. the new operator s used n trad t ona C++ code n a s m ar way to a ocate memory dynam ca y at run t me The syntax s new. but accord ng to the standard. fo owed by the type of the array and then the d mens on enc osed n square brackets After the array has been created. us ng the square-bracket notat on Th s use of a po nter w th array notat on under nes the re at onsh p between po nters and arrays.

t m ght not be obv ous where a part cu ar p ece of memory shou d be freed up or whose respons b ty t s to free t If delete s ca ed too soon and another p ece of code tr es to use the dynam ca y a ocated array. you can expect a run-t me error The same s true f anyone attempts to ca delete on the same po nter more than once A though manua memory a ocat on us ng new and delete makes t poss b e for you to manage memory very prec se y. t resu ts n an app cat on tak ng up more memory than t needs In extreme cases. m stakes are go ng to be made There are two ma n prob ems assoc ated w th manua memory management ■ ■ Not freeing up memory  If you don’t free up memory when you have fin shed w th t. and we cannot cover t n great depth. these two prob ems were the mpetus beh nd the deve opment of garbage co ectors. so I w focus on how to use the gener c types you w encounter n NET Chapter 12  Arrays and co ect ons   205 .Problems with manual memory management Manua memory management s w de y cons dered to be the s ng e b ggest cause of bugs n C and C++ programs. we need to ntroduce the concept of generic types Th s s a comp ex top c. wh ch make the system track the use of dynam ca y a ocated memory and free t up when no one e se s us ng t Generic types Before we ta k about the NET array and co ect on c asses. and t’s the dr v ng force beh nd the deve opment of the garbage-co ect on mechan sms n anguages such as C# and Java If t’s up to the programmers to ca delete on every p ece of memory they a ocate. but th s sect on prov des enough deta for you to understand why gener c types are usefu and how they work You w a so find that you use gener c types far more often than you create them. the amount of extra memory consumed by an app cat on can reach the po nt where t beg ns to nterfere w th other app cat ons or even the operat ng system Freeing up memory inappropriately  In a comp ex app cat on. you create a memory leak A though th s prob em s norma y the ess ser ous of the two.

The c ass defin t on beg ns w th the generic keyword. as needed... as ong as they are ref types and you can get a hand e to them A st of String^ w work n exact y the same way as a st of Person^ or a st of Vehicle^ In fact.Perhaps the eas est way to ntroduce gener c types s through an examp e Suppose that you want to create a c ass that w ho d a st of object hand es When you beg n des gn ng the c ass. T GetAtIndex(int idx). This is important because it means that it is not necessary to know when compiling the original MyList<T> code what types it will be used with at run time. you w soon rea ze that t doesn’t matter what type the objects n the st are. a p aceho der that w be fi ed n ater and wh ch must be the name of a type You can then mp ement the c ass n terms of T. Th s ne nforms the comp er that we want a st of String^. To use th s type n code. you can say that your st c ass w work w th T^. 206  Microsoft Visual C++/CLI Step by Step . where T s any reference type Th s s what gener c types g ve you the flex b ty to do You can wr te a c ass n terms of T^. and for funct on parameter and return types Note  It is possible (and quite common) for a generic type to have more than one type parameter. a dictionary of key/value pairs will have one parameter for the key type and a second for the value type. you need to spec fy to the comp er what T w name n ang e brackets be by prov d ng as a type MyList<String^> ^listOfString = gcnew MyList<String^>(). . and on y dec de what T s go ng to be when you use t Here s what a (very) part a defin t on of such a gener c st c ass m ght ook ke generic <typename T> ref class MyList { public: void Add(T obj). us ng t n member dec arat ons. a generic version of the class is added to the assembly. which would be denoted by <typename K. and the comp er w ensure that the object w on y work w th String^ Any attempt to add another type resu ts n a comp e-t me error The types created from a gener c type by spec fy ng a type parameter are ca ed constructed types Note  When this code is compiled. wh ch a erts the comp er that you’re start ng a gener c type The <typename T> then nforms the comp er that T s a type parameter. }. For example. and constructed types are created at run time. typename V>.

and you specify the type it is to contain in angle brackets at the time of declaration. Create a new CLR Conso e App cat on project named IntArray 2. whereas the second dec ares an array of 10 String hand es You m ght recogn ze th s second type from the main funct on that you’ve seen n a the examp es Th s exerc se shows you how to create and terate over an array of ints 1. The genera syntax for dec arat on s array<type. Add the fo ow ng code to main to create an array of ints and then fi t w th some squares array<int> ^intArray = gcnew array<int>(5). indexing is not just a way of specifying an offset from an address. Observe that a of these are dec ared as hand es Th s s because an array s a managed object. you can om t the rank) So. Creat ng a managed array s qu te d fferent from creat ng a standard C++ array You dec are a managed array by us ng the array keyword. array<String^> ^stringArray = gcnew array<String^>(10). where rank s the number of d mens ons (a though for a 1D array. and you a ways nteract w th arrays through hand es So. array<Person^> ^arr3. array<double.Managed arrays The NET Framework brary conta ns an array c ass that prov des a managed equ va ent of a standard C++ array but w thout the d sadvantages A managed array s an object that s a ocated on the managed heap and subject to the norma garbage-co ect on ru es Note  Unlike standard C++ arrays. as n the fo ow ng examp es array<int> ^arr1. arr1 s a hand e to a 1D array of ntegers. i<intArray->Length. rank> handle_name. Chapter 12  Arrays and co ect ons   207 . The first ne dec ares an array of 5 ints. and arr3 s a hand e to an array of Person hand es Note The <> syntax indicates that the array is a generic type. The array class is written so that it can represent an array of any type of object. 2> ^arr2. we cou d dec are some arrays as fo ows array<int> ^intArray = gcnew array<int>(5). arr2 s a hand e to a 2D array of doub es. for (int i=0. i++) intArray[i] = i*i.

i++) Console::WriteLine("Element {0} is {1}". 4. Mod fy the oop so that t tr es to read off the end of the array for (int i=0. 2. and ver fy that the va ues are pr nted 5. as demonstrated n the fo ow ng array<int> ^intArray = gcnew array<int>() { 1. i<intArray->Length. And. knows exact y how many t has. 2. Add another oop to pr nt out the va ues for (int i=0. 3 }. and sn’t go ng to et you access an e ement that doesn’t ex st Initialization You saw ear er how a trad t ona C++ array can be n t a zed by us ng an aggregate n t a zer You can do the same w th managed arrays.Not ce how you access the array e ements by us ng the square-bracket notat on. i<intArray->Length+1. the comp er s c ever enough to work out the s ze of the array from the n t a zer. w th the ndex start ng at zero. just ke trad t ona arrays. i++) 6. i. Arrays and reference types Arrays of reference types are s ght y d fferent to arrays of va ue types Remember that reference types are a ways accessed through a hand e Th s means that an array of reference types s actua y go ng to be an array of hand es 208  Microsoft Visual C++/CLI Step by Step . Bu d and run the app cat on aga n Th s t me you shou d get an except on because the array object knows how many e ements t has. as ustrated here array<int> ^intArray = { 1. and t won’t et you try to access an e ement that doesn’t ex st Th s s an mportant d fference between trad t ona and managed arrays The managed array s ho d ng a set of va ues for you. just as n trad t ona arrays There s no reason why ndex ng must start from zero. 2. 3 }. so you can om t the d mens on. so we can wr te the fo ow ng array<int> ^intArray = gcnew array<int>(3) { 1. As you m ght expect. Bu d and run the app cat on. 3 }. but t s trad t ona for anguages n the C fam y 3. intArray[i]). you can om t the ent re gcnew express on because the comp er knows from the eft s de of the statement that you want an array<int>.

// Create an array of String references array<String ^> ^arr = gcnew array<String ^>(SIZE). // Print the content for (size_t i=0. you w use the System::String c ass. Comp e and run the app cat on. the first ne shou d ook ke th s int main(array<System::String ^> ^args) The args argument s a hand e to an array of String hand es. int main(array<System::String ^> ^args) { Console::WriteLine("Arrays of Reference Types"). } 3. // Implicitly assign a string to element one arr[1] = "def". and you have on y ass gned to two of them You can a so use an aggregate n t a zer w th reference types. else Console::WriteLine(arr[i]). gcnew String("def") }. Ed t the main funct on to match the fo ow ng const size_t SIZE = 5. so you cou d have n t a zed the array ke th s array<String ^> ^arr = gcnew array<String^>(SIZE) { gcnew String("abc"). // Explicitly assign a string to element zero arr[0] = gcnew String("abc"). but you can eas y subst tute a reference type of your own 1. Create a new CLR Conso e App cat on named RefArray 2. i<SIZE. i++) if (arr[i] == nullptr) Console::WriteLine("null"). Chapter 12  Arrays and co ect ons   209 . ensur ng that the va ues are pr nted as you expected You shou d see two str ngs pr nted first. fo owed by three nu s Th s s because the array object sets the String hand es to null when t s created. and you w to see ng th s “doub e caret” pattern as you work w th managed arrays become very accustomed The fo ow ng exerc se shows you how to create and use an array of reference types In th s examp e.You can see th s by exam n ng the ma n funct on of any app cat on you’ve wr tten so far If you ook at the defin t on of main.

however. the order of traversa s not guaranteed Us ng an enumerator means that you do not have to be concerned w th the under y ng co ect on type. return ng false when there are no more The Current property. mean ng (for nstance) that the mp ementat on cou d be changed to use a nked st rather than an array. t works w th any co ect on that mp ements the IEnumerator nterface Th s means that you can use the same programm ng construct to terate over very d fferent k nds of co ect on Enumerators Enumerators are the NET mp ementat on of the Iterator des gn pattern. and don’t have to n t a ze and ma nta n a counter Not hav ng to do th s means that there s ess chance to get an offby-one error n your code There s another advantage to us ng the for each oop that m ght not be mmed ate y apparent Th s oop doesn’t on y work w th arrays. an e ement from the array s ass gned to the String s. wh ch resets the po nter to just before the start When you create an enumerator. you can terate over a co ect on w thout hav ng to ma nta n a counter Here’s what a for each oop ooks ke for each (String ^s in arr) { // use s } Each t me around the oop. there s a better way to terate over arrays than us ng a counted for oop the for each oop W th for each. wh ch returns the tem current y be ng po nted to by the enumerator The Reset method. you w have to use a counted for oop 210  Microsoft Visual C++/CLI Step by Step . arrays and other co ect on types do th s by mp ement ng the IEnumerator nterface.Using the for each loop with arrays In NET code. so that you can use t w th n the body of the oop You do not have to know how b g the array s. wh ch moves to the next e ement n the co ect on. wh ch prov des an abstract way to terate over any co ect on In NET. wh ch has the fo ow ng three members ■ ■ ■ The MoveNext method. that you can on y read co ect ons through an enumerator If you want to mod fy e ements wh e you traverse the co ect on. a though w th some co ect ons. t s pos t oned just before the first e ement Ca ng MoveNext unt t returns false s guaranteed to v s t each e ement n the co ect on once. and the ca ng code wou d not have to change Note.

you need to spec fy two va ues n the constructor to set the va ues for each d mens on You a so obv ous y need to g ve two va ues when spec fy ng an e ement n a 2D array. }. } Chapter 12  Arrays and co ect ons   211 . you p ace both ns de a s ng e pa r of square brackets array2d[1. 6 { 7.Th s short exerc se shows you how to use a for each oop 1. you don’t prov de extra pa rs of square brackets. 2> { 1. } 3.2>(3. As you wou d expect. however. 8. Bu d and run the app cat on to ensure that you see the same output Multidimensional arrays Just as n standard C++. 3 { 4. but nstead spec fy the d mens on ns de the ang e brackets For examp e. Cont nue w th the project from the prev ous exerc se 2. ndexes start from zero n a d mens ons. you can create mu t d mens ona arrays n C++/CLI Un ke standard C++. ^array3d = { }. Because you have two d mens ons.2> ^array2D = gcnew array<int.1] = 7. and you use nested cur y brackets to show wh ch va ues be ong to wh ch row of the array array<int. but n C++/ CLI. 9 }. 3). and you can genera ze the creat on and use of these arrays to any number of d mens ons you ke You can use aggregate n t a zers w th mu t d mens ona arrays. 5. Mod fy the code that pr nts out the contents of the array to use a for each oop for each (String ^s in arr) { if (s == nullptr) Console::WriteLine("null"). here s how you wou d dec are a two-d mens ona array of ints array<int. else Console::WriteLine(s). 2.

ForEach Performs an act on on each e ement of the array. Clone Creates a sha ow copy of the array. Method Description AsReadOnly Returns a read on y wrapper for an array. un ess overr dden by a der ved c ass. perform ng type downcast ng as requ red. LongLength Returns the tota number of e ements n a d mens ons of the array as a 64 b t nteger. Clear Stat c method that sets a or part of an array to zero or a nu reference. BinarySearch Stat c method that searches a s ng e d mens ona array for a va ue by us ng a b nary search a gor thm. Copy Stat c method that cop es a or part of one array to an other array. A ways returns fa se. Exists Determ nes whether the array conta ns e ements that match a cond t on. See the sect on “Us ng enumerators” ater n th s chapter for deta s. CopyTo Method that cop es a or part of one s ng e d mens ona array to another. GetLowerBound Returns the ower bound of a spec fied d mens on as an nteger. Length Returns the tota number of e ements n a d mens ons of the array as a 32 b t nteger. un ess overr dden by a der ved c ass. A ways returns true.NET array class Managed arrays n the NET Framework a nher t from System::Array.The . A ways returns fa se. FindAll Return a the e ements of the array that match a cond t on. FindLast Return the ast e ement of the array that matches a cond t on. GetEnumerator Returns an enumerator for the array. IsSynchronized Returns true f the array s thread safe (synchron zed). un ess overr dden by a der ved c ass. Rank Returns the number of d mens ons n the array. SyncRoot Returns a po nter to an object that can be used to syn chron ze access to the array. Find Return the first e ement of the array that matches a cond t on. GetLength Returns the number of e ements n a spec fied d mens on as an nteger. 212  Microsoft Visual C++/CLI Step by Step . wh ch means that every managed array has a number of usefu propert es and methods These propert es and methods are summar zed n the fo ow ng two tab es Property Description IsFixedSize Returns true f the array has a fixed s ze. IsReadOnly Returns true f the array s read on y.

.

6. wh ch matches the dec arat on 4. j<=arr->GetUpperBound(0).{1}] = {2}". so you can pr nt out the s zes of each d mens on. The outer oop terates over the rows. i. The GetLength method—not to be confused w th the Length property—returns the s ze of any one d mens on of the array. the GetLowerBound and GetUpperBound methods return the nd ces of the ower and upper bounds The argument to GetUpperBound and GetLowerBound s the d mens on of the array whose bound you want to find In C++. k++) arr[j.When you run th s code.k] = (j+1)*(k+1). and the [x. you need to know how to get and set e ements n the array 5. k<arr->GetLength(1). 1).1] arr->SetValue(10. the ower bound s nvar ab y 0 and the upper bound can be obta ned by us ng the GetLength method. Add the fo ow ng nested oops to the end of your code // Fill the array with values for (j=0. whereas the nner oop terates over the co umns. you shou d find that the rank s two and the tota ength s s x. the outer oop terates over the rows. i<arr->Rank. k. Bu d and run the app cat on Check that the resu ts are what you expect 214  Microsoft Visual C++/CLI Step by Step . arr->GetLength(i)). j.y] notat on s used to reference the array e ements The Array c ass a so has the SetValue method.k]). arr[j. Aga n. j++) for (k=arr->GetLowerBound(1). wh ch prov des an a ternat ve way of sett ng va ues for those anguages that don’t support the array notat on sty e of C++ // Put '10' in array element [1. Pr nt out the va ues n the array by us ng a s m ar pa r of nested oops // Print out the array data for (j=arr->GetLowerBound(0). so these are ma n y usefu n other anguages for wh ch t m ght be common to have arrays w th arb trary ower and upper bounds 7. as presented here // Print out the array dimension information for (i=0. i++) Console::WriteLine("Dimension {0} is of size {1}". and the nner oop terates over the co umns In th s case. k++) Console::WriteLine("pn[{0}. j++) for (k=0. 1. j<arr->GetLength(0). k<=arr->GetUpperBound(1). Now that you have an array and can find out how arge each d mens on s.

{1}] = {2}". such as copy ng. create a second two-d mens ona array the same s ze and type as the or g na // Create another multidimensional array of ints array<int. arr2.2. 5. To copy some va ues over from the first array to the second. such as n the fo ow ng examp e for(j=arr2->GetLowerbound(0). 2> ^arr2 = gcnew array<int. k++) arr2[j.2). Add some code to fi the new array w th a constant va ue // Fill the array with a constant value for (j=0. arr2[j. find out how many d mens ons they have and how arge they are. you can copy a or part of one array nto another The first two arguments are the source array and the ndex from wh ch to start copy ng The second two are the dest nat on array and the start ng ndex at wh ch e ements are to be rep aced The fina argument s the number of e ements to be cop ed In th s case. wh ch you’ be ab e to see f you add code to pr nt the contents of arr2. At the end of the main funct on. j++) for (k=0. k++) Console::WriteLine("pn[{0}. j++) for(k=arr2->GetLowerbound(1). 4. search ng.k]). 2>(3. and sort ng Copying array elements The fo ow ng exerc se shows you how to use the Copy method to copy part of one array to another 1. you’ve cop ed two e ements from arr nto the m dd e of arr2. j<=arr2->GetUpperBound(0). Cont nue w th the project from the prev ous exerc se 2. and get and set va ues Th s sect on ntroduces some of the more advanced operat ons supported by the Array c ass. k. k<=arr2->GetUpperBound(1). 3. 2). Bu d and run the app cat on Chapter 12  Arrays and co ect ons   215 . j. Us ng th s method. j<arr2->GetLength(0).0. k<arr2->GetLength(1). use the stat c Copy method // Copy two values from arr to arr2 System::Array::Copy(arr.k] = 47.More advanced array operations You can now create arrays.

the index returned will be one less than the lower bound of the array. "Horse". pos+1). "Cat". searches for an occurrence beg nn ng at a g ven offset Because the search s start ng just past the first occurrence. the ndex returned s that of the second occurrence. // Check the length Console::WriteLine("sa has length {0}". s. wh ch n th s case s 0 The second ca . LastIndexOf works n the same way as IndexOf. "Cat" }. Open the Str ngs cpp source fi e and add the fo ow ng code to the top of the main funct on to create an array of str ngs // Create an array of strings array<String ^> ^sa = { "Dog". The IndexOf and LastIndexOf funct ons both et you search to determ ne whether a part cu ar object occurs n the array Add the fo ow ng code to the main funct on // Search for a value String ^s = "Dog". and you can do so by us ng the IndexOf and LastIndexOf methods 1. "Elephant". The ca to IndexOf finds the first occurrence of the str ng “Dog” n the array and returns ts ndex. "Gerbil". to an over oad of IndexOf. // Search for the next occurrence pos = Array::IndexOf(sa. which in C++ will usually mean a value of –1. pos). Console::WriteLine("Next index of s in sa is {0}". pos). but t starts search ng from the other end of the array 4.Searching It’s common to want to search an array to see whether t conta ns a spec fic entry. Create a new CLR Conso e App cat on project named Strings 2. wh ch s 4 A th rd over oad ets you search w th n a port on of the array Note  If the value isn’t found. int pos = Array::IndexOf(sa. sa->Length). s). 3. Console::WriteLine("Index of s in sa is {0}". "Dog". "Pig". Bu d and run the app cat on 216  Microsoft Visual C++/CLI Step by Step .

5. 1 }. Array::Reverse(sa). When you run the app cat on. for each (String ^s in sa) Console::WriteLine(s). for each(String ^s in sa) { Console::WriteLine(s). 1. the e ements w have been sorted from Cat to Pig Chapter 12  Arrays and co ect ons   217 . 2. Cont nue w th the project from the prev ous exerc se The sa array current y conta ns the fo ow ng entr es Pig Horse Gerbil Elephant Dog Dog Cat Cat 2. 4. Add another ca to Sort. wh e p gs come n at number s x—so fee free to change them as you ke 3. Console::WriteLine("---Sorting with keys---"). 3. and the e ements n sa are sorted nto exact y the same order When you run the code and pr nt out the array. one of wh ch conta ns keys used to define the sort order Here’s an exerc se to show you how th s works 1. spec fy ng both arrays Array::Sort(keys. Th s array conta ns the keys that you’re go ng to use to sort the array of an ma names They reflect my preferences—cats are number one. from Pig back to Cat One va uab e over oad to Sort makes t poss b e for you to prov de two arrays. After the ca s to Sort and Reverse.Sorting The stat c Array::Sort method and ts over oads g ve you a way to sort an array or a part of an array. you shou d see the e ements of the array pr nted n reverse order. whereas Array::Reverse ets you reverse the order of e ements Try add ng the fo ow ng code to the main rout ne Array::Sort(sa). sa). add a new array array<int> ^keys = { 6. } The keys array s sorted. 2.

ca s to MoveNext return fa se The property Current retr eves the current object but doesn’t move the po nter. t s passed a reference to another object The funct on returns 0 f the two nstances are equa . Cont nue by us ng the Str ngs project. a negat ve va ue f the object passed n s greater than the nstance ca ng the funct on.” for deta s on how to use safe cast ) 218  Microsoft Visual C++/CLI Step by Step . safe cast (See Chapter 11. Bu d and run the app cat on You’ not ce severa th ngs about th s code To beg n w th. The IEnumerator nterface s defined n the System::Collection namespace. add the fo ow ng using dec arat on after the using namespace System. you’ use an enumerator to st the e ements n the String array 1. CompareTo When CompareTo s nvoked on an object. while (ie->MoveNext()) Console::WriteLine(ie->Current). and that they are what makes for each oops work w th co ect ons The GetEnumerator method on a co ect on returns an enumerator that you can use to terate over the e ements of the co ect on In th s next exerc se. “Except on hand ng.The IComparable interface Any type that wants to be used n the Sort method must mp ement the IComparable nterface. IEnumerator ^ie = sa->GetEnumerator(). wh ch has one member. 3. and a pos t ve va ue f the object passed n has a esser va ue Using enumerators You have a ready seen how you can use enumerators to terate over any co ect on. so you’ often need to cast th s to the actua type of the object by us ng the C++ dynamic cast or the NET equ va ent keyword. the enumerator starts off pos t oned before the first e ement. ne using namespace System::Collections. Add the fo ow ng code to the end of the main funct on Console::WriteLine("---Using Enumerator---"). so you’ get the same va ue back unt you ca MoveNext aga n The Current property a so returns a genera Object hand e. so you need to ca MoveNext once to get to the first e ement When there are no more e ements to retr eve. so t’s eas er to use enumerators f you add a using dec arat on for the namespace 2.

V> Stores a co ect on of key/va ue pa rs as a hashtab e HashSet<T> A co ect on of un que va ues LinkedList<T> A doub y nked st List<T> An expandab e array Queue<T> Stores a st of e ements and accesses them n the same order n wh ch they were stored SortedList<K.What sn’t obv ous from the preced ng code s that the enumerator gets a snapshot of the under y ng co ect on Enumerators are des gned for read-on y access to co ect ons. This interface has the one method. and although it provides the same functionality.NET collection classes The System::Collections::Generic namespace conta ns severa very usefu co ect on c asses that you can use n C++ programs Some of the most common y used are sted n the fo ow ng tab e A coup e of them w be exam ned ater n more deta to g ve you an dea of how they work Class Description Dictionary<K. and you can have severa ndependent enumerators act ve on the same co ect on at one t me If any changes are made to the under y ng co ect on. Chapter 12  Arrays and co ect ons   219 . Other . wh ch causes the IEnumerator to throw an InvalidOperationException. defined n the System::Collections::Generic namespace.V> A co ect on of key/va ue pa rs w th wh ch you can retr eve e ements by ndex as we as by key Stack<T> Accesses a st of e ements from the top on y by us ng Push and Pop operat ons The List<T> class The List<T> c ass. s a dynam ca y expandab e (and shr nkab e) array By defau t. This class was introduced before generics were added to . the snapshot w fa out of synchron zat on. which returns a pointer to some object that implements the IEnumerator interface. but the c ass prov des two stat c methods w th wh ch you can create read-on y and fixed-s ze Lists Note  The non-generic version of the List is System::Collections::ArrayList.NET. use of generic collections is preferred whenever possible because they are type-safe. a ert ng you that t no onger reflects the under y ng data Note  Any type that wants to provide enumerator access to its members must implement the IEnumerable interface. GetEnumerator. nstances of th s c ass are res zab e and wr tab e.

lst->Add(3). 1). Open the MyL st cpp source fi e and add the fo ow ng ne mmed ate y after the using namespace System. return 0. Console::WriteLine("Count={0}". } The defau t List constructor creates an empty List Because th s s a gener c type. Add the fo ow ng code to the main funct on int main(array<String ^> ^args) { Console::WriteLine("List Demo"). you need to spec fy the type that the List s to conta n. // Add some elements lst->Add(0). // Look at the count and capacity Console::WriteLine("Capacity={0}". lst->Capacity). // Adjust the capacity lst->Capacity = 10. lst->Count). // Create an empty List List<int> ^lst = gcnew List<int>(). Create a new CLR Conso e App cat on project named MyList 2. you’ find that the count s 0—not surpr s ng because you haven’t added anyth ng yet—and that the capac ty s a so 0 Us ng the fo ow ng a ternat ve constructor. ne using namespace System::Collections::Generic. you can spec fy a d fferent n t a capac ty // Create a List with a capacity of ten elements List<int> ^pal = gcnew List<int>(10). lst->Insert(1. lst->Capacity).The fo ow ng exerc se shows you how to create a List and man pu ate t 1. Console::WriteLine("Capacity={0}". n th s case int The next two nes use the Capacity and Count propert es to pr nt the current capac ty of the List and a count of how many objects t current y conta ns If you run th s code. The List c ass s defined n the System::Collections::Generic namespace By nsert ng a using d rect ve. you can use the name w thout hav ng to fu y qua fy t every t me 3. Console::WriteLine("Count is now {0}". lst->Add(2). lst->Count). 220  Microsoft Visual C++/CLI Step by Step .

wh ch means that t prov des much of the same funct ona ty ■ ■ The IList nterface prov des the Add. whereas Insert takes a zero-based ndex and nserts a new tem at that pos t on 4. for each(int i in lst) { Console::WriteLine(i). you can reduce ts capac ty to match the actua number of e ements stored by ca ng TrimToSize You can a so reset the capac ty of the List at any t me by us ng ts Capacity property The List doesn’t conta n any e ements unt you add some by us ng the Add or Insert funct ons Add appends a new tem to the end of the st. wh ch w search the List and remove the first occurrence 6. and IsReadOnly propert es The ICollection nterface prov des the CopyTo method. } If you want to remove more than one e ement. f you have stored a hand e to an object n the co ect on.If you exceed the capac ty when add ng e ements. IsFixedSize. Console::WriteLine("---Item removed---"). and SyncRoot propert es ■ The IEnumerable nterface prov des the GetEnumerator method ■ The ICloneable nterface prov des the Clone method You use these nterfaces to spec fy common funct ona ty for the co ect on c asses After you know how the nterface methods work. The syntax for remov ng tems from a List s s m ar to that used for retr ev ng them // Remove item at index 2 lst->RemoveAt(2). you can use the Remove funct on. and RemoveAt methods. Remove. p us the Item. IsSynchronized. t becomes eas er to use other co ect on c asses Chapter 12  Arrays and co ect ons   221 . Because List mp ements IEnumerator. you can pr nt out the contents of the List by us ng a for each oop for each (int i in lst) Console::WriteLine(i). t w automat ca y be doub ed If your array s too arge. the RemoveRange funct on takes a start ng ndex and a number of e ements to remove In add t on. Bu d and run the app cat on Other list operations The List<T> c ass mp ements the same nterfaces as the System::Array c ass d scussed ear er n the chapter. p us the Count. Insert. Clear. 5. IndexOf. Contains.

the method throws an ArgumentException 222  Microsoft Visual C++/CLI Step by Step . When you create a SortedList. you can use the name w thout hav ng to fu y qua fy t every t me 3. a SortedList has a defau t capac ty and w automat ca y ncrease ts capac ty as necessary Us ng a ternat ve constructors. a so defined n the System::Collections::Generic namespace. 1044). sl->Add("Dilbert". such as number and str ng c asses. 1110).The SortedList<K. int>(). 3375). wh ch a so ma nta ns key/ va ue pa rs. but the SortedList ma nta ns ts data n sorted-key order and a ows you to access tems by  ndex as we as by key SortedList sorts ts entr es two ways ■ ■ The objects stored n the SortedList can mp ement the IComparable nterface w th ts CompareTo method A the va ue types. and an int for the va ue As w th the List d scussed n the prev ous sect on. and by nsert ng a us ng d rect ve. Open the SortedL st cpp source fi e and add the fo ow ng ne mmed ate y after the using namespace System. Add the fo ow ng code to the main funct on to create a SortedList and add some data to t SortedList<String^. and you shou d mp ement t on any other user-defined types whose va ues can be ordered An externa comparer object can be prov ded. Create a new CLR Conso e App cat on project named SortedList 2. suppose you wanted to ma nta n a st of emp oyees’ names together w th the r phone extens ons A SortedList wou d work we n th s case. us ng the name as the key and the extens on as the va ue 1. sl->Add("Wally". The SortedList c ass s defined n the System::Collections::Generic namespace. sl->Add("Ted". int> ^sl = gcnew SortedList<String^. 2213). and you can tr m excess by us ng the Trim ToSize funct on The Add method takes key/va ue pa rs and adds them to the SortedList If the key a ready ex sts n the co ect on.V> c ass. you must spec fy the types for the key and the va ue w th n the ang e brackets In th s case. represents a co ect on of keys and va ues A SortedList s very s m ar to a Dictionary. mp ement th s nterface. we are us ng a String^ for the key.V> class The SortedList<K. ne using namespace System::Collections::Generic. sl->Add("Alice". wh ch mp ements the IComparer nterface w th ts Compare method The fo ow ng exerc se shows you how to create a SortedList and man pu ate t As an examp e. you can create SortedList c asses w th part cu ar n t a capac t es.

Each e ement of the SortedList s returned as a KeyValuePair object. but you can use nulls as values. In th s code.Value). else Console::WriteLine("Key not found"). you can use Remove to get r d of an tem by key RemoveByIndex does the same th ng by ndex. the ContainsKey and ContainsValue funct ons w return true f the co ect on conta ns a g ven va ue or key If you want to de ete tems from the co ect on.Note  Keys cannot be nulls. ke th s // Change the value associated with key 'Alice' sl["Alice"] = 5555. If the key a ready ex sts. as demonstrated here Console::WriteLine("Value for key 'Alice' is {0}". you can retr eve them by key. wh ch returns a bool to et you know whether t found a va ue int value = 0.Key. f t doesn’t ex st. if (sl->TryGetValue("Fred". Add some code to pr nt out the contents of the SortedList by us ng a for each oop for each (KeyValuePair<String^. int> kp in sl) Console::WriteLine("Key={0}. and Clear can be used to remove a entr es Chapter 12  Arrays and co ect ons   223 . kp. sl["Alice"]). the ndexer throws an except on As an a ternat ve to hand ng an except on. sl["Alice"]). you can use TryGetValue. Bu d and run the app cat on Other SortedList operations You can use the IndexOfKey and IndexOfValue methods to return the ndex of a g ven key or va ue. value={1}". Console::WriteLine("Value for 'Alice' is {0}". a new key/va ue pa r s created 3. and both of them w return –1 f the key or va ue you spec fy doesn’t ex st n the co ect on L kew se. In add t on to retr ev ng va ues by ndex. 4. ts assoc ated va ue s overwr tten. The ndexer uses the key to return ts assoc ated va ue f a match s found. value s passed through to TryGetValue by reference so that the funct on can update t 2. value). value)) Console::WriteLine("Value is {0}". You can a so mod fy entr es n the st by us ng the ndexer. kp. f no match s found. and you can use ts Key and Value propert es to retr eve the key and va ue 1.

they are both supported n C++/CLI Because the use of temp ates n C++/CLI s an advanced top c. consult the reference documentation. A though gener cs and temp ates do have some features n common. whereas a temp ate has been nstant ated at comp e t me Temp ates support features such as spec a zat on. and ts features m ght appea to deve opers ook ng for more performance and extens b ty Note  If you want more details of the STL/CLR library. at east) and seem n many cases to be do ng the same job Note  If you are new to C++ or have not encountered templates before. and a vers on that works w th managed types has been prov ded n the STL/CLR brary Th s has been done for two reasons F rst. you might want to skip this section on first reading. which.com/en-us/library/bb385954. gener cs are run-t me th s means that a gener c type s st gener c at run t me. and th s enab es them to cont nue to be product ve Second. wh ch temp ates do not The STL/CLR library One reason why temp ates are supported n C++/CLI s to perm t the use of the STL/CLR brary The Standard Temp ate L brary (STL) s part of standard C++ It s best known for prov d ng a set of h ghperformance. they are very d fferent n the way n wh ch they work. because they ook so s m ar (on the surface. non-type temp ate parameters. and temp ate temp ate parameters Gener cs don’t support these and are rather s mp er ■ Gener c types cannot nher t from a type parameter. as s the case w th temp ates ■ There s no metaprogramm ng support for gener cs ■ Gener c types support constra nts on type parameters. extens b e co ect on c asses Th s sect on can on y g ve the br efest overv ew of what the STL s and how t works The STL conta ners are standard n unmanaged C++ code. aspx.microsoft. many C++ deve opers are fam ar w th (and ke us ng) the STL conta ners. as of this writing. you can find at http://msdn. and ne ther of them can act comp ete y as a subst tute for the other For th s reason. you m ght be wonder ng how NET gener cs re ate to C++ temp ates.Generics and templates If you are fam ar w th standard C++. th s sect on on y g ves a br ef summary of the s m ar t es and d fferences between the two mechan sms ■ ■ Temp ates are comp e-t me. the STL s a ot more extens b e and configurab e than the NET co ect on c asses. 224  Microsoft Visual C++/CLI Step by Step .

// Use an iterator to print all the values in order vector<double>::iterator it = v1. i<10. they are po nt ng at the same pos t on The three concepts behind STL The STL s based on three concepts.begin(). // Append values for(int i=0. wh ch have far-reach ng consequences for how conta ners are wr tten and used The first concept s that of the container In STL. the pop back funct on removes an e ement from the end Iterators are c asses. you can prov de your own memory a ocator f you want And. } A vector s the equ va ent of an ArrayList a dynam ca y res zab e array The push back funct on adds an e ement to the end of a sequence. f you want to sort the contents n some part cu ar way. i++) v1.0). it != v1. and * to dereference them n order to get to the va ue at that pos t on The == and != operators are over oaded to compare pos t on f == for two terators returns true. it++) Console::WriteLine(*it). the ma n job of a conta ner s to ho d ts e ements A though th s m ght seem obv ous. so an terator to a vector<int> s a vector<int>::iterator You obta n an terator by ca ng the begin funct on. and f you were us ng a nked st.Here s a s mp e examp e to g ve you a fee for what STL/CLR code ooks ke #include "stdafx. a ways ca ed iterator. a though STL conta ners w a ocate memory for the r members. wh ch m ts the r adaptab ty For examp e. return 0. you cou d a so use push front to add va ues to the beg nn ng As you m ght expect. you can do th s by prov d ng your own custom externa funct on rather than hav ng to re y on the sort funct on that s bu t n to the conta ner Chapter 12  Arrays and co ect ons   225 .h" #include <cliext\vector> using namespace System. for(.push_back(i*2. many conta ner types n other brar es do a ot more bes des. int main(array<System::String ^> ^args) { // Create a vector of int vector<double> v1. that are defined w th n a conta ner.end(). using namespace cliext. wh ch returns an terator that po nts to the start of the sequence The end funct on returns an terator po nt ng to the end of the sequence. and you use th s to check when you get to the end You use terators ke po nters you can use ++ and –– to move them a ong the sequence.

.

Use the SortedList<> or Dictionary<> c asses. terate over the members of a managed array.. Use the List<> c ass. Create a dynam c array.In case you th nk that th s does not sound very effic ent. For examp e: array<Person ^> ^people = gcnew array<Person ^>(). Chapter 12  Arrays and co ect ons   227 . Use a for each oop. For examp e: List<Person> ^lst = new List<Person>(). for each (Person p in lst) Console::WriteLine(p). Create a managed array Use the gener c array<> type. Ma nta n a st of key/va ue pa rs.. means that very effic ent code s generated at run t me Quick reference To Do this Create a fixed s ze array of C++ bu t n types. mak ng heavy use of n ne code and temp ates. Use a nat ve C++ array. . the way that the STL has been wr tten.

.

but the M crosoft NET Framework has added support for them nto M crosoft Intermed ate Language (MSIL) so that they can be eas y mp emented n any NET programm ng anguage You’ see n th s chapter that propert es can often ead to a more natura sty e of programm ng w thout sacr fic ng robustness or v o at ng the pr nc p es of object-or ented programm ng What are properties? It s a ong-accepted pr nc p e of object-or ented programm ng that t’s a bad dea to g ve users d rect access to the data members that make up your c asses There are two ma n reasons for th s ■ ■ If users d rect y access data members. you w be ab e to ■ Descr be what propert es are ■ Exp a n how propert es are supported by C++/CLI ■ Imp ement propert es P ropert es have been ava ab e n some programm ng anguages—such as M crosoft V sua Bas c—for some t me. t’s recommended that you h de data members. they’re requ red to know about the mp ementat on of the c ass. a data member named date m ght be accessed us ng a pa r of member funct ons named set date and get date Th s method works fine. poss b y ead ng to app cat on fa ures or other undes rab e resu ts As a resu t. nd rect access has often been mp emented by us ng get and set members Thus. and that m ght m t your ab ty to mod fy the mp ementat on ater Users of your c asses m ght acc denta y—or de berate y—corrupt the data n objects by us ng nappropr ate va ues. but c ent code a ways has to ca the get and set funct ons d rect y 229 .CHAPTER 13 Properties After comp et ng th s chapter. mak ng them pr vate and g v ng nd rect access to them by us ng member funct ons In trad t ona C++.

Propert es n the NET Framework g ve you a way to mp ement a v rtua data member for a c ass
You mp ement the get and set parts of the property, and the comp er converts them nto ca s to the
get or set method as appropr ate
MyClass ^pmc = gcnew MyClass();
pmc->Name = "fred";
// calls the setter
s = pmc->Name;
// calls the getter

It appears to the user that MyClass has a rea data member ca ed Name, and the property can be
used n exact y the same way as a rea data member
Anyone who programmed n V sua Bas c wou d find the dea of mp ement ng propert es us ng
the get, set, and let methods fam ar In the NET Framework, propert es can be created and used
n any NET anguage, so you can create a c ass n V sua Bas c and st use ts propert es n a C++
app cat on, and v ce versa

The two kinds of properties
C++/CLI supports two k nds of propert es sca ar and ndexed
A scalar property g ves access to a s ng e va ue by us ng getter and setter code For examp e, a
Name property wou d mp ement getter and setter code to g ve access to the under y ng name data
It’s mportant to note that a property doesn’t have to represent a s mp e data member of the managed c ass; a property can represent der ved va ues For examp e, f a c ass has a date-of-b rth member, t wou d be poss b e to mp ement a property that ca cu ates the age Propert es can a so represent far more comp ex va ues, wh ch m ght nvo ve us ng data from other sources, such as search ng
databases or access ng URLs
An indexed property makes t poss b e for a property to be accessed as f t were an array, us ng the
trad t ona C++ square bracket notat on

Note  If you’ve ever come across the overloaded [ ] operator in traditional C++, you’ll find
that indexed properties provide similar functionality, but you don’t have to code the operator overload yourself.
Indexed propert es are a so mp emented by us ng getter and setter code, and the comp er automat ca y generates the requ red code so that c ents can use the square bracket notat on
The next sect ons n th s chapter demonstrate how to mp ement both sca ar and ndexed
propert es

230  Microsoft Visual C++/CLI Step by Step

Implementing scalar properties
As ment oned n the prev ous sect on, a sca ar property s one that g ves you access to a s ng e data
member by us ng getter and setter code The fo ow ng exerc se shows you how to mp ement sca ar
propert es In th s examp e, we’ use a s mp e Person c ass conta n ng name and age members
1. Start M crosoft V sua Stud o 2012 and create a new CLR Conso e App cat on project named

Properties
2. Add the fo ow ng c ass defin t on after the using namespace System; ne and before the main

funct on
ref class Person
{
String ^name;
int age;
public:
// Person class constructor
Person()
{
Name = "";
Age = 0;
}
// The Name property
property String ^Name
{
String ^get() { return name; }
void set(String ^n) { name = n; }
}
// The Age property
property int Age
{
int get() { return age; }
void set(int val) { age = val; }
}
};

The c ass has two pr vate data members that ho d the name and age of the person Propert es
are ntroduced by the property keyword, wh ch s fo owed by a type and then the property
name It s convent on to beg n property names w th a cap ta etter
The getter and setter are dec ared ns de the property and ook a ot ke nested funct ons The
getter s a ways ca ed get and has a return type that matches the property type The setter s
ca ed set, takes an argument of property type, and has a return type of void
You can use the property from C++ code as f t were a rea data member of the c ass Note
how the propert es are used n the constructor n preference to us ng the data members
d rect y; you w see why th s s a good dea short y

Chapter 13  Propert es   231

Note  The property names in this example are the same as the names of the underlying data members, but capitalized. It is a widespread convention in C# code that
function and property names are capitalized. Therefore, to fit into the .NET world, it
is a good idea if your property names are capitalized, as well.
3. Add the fo ow ng code to main to test the property
int main(array<String ^> ^args)
{
// Create a Person object
Person ^p = gcnew Person();
// Set the name and age using properties
p->Name = "fred";
p->Age = 77;
// Access the properties
Console::WriteLine("Age of {0} is {1}", p->Name, p->Age);
return 0;
}

After a Person object has been created and n t a zed, the name and age members can be
accessed through the Name and Age v rtua data members that have been generated by the
comp er
4. Bu d and run the app cat on

Errors in properties
What happens f a property get or set method encounters an error? Cons der the fo ow ng code
// Set the name and age using properties
p->Name = "spiro";
p->Age = -31;

How can the Age property commun cate that t sn’t happy w th a negat ve va ue? Th s s tuat on s
a good one n wh ch to use except ons, wh ch are d scussed n Chapter 11, “Except on hand ng ” You
cou d mod fy the setter funct on to check ts argument ke th s
void set(int val)
{
if (val < 0)
throw gcnew ArgumentException("Negative ages aren't allowed");
age = val;
}

If anyone tr es to set the age to a negat ve va ue, an ArgumentException w
ca er that there s a prob em

232  Microsoft Visual C++/CLI Step by Step

be thrown to a ert the

Auto-implemented properties
Many propert es s mp y ass gn to and return a data member, as shown n the fo ow ng
String ^name;
property String ^Name
{
String ^get { return name; }
void set(String ^n) { name = n; }
}

When that s the case, you can get the comp er to mp ement the getter and setter, and t w
generate a backing variable to store the data You don’t see th s var ab e, but you access t nd rect y
through the property getter and setter
Th s means that you can mp ement the Name property very s mp y, as demonstrated here
property String ^Name;

In the next short exerc se, you can dec are and use an auto- mp emented property n your Person
c ass
1. Mod fy your Person c ass, prov d ng an automat c mp ementat on for the Name property and

remov ng the data member
2. Bu d and run the app cat on, wh ch shou d work exact y the same as before

Because you used the property n the constructor rather than ass gn ng to the data member,
chang ng to an auto- mp emented property st works
Whenever you use auto- mp emented propert es, you must use the property w th n your c ass
when ass gn ng to or read ng the va ue because you don’t know the name of the back ng var ab e
that the comp er creates

Read-only and write-only properties
You don’t a ways have to prov de get and set methods for a property If you don’t prov de a set
method, you end up w th a read-on y property If you om t the get method, you’ have a wr te-on y
property (wh ch s poss b e, but a ot ess common than the read-on y var ety)
The fo ow ng exerc se shows how to mp ement a read-on y property, and t a so ustrates how to
create a der ved property You’ change the Person c ass from the prev ous exerc se so that t nc udes
a date of b rth rather than an age The der ved Age property w then ca cu ate the person’s age from
the date of b rth; t’s obv ous y a der ved property because you can’t change someone’s age w thout
chang ng h s or her date of b rth, as we It’s a so obv ous y a read-on y property because t’s a ways
ca cu ated and cannot be set by users of the c ass
1. E ther start a new CLR Conso e App cat on project or mod fy the one from the prev ous

exerc se

Chapter 13  Propert es   233

2. Type or ed t the defin t on of the Person c ass so that t ooks ke the fo ow ng code P ace t

after the using namespace System; ne and before the main method
ref class Person
{
int dd, mm, yyyy;
public:
// Person class constructor
Person(String ^n, int d, int m, int y)
{
Name = n;
dd = d; mm = m; yyyy = y;
}
// Auto implementation of the Name property
property String ^Name;
// The read-only Age property
property int Age
{
int get() {
DateTime now = DateTime::Now;
return now.Year - yyyy;
}
}
};

The c ass now has three nteger data members to ho d the date of b rth, n t a zed n the
constructor
The Age property now has on y a get method, wh ch retr eves a DateTime object represent ng
the current date and t me and then ca cu ates the age from the d fference between the current year and the stored year
3. Use the Name and Age propert es as you d d n the prev ous examp e
int main(array<String ^> ^args)
{
// Create a Person object
Person ^p = gcnew Person("fred", 4,9,1955);
// Access the Name and Age properties
Console::WriteLine("Age of {0} is {1}", p->Name, p->Age);
return 0;
}

You can’t set the Age property because you haven’t prov ded a setter Th s w
p er error f you try to ass gn to the Age property
4. Bu d and run the app cat on

234  Microsoft Visual C++/CLI Step by Step

resu t n a com-

Properties, inheritance, and interfaces
Propert es are first-c ass members of types, on the same eve as member funct ons and data members Th s means that you can use them n nher tance and n nterfaces Propert es can be v rtua and
even pure v rtua , and t sn’t necessary for both the get and set methods to have the same v rtua
spec fier
Th s exerc se shows you how to use a v rtua property when nher t ng from a base c ass
1. Create a new CLR Conso e App cat on project named PropertyInheritance
2. Immed ate y after the using namespace System; ne, define an abstract c ass ca ed Shape
public ref class Shape abstract
{
public:
virtual property double Area;
};

Th s c ass defines a property ca ed Area that s v rtua and wh ch can be overr dden by
subc asses
3. Add the defin t on for a Circle c ass, wh ch nher ts from Shape and wh ch a so mp ements

the Area property
public ref class Circle : Shape
{
double radius;
public:
Circle(double r)
{
radius = r;
}
virtual property double Area
{
double get() override {
return Math::PI * radius * radius;
}
}
};

The constructor for Circle takes a va ue for the rad us, wh ch s used n the Area property to
ca cu ate the area of the c rc e Note the p acement of the mod fiers on the Area property
dec arat on It s dec ared as virtual, and the get s dec ared as an override
4. Add a s mp e funct on to take a Shape and pr nt out ts area
void printArea(Shape ^s)
{
Console::WriteLine("Area is {0}", s->Area);
}

Chapter 13  Propert es   235

5. Create a Circle n main and pass t to the printArea funct on
Circle ^c = gcnew Circle(4.0);
printArea(c);

6. Bu d and run the app cat on

You w see that even though the printArea funct on has a Shape as ts argument type, t w
use the Circle mp ementat on of Area at run t me

Implementing indexed properties
Now that you know how to mp ement a sca ar property, et’s move on to cons der ndexed propert es, wh ch are a so known as indexers These are usefu for c asses that have data members that are
co ect ons of tems, and where you m ght want to access one of the tems n the co ect on

The Bank example
Cons der as an examp e a Bank c ass that ma nta ns a co ect on of Accounts If you’re not us ng propert es, you’d tend to see code such as the fo ow ng be ng used to access members of the Bank c ass
// Get a reference to one of the Accounts held by the Bank
Account ^acc = theBank->getAccount(1234567);

An ndexed property makes t poss b e for you access the Account members by us ng array notat on, such as s demonstrated here
// Get a reference to one of the accounts held by the Bank
Account ^acc = theBank->Account[1234567];

You can mp ement get and set methods for ndexed propert es so that you can use them on both
s des of the equa s gn (=) The fo ow ng code fragment uses two propert es, w th the first ndexed
property g v ng access to an account, and the second g v ng access to an overdraft m t
// Set the overdraft limit for one of the accounts
theBank->Account[1234567]->OverDraft = 250.0;

Implementing the Bank class
The onger exerc se that fo ows wa ks you through mp ement ng the Bank and Account c asses, and t
a so shows you how to create and use both sca ar and ndexed propert es
1. Start V sua Stud o 2012 and create a new CLR Conso e App cat on project named Banker

236  Microsoft Visual C++/CLI Step by Step

2. Add a new C++ header fi e named Bank.h to the project When the fi e opens n the ed tor,

ed t the c ass dec arat on so that ooks ke th s
#pragma once
ref class Bank
{
public:
Bank();
};

3. Add an mp ementat on fi e ca ed Bank.cpp to the project When t opens n the ed tor, ed t

the code so that t ooks ke th s
#include "stdafx.h"
using namespace System;
#include "Bank.h"
Bank::Bank()
{
Console::WriteLine("Bank: constructor");
}

4. To ensure that everyth ng s correct, open the Banker cpp fi e and add code to the main func-

t on to create a Bank object
int main(array<String ^> ^args)
{
Console::WriteLine("Bank Example");
// Create a Bank object
Bank ^theBank = gcnew Bank();
return 0;
}

5. You must a so nc ude Bank h from the Banker cpp fi e so that the comp er w

know where to
ocate the dec arat on of the Bank c ass Therefore, add the fo ow ng code to Banker cpp after
the #include “stdafx.h” ne

#include "Bank.h"

6. Comp e and run the app cat on You shou d see the constructor message be ng pr nted on

the conso e

Chapter 13  Propert es   237

Adding the Account class
The next stage nvo ves creat ng the Account c ass n very much the same way
1. Add a header fi e named Account.h to the project Ed t the header fi e so that t ooks

ke th s
#pragma once
using namespace System;
ref class Account
{
public:
Account();
};

2. Add an mp ementat on fi e named Account.cpp that ooks ke th s
#include "stdafx.h"
using namespace System;
#include "Account.h"
Account::Account()
{
Console::WriteLine("Account: constructor");
}

3. Add some structure to the Account c ass Accounts w

have an account number, a ba ance, and an overdraft m t, so add three pr vate members to the Account c ass defin t on n
Account h, as shown n the fo ow ng

private:
long accNumber;
double balance;
double limit;

// the account number
// the current balance
// the overdraft limit

4. Open Account cpp Ed t the constructor defin t on and mp ementat on as fo ows so that three

va ues are passed n and used to n t a ze these three var ab es
Account::Account(long num, double bal, double lim)
{
Console::WriteLine("Account: constructor");
// Basic sanity check
if (num < 0 || lim < 0)
throw gcnew ArgumentException("Bad arguments to constructor");
// Initialize values
accNumber = num;
balance = bal;
limit = lim;
}

238  Microsoft Visual C++/CLI Step by Step

Remember that you w
header fi e, as we

need to mod fy the dec arat on of the constructor n the Account h

The bas c san ty check s mp y checks that the account number and overdraft m t aren’t negat ve If they are, t throws an ArgumentException

Creating Account class properties
After the Account c ass has been constructed, you can add propert es to g ve access to the three data
members A three members are sca ar, so the propert es are easy to mp ement
1. Add a pub c property to Account h to a ow read-on y access to the account number, as

shown here
property long AccountNumber
{
long get() { return accNumber; }
}

You can add the funct on defin t on n ne n the c ass defin t on Remember to put t n the
pub c sect on
2. You a so need to add a read-on y property for the ba ance member, because n rea

fe, you

don’t want peop e s mp y mod fy ng the ba ances n the r accounts from code
property double Balance
{
double get() { return balance; }
}

3. Add a read/wr te property for the overdraft m t because t’s qu te poss b e that the m t

m ght be changed from t me to t me
property double OverdraftLimit
{
double get() { return limit; }
void set(double value) {
if (value < 0)
throw gcnew ArgumentException("Limit can't be negative");
limit = value;
}
}

If you choose to mp ement these propert es n ne n the c ass defin t on, you’ need to add a
using namespace System; ne or fu y qua fy the name of ArgumentException before the code
w comp e

Chapter 13  Propert es   239

h" The using dec arat on w make t eas er to use a List n the Bank c ass. #include "Account. and you’ need to reference the Account c ass ater 2.4. return true. Open the Bank h header fi e Add the fo ow ng two nes of code mmed ate y after the #pragma once ne at the top of the fi e using namespace System::Collections::Generic. so the next step s to mod fy the Bank c ass to ho d a co ect on of Account objects Rather than des gn someth ng from scratch. ensur ng that t’s pr vate List<Account^> ^accounts. as demonstrated here // Create an Account object Account ^theAccount = gcnew Account(123456. 0. Add the code for the pub c AddAccount method n ne n the header fi e as fo ows bool AddAccount(Account ^acc) { // check if the account is already in the list if (accounts->Contains(acc)) return false. the List s go ng to ho d Account hand es 3. Because List s a gener c co ect on.0). you need to spec fy what t s go ng to ho d In th s case. } 240  Microsoft Visual C++/CLI Step by Step . 0. Add a List var ab e to the Bank c ass. and then add code to create an Account object. “Arrays and co ect ons”) to ho d the Accounts Implementing the Add and Remove methods The Add and Remove methods prov de a way to man pu ate the co ect on of Accounts he d by the Bank c ass 1. else accounts->Add(acc). you’ use the System::Collections::Generic::List c ass (wh ch s ntroduced n Chapter 12. Bu d and run the app cat on and check the output Adding accounts to the Bank class The purpose of the Bank c ass s to ho d Accounts.0. 5. Test out your mp ementat on by add ng some code to the main funct on n Banker cpp to create a new Account object and access ts propert es Inc ude the Account h fi e.

double value) { . 6. you nc ude the ndex as the first parameter to the getter and setter property double Balance[long] { double get(long idx) { . Add code for the RemoveAccount funct on.. } } Chapter 13  Propert es   241 . the Account s added to the co ect on 4. and an ndexed property prov des a good way to access accounts by account number Indexed propert es work n a very s m ar way to sca ar propert es. you’ probab y want to do so by the account number. f present. } RemoveAccount checks whether an Account s n the st and. Bu d the app cat on to ensure that there are no errors Implementing an indexed property to retrieve accounts You can now man pu ate the co ect on of Accounts. removes t It sn’t necessary to ca Contains because RemoveAccount w s ent y do noth ng f you try to remove an tem that sn’t n the st However. wh ch works n a very s m ar way bool RemoveAccount(Account ^acc) { // check if the account is already in the list if (accounts->Contains(acc)) { accounts->Remove(acc).AddAccount takes a hand e to an Account object and then uses the List::Contains method to check whether the account a ready ex sts n the co ect on If t doesn’t.. users m ght be nterested n know ng that the account they’re try ng to remove sn’t n the co ect on a ready 5. but you show the comp er that you are defin ng an ndexed property by nc ud ng the ndex type n square brackets after the property name property double Balance[long] Th s nforms the comp er that we are defin ng an ndexed property ca ed Balance that w use a long as ts ndex type When you define the ndexed property. add ng and remov ng tems If you want to ook up a part cu ar account. Add the fo ow ng ne of code to the Bank constructor to create the List member accounts = gcnew List<Account^>(). } else return false.. } void set(long idx. return true..

} } Default properties You m ght wonder why the property s ca ed “defau t ” It s poss b e for a c ass to have mu t p e ndexers. You norma y use the defau t ndexer for the property that s most often used When you find an account whose number matches the one passed n. In th s exerc se you w mp ement an ndexed property to retr eve Account objects Because you on y need to retr eve Account hand es and not set them. an except on s thrown because try ng to access a nonex stent account s equ va ent to read ng off the end of an array It s a ser ous error that shou d be s gna ed to the ca er 242  Microsoft Visual C++/CLI Step by Step . ts hand e s returned If no such account s found. Open the Bank h header fi e 2. such as n the fo ow ng // Get account 12345 Account ^acc = myBank[12345]. you can use the ndex to find the appropr ate va ue You can use the ndexer ke th s // Get the balance for account 12345 double bal = myBank->Balance[12345]. can be used d rect y on an object. on the other hand. you’ mp ement a read-on y ndexed property 1. Add the fo ow ng code to mp ement the property // Indexed property to return an account property Account ^default[long] { Account ^get(long num) { for each(Account ^acc in accounts) { if (acc->AccountNumber == num) return acc. } throw gcnew ArgumentOutOfRangeException("No such account"). but you have to use them exp c t y by name An ndexed property ca ed defau t.W th n the getter and setter.

100. theBank->AddAccount(accountTwo). Console::WriteLine("Account Number is {0}". // Use the indexed property to access an account Account ^pa = theBank[234567]. theBank->AddAccount(accountThree).3. Test out the Bank c ass by add ng some code to the main funct on n Banker cpp You’ need to start by ensur ng that the Bank h and Account h header fi es are nc uded Next add some code so that your main funct on s s m ar to the fo ow ng int main(array<String ^> ^args) { Console::WriteLine("Bank example"). Bu d and run the app cat on and then check the output Chapter 13  Propert es   243 .0).0.0). } After creat ng a Bank and a number of Account objects. pa->AccountNumber). 1000. return 0. 10000.0. Account ^accountTwo = gcnew Account(234567.0).0. Account ^accountThree = gcnew Account(345678. // Create some accounts Account ^accountOne = gcnew Account(123456. 1000. // Create a bank Bank ^theBank = gcnew Bank(). 100. // Add them to the Bank theBank->AddAccount(accountOne). you add the Account objects to the Bank co ect on by ca ng Add You can then use the ndexed property to access an account by number and use that po nter to d sp ay the ba ance Test the property by pass ng n an account number that doesn’t ex st and check that an except on s thrown 4. 0.

Quick reference To Do This Create a property for a C++ c ass. } void set(int w) { . mp ement an ndexed property. mp ement a wr te on y property.. For examp e: property Amount ^Pay[Person] { Amount ^get(Person^) { . For examp e: property int Weight { int get() { . and whose get and set methods take an ndex va ue that s used to determ ne wh ch va ue to get or set.. mp ement a property that spec fies an ndex type n square brackets. } } mp ement a s mp e property that requ res no og c n ts get or set methods. } } . Use an auto mp emented property. Use the property keyword and mp ement get and/or set methods.. mp ement on y the set method... For examp e: property String ^Name. mp ement a read on y property.. mp ement on y the get method.

so they’re of no use n the NET env ronment. funct on po nters are a C++ anguage feature. you w ■ Understand what de egates are ■ Create and use de egates ■ Exp a n what events are ■ Create and use events be ab e to D e egates and events are extreme y powerfu and mportant constructs n the M crosoft NET Framework Events n part cu ar are used w de y n GUI app cat ons as a means of commun cat ng between components. and they a so form the bas s for the NET event mechan sm d scussed n the second part of th s chapter 245 . where features need to be access b e from many anguages If you’re nterested n know ng more about funct on po nters and how they work. and t’s a very usefu way of mp ement ng mechan sms such as event hand ers Unfortunate y.CHAPTER 14 Delegates and events After comp et ng th s chapter. see the s debar that fo ows De egates are the NET equ va ent of funct on po nters. but both de egates and events can be used to good effect n non-GUI code What are delegates? The funct on po nter mechan sm n C and C++ has been used by programmers for many years. and they can be created and used from any NET anguage They can be used by themse ves.

= SquareRoot(d).0.What are function pointers? W th a norma po nter. so the first ne takes the address of the funct on and stores t n pf The second ne uses pf to nvoke the funct on You can use a funct on po nter to nvoke any funct on that matches ts s gnature. for examp e). the name of a funct on w thout any parentheses eva uates to ts address. wh ch can be used to nvoke any funct on that takes two int parameters and returns a long The fo ow ng funct on prototype has the r ght s gnature long func1(int. 246  Microsoft Visual C++/CLI Step by Step . int). You can nvoke the funct on nd rect y ke th s pf = func1. you can use the same funct on po nter to nvoke d fferent funct ons And. you can access a var ab e through the address t conta ns W th a funct on po nter. = TenToThePowerOf(d). // assign address of func1 to pf // invoke func1() through pf Remember that n C++. result = Square(d). you can execute a funct on by us ng the address of the rout ne In exact y the same way that you can use a po nter to ho d the addresses of d fferent var ab es. and that’s what makes funct on po nters usefu for event hand ng You can define a funct on po nter to represent the event hand er and then hook up the actua funct on to the po nter ater What is the purpose of delegates? A de egate s a c ass whose purpose t s to nvoke one or more methods that have a part cu ar s gnature It s bas ca y an nd rect way of execut ng a funct on by de egat ng to an ntermed ate object Here’s a s mp e examp e to show when you m ght want to use a de egate Imag ne that I want to be ab e to perform operat ons on numbers by pass ng a number nto a funct on and gett ng a transformed va ue back. int). long l = pf(3. The code dec ares a funct on po nter ca ed pf. = Cube(d). n the same way that norma po nters must have a type assoc ated w th them (so that you can on y access doub es w th a double*.4). funct on po nters must have a funct on s gnature assoc ated w th them The fo ow ng ne of code shows how you dec are a funct on po nter n C++ long (*pf)(int. as demonstrated n the fo ow ng double double result result result d = 3.

can be bound to any funct on that takes one double as an argument and returns a double Implementing delegates Now that you have defined a de egate. Start M crosoft V sua Stud o 2012 and create a new CLR Conso e App cat on project named Delegate 2. The delegate keyword s used to define a de egate It m ght ook as though th s s a funct on prototype for a funct on named NumericOp. ne delegate double NumericOp(double). and System::MulticastDelegate as the base for de egates that can ca more than one method A de egates n C++/CLI are mu t cast de egates Defining delegates Th s exerc se uses the numer ca operat ons examp e from the prev ous sect on to show you how to create and use a s mp e de egate n C++/CLI code 1. Open the De egate cpp source fi e and add the defin t on of a de egate to the top of the fi e. I want to use the de egate to ca one method at a t me. but t’s actua y defin ng a de egate type that nher ts from System::MulticastDelegate Th s de egate type. and for other c asses to attach funct ons to the de egate and use t You’ see examp es of th s use of de egates ater n the chapter when we cover events In th s case. mmed ate y after the using namespace System. but I can a so define other methods and ca them through the de egate—prov ded that they are a so funct ons that take a double and return one Th s makes t poss b e for one c ass or component to define a de egate. you can’t use a de egate to ca a g oba funct on or a funct on that’s a member of an unmanaged C++ c ass Chapter 14  De egates and events   247 . I can define a mechan sm by wh ch I can ca any of those methods because they a have the same s gnature Not on y can I ca any of the four methods above.In each case. you can wr te code to use t to ca funct ons One of the ru es for us ng de egates s that you can on y use a de egate to ca funct ons that are members of C++/CLI c asses. named NumericOp. I’m ca ng a funct on that has the same s gnature one that takes a double and returns a double as ts resu t W th de egates. but t’s poss b e to attach more than one funct on to a de egate A the funct ons are ca ed n order when the de egate s nvoked The NET Framework defines the System::Delegate c ass as the base for de egates that ca a s ng e method.

so you use the & operator to spec fy the address of Ops::square The object po nted to by op s now set up so that t w ca the square funct on when t s nvoked. as shown here // Declare a delegate NumericOp ^op = gcnew NumericOp(&Ops::Square). Console::WriteLine("Result is {0}". so you can now create a NumericOp object The constructor takes one argument th s s the address of the funct on that s to be assoc ated w th the de egate. When you dec ared the de egate. } }. Th s managed c ass conta ns one pub c stat c method. and t w take exact y the same arguments (and return the same type) as Ops::square Note  You can’t change the function that a delegate invokes after it has been created. so add the fo ow ng c ass to your source code fi e. result). Cont nue w th the project from the prev ous exerc se A the funct ons we want to ca need to be stat c members of a c ass. This is one respect in which delegates differ from C++ function pointers. wh ch s mp y takes a number and returns ts square 2.0). 3. just above the main funct on ref class Ops { public: static double Square(double d) { return d*d. you created a new type named NumericOp. Create a de egate n the main funct on of the app cat on. Bu d and run the app cat on 248  Microsoft Visual C++/CLI Step by Step . 4.Calling static member functions by using delegates Let’s start by ook ng at the s mp est case ca ng stat c member funct ons by us ng a de egate 1. Every de egate has an Invoke method that you can use to ca the funct on that has been bound to the de egate Invoke w take the same arguments and return the same type as the funct on be ng ca ed Add the fo ow ng nes to use op to ca the square funct on // Call the function through the delegate double result = op->Invoke(3.

You can now eas y create another stat c member. myObject. There are two th ngs that you m ght not ce about th s code The first s that you have reused the op reference to refer to the new de egate object Th s means that the or g na de egate that you used to ca Square s no onger referenced. th s t me.5. as ustrated here // Declare a delegate bound to a non-static member MyDelegate ^pDel = gcnew MyDelegate(myObject. a nonstat c member funct on must be ca ed on an object. but t’s a so poss b e for a de egate to ca more than one funct on w th a s ng e ca to Invoke A de egate that does so s ca ed a multicast delegate and s der ved from the System::MulticastDelegate c ass Chapter 14  De egates and events   249 . Bu d and run the app cat on and check that t runs as you expect Calling non-static member functions by using delegates You can a so ca non-stat c member funct ons of c asses by us ng de egates By defin t on. thus. so you need to spec fy to the de egate the funct on t’s go ng to ca and the object t’s go ng to use You do so n the de egate’s constructor. create a de egate. Console::WriteLine("Result of Cube() is {0}". result = op(3. you can actua y om t the Invoke keyword. The constructor spec fies the address of an object. however. result). } 6. and a member funct on be ongng to the c ass to wh ch myObject be ongs Invok ng th s de egate s equ va ent to d rect y ca ng myObject->MyFunction Using multicast delegates We’ve seen how t’s poss b e to use a de egate to ca a s ng e funct on. and ca the funct on Test th s out by add ng to the Ops c ass a second pub c stat c member ca ed Cube static double Cube(double d) { return d*d*d.0). pass t the address of the Cube funct on n the constructor // Create a second delegate and use it to call cube op = gcnew NumericOp(&Ops::Cube). treat ng the de egate as f t were a funct on ca tse f 7. &MyClass::MyFunction). s can be garbage-co ected The second s that there s no exp c t ca to Invoke To m rror how de egates work n C# (and how funct on po nters work n unmanaged C++). Create another de egate n the same way as the first.

each of wh ch conta ns a stat c member funct on ref class Client1 { public: static void NotifyFunction1(int n) { Console::WriteLine("Client1: got value {0}". Create a new CLR Conso e App cat on project named Multicast 2. n). ref class Client2 { public: static void NotifyFunction2(int n) { Console::WriteLine("Client2: got value {0}". a mu t cast de egate s bu t up by comb n ng other de egates The fo ow ng exerc se shows you how to create and use a mu t cast de egate 1.Note  All delegates that you create in C++/CLI by using the delegate keyword are multicast delegates. you’ see that t takes two or more Delegate objects as ts arguments You don’t bu d up a mu t cast de egate by spec fy ng more funct ons to add to ts nvocat on st Instead. mmed ate y after the using namespace System. These two c asses are a most dent ca . define two c asses at the start of your project. A de egate objects have an invocation list that ho ds the funct ons to be ca ed The nvocat on st for a norma de egate has one member You can man pu ate the nvocat on sts for mu t cast de egates by us ng the Combine and Remove methods. Open the Mu t cast cpp source fi e and add the defin t on of a de egate to the top of the fi e. n). a though th s s se dom done n pract ce If you ook at the documentat on for the Combine method. both defin ng a s ng e stat c member funct on that has the s gnature requ red by the de egate 250  Microsoft Visual C++/CLI Step by Step . You’re go ng to ca two funct ons through the mu t cast de egate Because a funct ons ca ed by de egates have to be members of a managed c ass. named NotifyDelegate. } }. ne delegate void NotifyDelegate(int). } }. to any funct on that takes one int as an argument and doesn’t return anyth ng 3. You can b nd th s de egate.

del4(5). you shou d see two nes of output. each of wh ch b nds to one of the stat c methods Console::WriteLine("Multicast Delegates"). as shown n the fo ow ng screen shot Note that the funct ons are ca ed n the order n wh ch the de egates are comb ned. you need to create two norma de egates (as you d d n the prev ous exerc se) and comb ne them nto a mu t cast de egate So. You want to ca the two stat c member funct ons through one de egate. Remember that you don’t have to ca Invoke exp c t y When you bu d and run the app cat on. del3(5). just as you d d n the prev ous exerc se 5. Bu d a mu t cast de egate from del1 and del2 by us ng the += operator. At th s stage. Console::WriteLine("Invoking del4"). del3 += del1. as shown n the fo ow ng // Create a third delegate from the first two NotifyDelegate ^del3. 6.4. but you can’t create a de egate to b nd to two funct ons d rect y Instead. del3 += del2. so f you want to change the order. define two de egates n the main funct on. you’ need to change the way you create the mu t cast 7. You can now nvoke the mu t cast de egate as norma // Invoke the multicast delegate Console::WriteLine("Invoking del3"). Chapter 14  De egates and events   251 . // Create two delegates NotifyDelegate ^del1 = gcnew NotifyDelegate(&Client1::NotifyFunction1). you cou d nvoke both of the de egates. You can use th s de egate as the bas s for mak ng up another one // Create a second multicast delegate and invoke it NotifyDelegate ^del4 = del3 + del3. NotifyDelegate ^del2 = gcnew NotifyDelegate(&Client2::NotifyFunction2).

use a de egate to ca a funct on that returns a resu t Here s an examp e ref class JMath { public: static double Square(double d) { return d*d. wh ch resu ts n the output shown n the fo ow ng screen shot when you nvoke t Not ce how you can use the + operator to compose de egates at construct on t me 8. you can use the –= operator to remove an tem from a de egate’s nvocat on st // Remove an item del3 -= del2. t w be removed In th s examp e.3). What happens f you create a mu t cast de egate that ca s severa such funct ons? Wh ch resu t w be returned? It s most norma to use funct ons that don’t return a va ue w th mu t cast de egates. // Bind a delegate to Math::square MathOp ^m = gcnew MathOp(&JMath::Square).In th s case. you have removed del2 from del3. You spec fy the hand e of the de egate that you want to remove on the r ght s de of the –= operator If the de egate to be removed ex sts n the nvocat on st of the first de egate. but 252  Microsoft Visual C++/CLI Step by Step . del3(5). Console::WriteLine("Invoking del3"). // Delegate to call a function that returns a double delegate double MathOp(double d). As the fina part of th s exerc se. } }. // Invoke the delegate double result = m(3. of course. on y del1 s executed Delegates that return a result You can. you’re comb n ng the nvocat on st of del3 tw ce. when you nvoke del3.

standard mechan sm by wh ch event sources (such as a button) hook up w th event rece vers (such as a form) Events n the NET Framework mp ement a pub sh-andsubscr be mechan sm. you m ght want to wa k over the st of de egates. they are used as part of a user nterface and are conta ned by some other tem Th s tem s usua y a form. and events are very heav y used n GUI programm ng As an examp e. wh ch adds them to ts de egates When the t me comes to fire the event. } What are events? Most. wh ch you can do by us ng the GetInvocationList funct on w th n a for each oop. such as Click. and as s ustrated n the d agram that fo ows. so d sm ss the d a og box” or “the user c cked the Pr nt button on the too bar. f not a . t sn’t too hard to see how th s works An event source dec ares a de egate for each event that t wants to generate. such as a too bar The who e po nt of hav ng a button on a form s so that the user can c ck t to s gna h s ntent to the app cat on and convey nstruct ons For examp e. so pr nt the document ” Events prov de a forma zed. as shown here for each (MathOp ^m in myMultiDelegate->GetInvocationList()) { double val = m(…). “the user c cked the OK button. thus ca ng the requ s te funct ons n the rece vers Chapter 14  De egates and events   253 .there s noth ng to stop you from ca ng funct ons that do return a va ue Usua y. a though th s s mp ementat on dependent If you want to be sure of retr ev ng a part cu ar va ue (or gett ng va ues from ntermed ate steps). the resu t of the ast funct on executed w be returned. but t cou d a so be some other contro . GUI p atforms support the dea of events. the event source ca s Invoke on the de egate. cons der a button Buttons don’t ex st on the r own. where event sources make pub c the events that they w ra se—they pub sh them—and event rece vers nform the source as to wh ch events they’re nterested n—they subscr be to events Event rece vers can a so unsubscr be when they no onger want to rece ve a part cu ar event Events n the NET Framework are based on de egates. and so on An event rece ver then defines su tab e methods and passes them to the event source. DoubleClick.

os ng any b nd ngs that m ght have been set up by other c ents Events so ve these two prob ems An event uses a de egate to prov de the under y ng mechan sm. Create a new CLR Conso e App cat on project named Event 2. but t refines the behav or of a de egate n two ways ■ ■ An event can on y be fired by the type that dec ares t C ents can on y add and remove event hand er funct ons us ng += and –= They cannot use = to reset the nvocat on st Implementing an event source class The actua event mechan sm s mp fies the syntax so that you don’t have to dea w th de egates d rect y. so open the Event cpp source fi e and define the fo ow ng two de egates mmed ate y after the using namespace System. 254  Microsoft Visual C++/CLI Step by Step . two events w be used. and you cou d b nd your hand er funct on to t by us ng the += operator There are two prob ems w th th s. so define a de egate for each of the events ra sed by the source In th s examp e. on y the button shou d be ab e to nvoke ts c ck de egate to say t has been c cked The second prob em s that even though c ents cou d add and remove event hand ers by us ng the += and –= operators. ne // Delegates delegate void FirstEventHandler(String^).How do events differ from delegates? Peop e are somet mes confused about the d fference between events and de egates because they seem to be do ng very much the same task You have seen how a de egate prov des a way to execute a funct on nd rect y. and th s cou d be used to mp ement event hand ng a button cou d expose a de egate object for the c ck event. delegate void SecondEventHandler(String^). and th s means that anyone cou d nvoke the de egate Th s sn’t rea y des rab e. Event sources and rece vers use de egates. and t’s des gned to fit n w th the event mechan sm that a ready ex sts n M crosoft V sua Bas c The fo ow ng exerc se takes you through creat ng an event source c ass and event rece ver c asses that reg ster themse ves w th the source and use the events when they’re fired 1. t s a so poss b e to use the p a n = operator Th s wou d reset the nvocat on st to conta n a s ng e tem. however The first s that the button’s de egate wou d have to be pub c n order to et c ents b nd to t.

but you can make the data passed as comp ex as you want 3.The de egates define the s gnatures of the methods that event rece vers must mp ement to hand e the events. // Event raising functions void RaiseOne(String ^msg) { OnFirstEvent(msg). so they’re often g ven names that end w th Handler Each of these events w s mp y pass a str ng as the event data. The first th ng to note s the use of the event keyword to dec are two events You need one event dec arat on for each event that you want to ra se. and ts type s a hand e to the de egate assoc ated w th the event So. } void RaiseTwo(String ^msg) { OnSecondEvent(msg). the type s FirstEventHandler to match the FirstEventHandler de egate Us ng the event keyword causes the comp er to generate a ot of de egate hand ng code for you. f you’re nterested n exact y what’s go ng on. } }. Add the mp ementat on of the event source c ass to the source fi e // Event source class ref class EvtSrc { public: // Declare the events event FirstEventHandler ^OnFirstEvent. event SecondEventHandler ^OnSecondEvent. n the case of the first event object. see the s debar that fo ows You can then use the event objects n the EvtSrc c ass to ra se the events by us ng them as f they were funct on ca s and pass ng the appropr ate argument Chapter 14  De egates and events   255 .

public: }. so the next th ng you need s a c ass that w sten for events and act upon them when they’ve been generated 1. wh ch ca s the method for you remove OnFirstEvent. Cont nue w th the project from the prev ous exerc se and add a new c ass to the project named EvtRcv // Event receiver class ref class EvtRcv { EvtSrc ^theSource. save t away n the EvtSrc member EvtRcv(EvtSrc ^src) { if (src == nullptr) throw gcnew ArgumentNullException("Must have event source"). the comp er generates code to mp ement the under y ng de egate mechan sm For the OnFirstEvent event object n the exerc se.How does the event keyword work? When you dec are an event member for a managed c ass. The rece ver has to know the event sources t’s work ng w th to be ab e to subscr be and unsubscr be. a pub c method that ca s Delegate::Remove to remove a rece ver from th s event’s nvocat on st As w th the add funct on. a protected method that ca s Delegate::Invoke to ca a the methods on th s event’s nvocat on st The raise method s protected so that t can on y be ca ed through the proper channe s and not d rect y by c ent code Implementing an event receiver You now have a c ass that can be used to fire events. } 256  Microsoft Visual C++/CLI Step by Step . so we add an EvtSrc member to the c ass to represent the one source w th wh ch you’ be work ng 2. you use the += operator on the event object. a pub c method that ca s Delegate::Combine to add a rece ver to th s event’s nvocat on st Rather than ca ng add OnFirstEvent d rect y. you don’t ca th s method d rect y but nstead use the –= operator on the event object raise OnFirstEvent. // Save the source theSource = src. you get the fo ow ng methods generated ■ ■ ■ add OnFirstEvent. Add a constructor to the c ass that takes a hand e to an EvtSrc object and checks that t sn’t nu If the po nter s va d.

} You subscr be to an event by us ng the += operator In the code. &EvtRcv::SecondEvent). the s gnatures of these methods must match the s gnatures of the de egates used to define the events. you cou d a so use member funct ons to subscr be to nd v dua events as requ red Chapter 14  De egates and events   257 . // Save the source theSource = src. &EvtRcv::FirstEvent). += ca s the comp er-generated add OnFirstEvent method. msg).3. you’re creat ng two new de egate objects. message was {0}". Define the member hand er funct ons n EvtRcv that EvtSrc s go ng to ca As you know from our d scuss on of de egates. After you have the hand ers defined. wh ch comb nes the new y created de egate w th the event source’s de egate As you read n the preced ng s debar. theSource->OnSecondEvent += gcnew SecondEventHandler(this. wh ch n turn ca s Delegate::Combine A though you’ve subscr bed to a the events automat ca y n the constructor. as shown here // Handler functions void FirstEvent(String ^msg) { Console::WriteLine("EvtRcv: event one. } void SecondEvent(String ^msg) { Console::WriteLine("EvtRcv: event two. // Add our handlers theSource->OnFirstEvent += gcnew FirstEventHandler(this. and SecondEvent s the hand er for the SecondEventHandler de egate Each of them s mp y pr nts out the str ng that’s been passed to them 4. msg). you can subscr be to the event source Ed t the construc- tor for the EvtRcv c ass so that t ooks ke the fo ow ng EvtRcv(EvtSrc ^src) { if (src == nullptr) throw gcnew ArgumentNullException("Must have event source"). } FirstEvent s the hand er for the FirstEventHandler de egate. wh ch w ca back to the FirstEvent and SecondEvent hand ers on the current object Th s s exact y the same syntax you’d use f you were manua y creat ng a de egate The d fference s n the += operator. message was {0}".

return 0. mum!"). // Create a receiver. } The EvtSrc constructor takes no arguments. sten ng for events to be fired from the source int main(array<String^> ^args) { Console::WriteLine("Event Example").5. Ed t the main funct on to create event source and rece ver objects int main(array<String^> ^args) { Console::WriteLine("Event Example"). // Create a source EvtSrc ^src = gcnew EvtSrc(). whereas the EvtRcv constructor must be passed a va d EvtSrc po nter At th s po nt. you can wr te some code to test them out 1. // Fire events Console::WriteLine("Fire both events:"). // Create a receiver. Bu d the app cat on to ensure that there are no errors Hooking it all together Now that you’ve wr tten the event source and event rece ver c asses. and bind it to the source EvtRcv ^rcv = gcnew EvtRcv(src). &EvtRcv::FirstEvent). src->RaiseOne("Hello. // Create a source EvtSrc ^src = gcnew EvtSrc(). } The syntax for us ng the –= operator to unsubscr be s exact y the same as that for the += operator to subscr be 6. A match ng –= operator ets you unsubscr be from events Add the fo ow ng member func- t on to EvtRcv. wh ch w unsubscr be from the first event // Remove a handler void RemoveHandler() { // Remove the handler for the first event theSource->OnFirstEvent -= gcnew FirstEventHandler(this. the rece ver s set up. 258  Microsoft Visual C++/CLI Step by Step . and bind it to the source EvtRcv ^rcv = gcnew EvtRcv(src).

mum!"). you shou d see output s m ar to the fo ow ng screen shot The rece ver has had both hand ers ca ed. Th s t me you shou d see on y the second message pr nted because the rece ver s no onger hand ng the first event Standard events and System::EventHandler You can base an event on a de egate w th any s gnature. src->RaiseOne("Hello. so t has pr nted both of the messages assoc ated w th the events 2. src->RaiseTwo("One big step"). Insert some code to ca the RemoveHandler funct on of the rece ver and try fir ng both events aga n // Remove the handler for event one rcv->RemoveHandler(). t w conta n the pos t on of the cursor and deta s of wh ch mouse button was c cked and whether any mod fier keys were used Because a system events fo ow th s Chapter 14  De egates and events   259 . // Fire events again Console::WriteLine("Fire both events:"). n the case of a mouse-c ck event. return 0. EventArgs ^args) Hand er funct ons do not have a return va ue and take two arguments The first s a reference to the object that ra sed the event. and the second s a reference to an object of type EventArgs or a subc ass Th s second argument s used to pass extra nformat on about the event For examp e.src->RaiseTwo("One big step"). } Ca s to the source’s RaiseOne and RaiseTwo funct ons te t to fire both events When you run th s code. but the standard NET event mode requ res that de egates conform to a part cu ar standard A standard event hand er funct ons have the fo owng form void MyHandler(Object src.

gcnew EventArgs()). wh ch s des gned to ca funct ons that match the standard event hand er s gnature The fo ow ng exerc se shows you how to use the System::EventHandler de egate You w define a Counter c ass that conta ns a s ng e nteger va ue. arrang ng for t to fire the LimitReached event at the ap- propr ate po nt void Increment() { Console::WriteLine("Count: {0}". nstead. you can spec fy a m t. 4.pattern. and they shou d be n t a zed n the constructor ref class Counter { int count. int limit. p ac ng t n the pub c sect on event EventHandler ^LimitReached. ++count). 3. Add a new c ass ca ed Counter to the source fi e Th s c ass shou d have two data members represent ng the current count and the m t. } }. if (count == limit) LimitReached(this. you don’t need to keep defin ng your own de egate types. t s good pract ce to make your events and the r correspond ng de egates use th s mode . hav ng the same two arguments and void return type For th s reason. Add the dec arat on of a standard EventHandler event to the c ass. you can make use of the System::EventHandler de egate. } Observe how the arguments to the event are a reference to the current object. public: Counter(int lim) { count = 0. and an event w be fired when the m t s reached 1. Imp ement the Increment funct on. wh ch you can ncrement by ca ng the increment funct on When you construct a Counter. and an EventArgs object Th s defau t EventArgs object doesn’t pass any extra nformat on to the c ent but s necessary to conform to the de egate s gnature 260  Microsoft Visual C++/CLI Step by Step . limit = lim. Create a new CLR Conso e App cat on named EventHandler 2. as we A the de egates used n the standard event mode w ook the same.

You now need some code that w be ca ed when the event s fired. ncrement the Counter enough t mes that the m t s reached int main(array<System::String ^> ^args) { // Define a counter with a limit of 3 Counter count(3). return 0. Imp ement the main funct on Start by creat ng a Counter object w th an appropr ate m t set and then b nd the CallMe method to the Counter’s LimitReached event F na y.Increment(). t can be bound to the LimitReached event 6. i<5. as shown n the fo ow ng screen shot Chapter 14  De egates and events   261 . so add an Observer c ass to the source ref class Observer { public: static void CallMe(Object ^src. } When you bu d and run the app cat on. i++) count.LimitReached += gcnew EventHandler(&Observer::CallMe). EventArgs ^args) { Console::WriteLine("Limit reached"). for (int i=0.5. thus. } }. count. The stat c CallMe method has the r ght s gnature for an event hand er. you shou d see the event hand er be ng ca ed when the m t s reached.

. Use the de egate s Invoke funct on. &myHandler). ke th s: event ClickHandler ^OnClick. For examp e: event EventHandler LimitReached. Create a de egate bound to a non stat c c ass member. For examp e: OnClick(xVal.Quick reference To Do This Define a de egate. pass ng nullptr for the first parameter. Use gcnew to create a de egate object. For examp e: delegate void DelegateOne(double d). Create an event that fo ows the standard EventHandler pattern 262  Microsoft Visual C++/CLI Step by Step Use a System::EventHandler de egate. Use the event object as f t were a funct on. int). Create an event. Use gcnew to create a de egate object. Then. &MyClass::MyOtherFunc).7). Create a de egate bound to a stat c c ass member. F rst. For examp e: DelegateOne ^del = gcnew DelegateOne( myObject. &MyClass::MyFunc). and the address of the member funct on as the second parameter. Use the = operator. For examp e: del->Invoke(22. n the event source c ass. pass ng a hand e to the nstance for the first parameter. Ra se an event. define a de egate to define the hand er rout ne for th s event. Unsubscr be from an event. Use the delegate keyword w th a funct on prototype. use the event keyword to define an event object. Execute the funct on bound to a de egate. For examp e: src->OnClick -= new ClickHandler(this. Subscr be to an event. Use the += operator. &myHandler). as fo ows: delegate void ClickHandler(int. yVal). pass ng any param eters requ red. pass ng any parameters. For examp e: DelegateOne ^del = gcnew DelegateOne( nullptr. and the address of the stat c funct on as the second parameter. For examp e: src->OnClick += new ClickHandler(this.

you w be ab e to ■ Ident fy the components of the M crosoft NET Framework ■ Work w th the major components of the NET Framework ■ Recogn ze the ma n namespaces that make up the NET Framework c ass brary I n prev ous chapters.NET Framework? The NET Framework s a comput ng p atform that has been des gned by M crosoft to s mp fy the deve opment of modern app cat ons. you earned how to use C++/CLI to bu d s mp e app cat ons Now. t’s t me to move on to earn how to bu d rea M crosoft NET app cat ons that nvo ve GUIs. and a the other mechan sms needed by the modern M crosoft W ndows app cat on And that’s where the NET Framework comes n The NET Framework s the brary of c asses that you use to bu d W ndows app cat ons It s arge.NET Framework class library After comp et ng th s chapter. and far-reach ng n ts scope Th s chapter g ves you an overv ew of what the NET Framework s and what t can do before we cover some of ts features n more deta n ater chapters What is the .CHAPTER 15 The . comp ex. databases. such as the fo ow ng ■ App cat ons that use soph st cated GUI front ends ■ App cat ons that use the Internet ■ App cat ons that are d str buted over more than one computer ■ App cat ons that make use of databases and other data sources There are two ma n components to the NET Framework the Common Language Runt me and the NET Framework c ass brary You exam ne both components n th s chapter 263 . web servers.

and remoting (commun cat on between objects n d fferent doma ns.eve . memory management.NET executable and show you the code in IL. and nher tance— s bu t nto IL. ILDASM. There’s an example of how to do so in the section “Metadata” later in the chapter. wh ch he ps to ensure that types created n d fferent anguages can nteroperate w th one another 264  Microsoft Visual C++/CLI Step by Step .anguage ntegrat on The CTS prov des a set of ru es that anguages must obey. or a at once when an app cat on s nsta ed One of the great nnovat ons of IL s that t sn’t s mp y a ow. you can use the IL Disassembler tool. encapsu at on and data-h d ng.ndependent object code In fact. po ymorph sm. but t’s poss b e to wr te both managed and unmanaged code n M crosoft V sua C++ and to have both types of code work ng together n the same app cat on The Microsoft Intermediate Language A NET anguages comp e down nto an ntermed ate form ca ed M crosoft Intermed ate Language (MSIL. and v ce-versa. to open a . support for object-or ented funct ona ty—such as the deas of c asses. and even nher t ng from a C++/CLI c ass n V sua Bas c Note  If you’re interested in seeing what IL looks like. The Common Type System The Common Type System (CTS) prov des a spec ficat on for how types are defined. or computers) Code that s run by the CLR s known as managed code. wh ch s an mportant part of the NET cross. funct on-by-funct on as an app cat on executes. prov d ng serv ces such as garbage co ect on The CLR s a run-t me execut on eng ne that s respons b e for execut ng code w th n the NET env ronment. eas y ca ng members n C++/CLI c asses from V sua Bas c. wh ch s done by a Just-In-T me (JIT) comp er Th s convers on m ght happen on demand. or just IL ) IL s s m ar to Java bytecode n that t’s an ntermed ate form of code produced by the comp er that can’t be d rect y executed on a target system IL code s a so portab e and s a ways converted nto nat ve code before t’s executed. and used. prov d ng serv ces such as secur ty. code that executes outs de the contro of the CLR s unmanaged code A M crosoft V sua Bas c and C# code s managed. processes. so you can v ew t as a type of object-or ented assemb er anguage Th s funct ona ty makes t far more powerfu than Java bytecode. and t makes t poss b e for you to perform cross. mach ne. managed.anguage object-or ented programm ng.The Common Language Runtime You’ve a ready met the Common Language Runt me (CLR) because th s s the part of NET that manages your code as t runs.

a Dialog c ass can conta n a the funct ons re at ng to d a og boxes Th s ab ty makes t much eas er to use a brary the s ze of the W ndows API The second prob em w th the W ndows API s that t’s bas ca y wr tten for C programmers. so t can’t eas y be used from every anguage One of the benefits of object-or ented programm ng s the he p that t g ves n structur ng and manag ng arge-sca e projects The W ndows API has grown to severa thousand funct ons. t’s a C  brary.NET Framework class library The NET Framework c ass brary s an object-or ented brary of c asses that prov des a the too s you need to wr te a w de var ety of app cat ons S nce W ndows was first re eased. t w comp ete y nteroperate w th other CLS-comp ant anguages You’ see n the on ne documentat on that some NET member funct ons are marked as not CLScomp ant. and t becomes harder and harder to manage such a arge co ect on of unstructured rout nes In add t on to  ts other benefits (such as encapsu at on and po ymorph sm). so t uses many features that are un que to C. wh ch makes t hard—and somet mes mposs b e—to use some funct ona ty from anguages other than C or C++ You a so tend to need a ot of ug y “p umb ng” to nterface between anguages such as V sua Bas c and the API The NET Framework c ass brary prov des a set of c asses that can be used from any NET anguage because t works at the IL eve A NET anguages comp e down to the same ntermed ate code. programmers have wr tten W ndows app cat ons us ng the W ndows API (app cat on programm ng nterface) Th s API g ves you a arge number of C funct ons— severa thousand. such as po nters and nu -term nated str ngs. object-or ented programm ng ets you mpose a structure on code So. for examp e. t sn’t object-or ented. they can a use the c asses defined n the c ass brary Th s s a huge advantage and prov des anguage nteroperab ty on a sca e never seen before Chapter 15  The . uns gned ntegers are not nc uded n the types spec fied by the CLS The .NET Framework c ass brary   265 . there are two ma n prob ems w th the W ndows API first. n fact—that you can ca from your app cat ons to nteract w th W ndows However. and second. and f a anguage or a brary s CLS-comp ant. and because they a use references and agree on the bas c set of va ue types. funct ons that use uns gned ntegers are not CLS-comp ant because uns gned ntegers aren’t supported by V sua Bas c As a resu t. wh ch means that they m ght not be access b e from some NET anguages For examp e.The Common Language Specification The Common Language Spec ficat on (CLS) s a set of ru es and constra nts that comp er and brary wr ters need to fo ow to ensure that the anguages and code they produce w nteroperate w th other NET anguages The CLS forms a subset of the CTS.

and the assembly manifest descr bes the assemb y’s vers on together w th the vers ons of any assemb es on wh ch t depends Th s nformat on means that t’s poss b e to check that components w th the wrong vers on nformat on aren’t be ng used at run t me Deployment  Assemb es are oaded on y as needed. base c ass. wh ch means that they carry descr pt ve nformat on w th them n the exe or d fi e Th s nformat on. wh ch makes them h gh y su tab e for d str buted app cat ons Type  A type’s dent ty nc udes the assemb y n wh ch t res des Two types w th the same name v ng n two d fferent assemb es are cons dered to be two comp ete y d fferent types Security  The boundary between assemb es s where secur ty perm ss ons are checked Metadata NET c asses are se f-descr b ng. ca ed metadata. and deta s of members Add t ona attr bute nformat on Most of the metadata s standard and s created by the comp er when t produces the IL code. but you can use attr butes to add extra metadata nformat on 266  Microsoft Visual C++/CLI Step by Step . v s b ty. and any other fi es needed for run-t me operat on An assemb y s therefore much more se f-conta ned than a standard W ndows executab e or Component Object Mode (COM) object because there s no re ance on externa sources of nformat on such as the W ndows Reg stry Every NET type s part of an assemb y. and no NET type can ex st outs de an assemb y There are severa aspects by wh ch assemb es are fundamenta to the NET wor d ■ ■ ■ ■ Versioning  The assemb y s the sma est un t to wh ch vers on ng s app ed. metadata that descr bes the assemb y and ts contents. vers on. nc udes the fo ow ng ■ The name. nterfaces mp emented.Assemblies Assemb es are the bas c bu d ng b ocks w th wh ch NET app cat ons are constructed. and cu ture-spec fic nformat on (such as the anguage and ca endar used) for the assemb y ■ The types that are exported by the assemb y ■ Other assemb es on wh ch th s one depends ■ Secur ty perm ss ons needed to run ■ ■ Informat on for each type n the assemb y name. and they’re the fundamenta un t of dep oyment and vers on ng Assemb es conta n IL code.

[assembly:AssemblyDescriptionAttribute("")]. [assembly:AssemblyCopyrightAttribute("Copyright (c) [assembly:AssemblyTrademarkAttribute("")]. Open Assemb yInfo cpp The fi e conta ns a number of nes that ook ke the fo ow ng [assembly:AssemblyTitleAttribute("Meta1")]. and most of them are sted n Assemb yInfo cpp 4. th s s ocated n the fo der \Program F es (x86)\ M crosoft SDKs\W ndows\v8 0A\b n\NETFX 4 0 Too s Note  I am using a prerelease version of Windows 8 and Visual Studio 2012. [assembly:AssemblyCultureAttribute("")]. and StdAfx cpp s there to nc ude the StdAfx h header fi e 3. the keyword assembly: at the start of the attr bute means that th s attr bute app es to an assemb y. [assembly:AssemblyProductAttribute("Meta1")]. 6. Metadata s added to C++ code by enc os ng dec arat ons n square brackets ([]) Metadata s most often attached to code to descr be c asses and funct ons Here. use the F e menu to nav gate to the Meta1 exe executab e and open t You shou d see someth ng ke the screen shot that fo ows Chapter 15  The . Ed t the AssemblyCompanyAttribute ne to conta n some su tab e name.NET Framework c ass brary   267 . [assembly:AssemblyConfigurationAttribute("")]. 2012")]. When the ILDASM w ndow opens. wh ch automat ca y creates the assemb y for you How can you be sure that the metadata n the assemb y reflects your change? One way to find out s to use ILDASM. [assembly:AssemblyCompanyAttribute("")]. Assemb yInfo cpp conta ns defin t ons of the standard metadata tems that you can mod fy. so the location of ildasm. Bu d the project. as opposed to be ng attached to code There’s a set of standard attr butes that you can use to change the metadata comp ed nto an assemb y.The fo ow ng exerc se shows you how to mod fy the standard metadata produced by the comp er 1. 5. Open So ut on Exp orer and ook at the Source F es fo der You can see that the project conta ns three C++ source fi es Meta1 cpp s the code for the app cat on. Start M crosoft V sua Stud o 2012 and create a new CLR Conso e App cat on project named Meta1 2. wh ch s part of the NET SDK On my system. such as the fo ow ng [assembly:AssemblyCompanyAttribute("City Power & Light")].exe might be different on your system.

and enumerat ons that are conta ned n over 400 namespaces Th s sect on beg ns by exp a n ng how to use namespaces n C++/CLI code and then goes on to st some of the major NET namespaces.ctor(string) /* 0A000009 */ = ( 01 00 16 41 63 6D 65 20 52 6F 63 6B 65 74 20 53 // . nterfaces.custom /*0C000005:0A000009*/ instance void ['mscorlib'/* 23000001 */] 'System. you can see that the metadata does reflect the change you made to the project The .'AssemblyCompanyAttribute' /* 0100000D */::.Reflection'. Doub e-c ck MANIFEST. wh ch opens a separate w ndow d sp ay ng the assemb y metadata At the top of th s st ng are the deta s of the assemb es on wh ch th s executab e depends Scro down unt you find the AssemblyCompanyAttribute ne. structures.. together w th br ef deta s of the r funct on and content 268  Microsoft Visual C++/CLI Step by Step .NET Framework namespaces The NET Framework c ass brary s made up of a set of c asses..7.. A though the contents are presented n hexadec ma .City Power & 6C 65 64 2C 20 49 6E 63 2E 00 00 ) // Light.. wh ch shou d read someth ng ke the fo ow ng .

so n C#.Thread A c asses.Threading.Generic. whereas those beg nn ng w th Microsoft have been deve oped by other product groups w th n M crosoft Namespace names can have any number of components. nterfaces. the components of the name are separated by the scope reso ut on operator ( ) In many other NET anguages such as C# and V sua Bas c. structures. NET namespaces prov de an add t ona eve of scop ng that he ps you to organ ze code and guard aga nst name c ashes Two c asses w th the same name can be used n an app cat on. yet they aren’t necessar y re ated n any other way Note  If you are a Java programmer. the components are separated by us ng a per od ( ). As w th trad t ona C++ namespaces. keep in mind that although . there’s no relationship between namespace names and directory paths as there is in Java.NET namespaces look very much like Java package names. as n the fo ow ng examp e using namespace System::Collections. as ustrated n the fo ow ng examp es System::Collections::Generic::List System::Threading::Thread // the List<T> class from // System::Collections::Generic // the Thread class from System::Threading Namespace names n NET typ ca y cons st of more than one word In C++/CLI. the preced ng examp es wou d be as fo ows System. prov ded that they be ong to d fferent namespaces A type name that nc udes the namespace nformat on s ca ed the fully qualified name.List System. but there’s no h erarch ca re at onsh p mp ed n names that conta n the same root components The h erarch ca nature of namespace names s mp y g ves you a way to organ ze your c asses So. and enumerat ons that are part of the NET Framework c ass brary be ong to a namespace Most of the namespaces prov ded by M crosoft beg n w th one of two prefixes Those that start w th System have been deve oped as part of the NET Framework c ass brary.You’ve a ready encountered NET namespaces n use n C++/CLI code when you’ve used the C++ using keyword. There’s no requ rement that a the c asses be ong ng to one namespace are defined n the same d fi e or that a s ng e d fi e conta ns c asses from on y one namespace Chapter 15  The . for examp e.NET Framework c ass brary   269 .Collections. System::Collections::Generic and System::Collections both conta n co ect ons.

and t nc udes the fu y qua fied names of a the types For examp e.dll> t oads the d fi e and reads the metadata for a the types that are defined there Because mscor b d conta ns most of the core NET Framework c asses. conta ns a ot of fundamenta c asses.Using namespaces in C++ applications C++/CLI app cat ons emp oy the #using preprocessor d rect ve to mport metadata nto app cat ons Remember that metadata s nformat on that descr bes the types n an assemb y.dll> // Import all the names using namespace System::Collections::Generic.dll files. f the comp er sees a ne such as #using <mscorlib. t mports the metadata for a very arge number of types Note  You can only use #using to reference assemblies defined in . t’s common to use a trad t ona using d rect ve to spec fy namespace names so that you can use unqua fied names. // Now you can use List without having to qualify it List<int> ^pal = gcnew List<int>(). The #using keyword means that you have to know wh ch d fi e ho ds the c ass or c asses that you want to use Your typ ca source for th s nformat on s the on ne he p Some of the fu y qua fied names can get rather ong Thus. p us the base c ass for arrays ■ Events and event hand ers ■ De egates and nterfaces ■ Attr butes ■ Except ons ■ Math 270  Microsoft Visual C++/CLI Step by Step . defined n mscor b d . nc ud ng the fo ow ng ■ Base c asses for common y used va ue and reference types. as shown here // Read the metadata for MSCORLIB #using <mscorlib. The System namespace The System namespace.

.

dll> 272  Microsoft Visual C++/CLI Step by Step .” ooks at the Collections namespaces. use 12345 and d v de the resu t by 100 The Collections namespaces Chapter 12. n part cu ar System:: Collections::Generic System::Collections::Generic s mp emented n mscor b d . but wh ch s s ower The second s to use nteger ar thmet c w th sca ng For examp e. Floating-point and decimal arithmetic Chapter 8. else if (result == Double::NaN) Console::WriteLine("Not a number"). “Inher tance.” po nts out that float ng-po nt ca cu at ons are subject to round ng errors Th s s because of the way that IEEE-754 encodes va ues by us ng base 2. double bottom = 0. n the same way that we can on y ever get an approx mat on to the correct va ue of p . and so we see round ng errors as these approx mat ons accumu ate There are two ways around th s prob em The first s to use the System::Decimal type. a dec ma va ue such as 0 1 cannot be exact y represented n base 2 ar thmet c t comes out as 00011001100110011… w th the “0011” repeatng forever Th s means that you can on y ever get an approx mat on to 0 1. as shown n the fo ow ng examp e double top = 1. if (result == Double::PositiveInfinity) Console::WriteLine("+infinity"). you’ have to nc ude a #using statement.0. double result = top/bottom. else if (result == Double::NegativeInfinity) Console::WriteLine("-infinity"). as we as methods to test for them. wh ch means t s not poss b e to represent some dec ma numbers exact y In the same way that p cannot be exact y represented as a dec ma (3 14159…). “Arrays and co ect ons. so to use t. so you never get a d v de-by-zero error when perform ng float ngpo nt math.0. wh ch performs ar thmet c n base 10 and so does not get these round ng errors. as demonstrated here #using <mscorlib. nstead.Floating-point types The Single and Double types mp ement IEEE-754 float ng-po nt ar thmet c Th s means that every operat on has a defined resu t. nstead of us ng 123 45. you get an answer of nfin ty The float ng-po nt c asses have va ues to represent pos t ve and negat ve nfin ty and “not a number” (often represented as NaN).

.

.

whereas System::Net::WebSockets prov des a managed mp ementat on of the WebSocket nterface The ServiceModel namespaces The System::ServiceModel namespaces (over 30 of them) together mp ement W ndows Commun cat on Foundat on (WCF). ta k ng to HTTP and FTP servers. wh ch a ows teams to use des gn too s such as M crosoft Express on B end n add t on to cod ng too s such as M crosoft V sua Stud o The Net namespaces Network ng support s prov ded by a number of namespaces n the System::Net fam y System::Net tse f prov des an nterface to many of the protoco s common y used today.NET Framework c ass brary   275 . serv ce-or ented app cat ons W th WCF. but the techno og es used were very d fferent. you built UIs by using a technology called Windows Forms.” de ves deeper nto some of the System::IO c asses The System::IO c asses are n mscor b d The Windows namespaces The System::Windows prefix dent fies 50 namespaces that together prov de the funct ona ty of W ndows Presentat on Foundat on (WPF). dependng on where your components were ocated (same process. and manag ng d str buted components and the r c ents Chapter 19 shows you how to wr te a web serv ce by us ng WCF Chapter 15  The . you can bu d app cat ons out of components hosted n other processes. and comprehens ve support for p ay ng med a Note  In earlier versions of the . an advanced user nterface (UI) framework for NET ntroduced n vers on 3 0 WPF prov des a the too s you need to create modern UIs. which was heavily influenced by Visual Basic. or d fferent process on another computer) and the commun cat on mechan sm you wanted to use (TCP/IP. HTTP. 2D and 3D graph cs. run-t me an mat on. such as man pu at ng IP addresses.NET Framework. mak ng DNS ookups. d fferent process on the same computer.As w th a the NET Framework c ass brary c asses.ndependent They can be used a ongs de or n p ace of the C++ stream c asses Chapter 19. nc ud ng support for forms-based app cat ons. a techno ogy ntroduced n NET 3 0 for creat ng d str buted. manag ng cook es. these c asses are anguage. “Wr t ng a serv ce by us ng W ndows Commun cat on Foundat on. an XML markup anguage. and even on other computers Th s has ong been poss b e. typography and pr nt ng. messag ng) WCF prov des an ntegrated framework for creat ng. One key feature of WPF s ts use of XAML. dep oy ng. to define user nterfaces Th s makes t poss b e to separate the UI from the code. and authent cat on System::Net::Sockets prov des an mp ementat on of the Berke ey Sockets protoco and prov des a NET wrapper around the W ndows W nSock API.

dll.Xml. mak ng t poss b e to map managed objects to a back ng database automat ca y 276  Microsoft Visual C++/CLI Step by Step . nc ud ng M crosoft Access databases System.OracleClient  The prov der for Orac e makes t poss b e to work w th Orac e databases from NET code System.The Xml namespaces XML s heav y used throughout the NET Framework.Data.Data.Data.EntityClient  Ent ty Framework (EF) s an object-re at ona mapp ng framework that can be used from ADO NET.SqlClient  Th s prov der s opt m zed for use w th M crosoft SQL Server System.Linq.dll The Data namespaces The System::Data namespaces ho d the c asses that mp ement ADO NET. and severa namespaces prov de support for creat ng and man pu at ng XML. a framework w th wh ch you can bu d components to manage data from a number of data sources Data from d fferent data sources s prov ded by data prov ders.OleDb  Object L nk ng and Embedd ng Database (OLE DB)–based techno ogy that makes t poss b e to use many d fferent k nds of data sources—such as re at ona database tab es. M crosoft Exce spreadsheets. five of wh ch are sh pped w th the NET Framework ■ ■ ■ ■ ■ System. nc ud ng the fo ow ng ■ ■ System::Xml  Prov des the bas c c asses needed for process ng XML System::Xml::Linq  Makes t poss b e to use Language-Integrated Query (LINQ) to work w th XML data ■ System::Xml::Schema  Prov des support for XML schemas ■ System::Xml::Serialization  G ves you the ab ty to ser a ze NET objects to and from XML ■ System::Xml::XPath  Conta ns the XPath parser and eva uat on eng ne ■ System::Xml::Xsl  Conta ns the Extens b e Sty esheet Language (XSL) processor Us ng these c asses.Xml. and even text fi es—as f they were databases System. w th the LINQ c asses n System. t’s poss b e to perform a the man pu at on of XML that you’ ever need to do These c asses make the NET Framework one of the most product ve env ronments for XML programm ng You can find the XML c asses n System.Data.Data.Odbc  The ODBC prov der g ves access to Open Database Connect v ty (ODBC) data sources.

and data s usua y passed to and from the web serv ce n XML format by us ng S mp e Object Access Protoco (SOAP) The use of XML over HTTP makes t poss b e to access web serv ces eas y from c ents wr tten n just about any programm ng anguage on any p atform It’s a so poss b e to find out what serv ces a web server supports. and these n turn cons st of a co ect on of DataColumn and DataRow objects You can use DataSets to work n disconnected mode Th s means retr eve data from a database nto a DataSet. nc ud ng the HttpRequest and HttpResponse c asses that enab e an ASP NET page to exchange data w th the c ent by us ng HTTP System::Web::Mail  Th s makes t poss b e for you to prepare and send ema attachments by us ng the S mp e Ma Transfer Protoco (SMTP) serv ce that s bu t n to the W ndows operatng system ■ System::Web::Security  Th s prov des c asses that mp ement secur ty n ASP NET ■ System::Web::Services  Th s prov des the c asses w th wh ch you can bu d web serv ces ■ System::Web::UI  Th s conta ns a the c asses w th wh ch you can bu d server-s de contro s The features prov ded by two of these namespaces mer t part cu ar ment on A web service s a programmab e ent ty v ng on a web server that can be accessed by us ng standard Internet protoco s What th s means n pract ce s that you can expose a funct on on a web server that others can ca Commun cat on between c ent and server uses standard protoco s such as HTTP.The most mportant c ass n the System::Data namespace tse f s DataSet. and then update the database from the DataSet ater The Web namespaces Because one of the ma n reasons for ntroduc ng the NET Framework was to make t eas er to bu d web app cat ons. the atest vers on of M crosoft Act ve Server Pages techno ogy that s opt m zed to work n the NET env ronment The most s gn ficant of the Web namespaces are sted here ■ ■ System::Web  Th s prov des the bas c funct ona ty for browser-to-server commun cat on over HTTP. t’s perhaps no surpr se that the NET Framework conta ns a number of namespaces re ated to web programm ng These are a re ated to M crosoft ASP NET. wh ch represents an n-memory cache of data retr eved from a data source A DataSet cons sts of one or more DataTable objects.NET Framework c ass brary   277 . and t’s very easy n V sua Stud o 2012 to wr te c ents that make use of web serv ces Chapter 15  The . d sconnect from the database server and work w th the data oca y.

Use the c asses n the System::Collections::Generic namespace. sts. and hash tab es. and you can use t to program server-s de contro s that m ght not map d rect y to HTML Quick reference To Do this Use data structures such as dynam c arrays. Use the c asses n System::Windows::Forms. Look at the c asses n the System::Xml namespace. Work w th XML. 278  Microsoft Visual C++/CLI Step by Step . Look at the System::Data namespaces. you can bu d server-s de contro s You program these as f they were norma contro s. Use the c asses n the System::Diagnostics namespace. but the r code executes on the server The System::Web::UI::HtmlControls namespace conta ns c asses that represent HTML server contro s that map d rect y to standard HTML e ements such as buttons and forms System::Web::UI::WebControls s more abstract. or mon tor system performance. Create a form based app cat on. Work w th databases by us ng ADO. Trace app cat on execut on.NET. and der ve a c ass from System::Windows::Forms::Form. nteract w th the event og.W th the System::Web::UI namespaces.

. . 351 CHAPTER 20 Introduc ng W ndows Store apps 369 CHAPTER 21 More about W ndows Store apps 397 279 . 333 CHAPTER 19 Wr t ng a serv ce by us ng W ndows Commun cat on Foundat on . . . . . . . . . . . . . . . . . . . . . . . .NET Framework CHAPTER 16 Work ng w th fi es .PAR T I I I Using the . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281 CHAPTER 17 Read ng and wr t ng XML 305 CHAPTER 18 Us ng ADO NET . . . . . . . . . . . . . . . . . .

.

you’ll find it easy to start working with . 281 .NET I/O because the two have many similarities. and enumerat ons that mp ement the M crosoft NET I/O mode Note  If you know anything about the Java I/O mechanism as implemented in the java. wh ch conta ns the c asses.io package.CHAPTER 16 Working with files After comp et ng th s chapter. structures. you w be ab e to ■ Understand how the M crosoft W ndows NET Framework performs nput/output (I/O) ■ Ident fy the c asses that make up the System::IO namespace ■ Perform text I/O ■ Read and wr te fi es ■ Work w th fi es and d rector es ■ Perform b nary I/O Y ou’ve a ready used the Console c ass to perform I/O to and from the conso e Th s chapter ntroduces you to the System::IO namespace.

The System::IO namespace
The System::IO namespace conta ns a the c asses that are used for b nary and text I/O as we as
c asses that he p you to work w th fi es and d rector es The fo ow ng tab e sts the ma n c asses n the
namespace
Class

Description

BinaryReader

Reads pr m t ve data types as b nary va ues

BinaryWriter

Wr tes pr m t ve data types as b nary va ues

BufferedStream

A stream c ass that buffers reads and wr tes to another
stream

Directory

Has stat c methods for work ng w th d rector es

DirectoryInfo

Has non stat c methods for work ng w th d rector es

File

Has stat c methods for work ng w th fi es

FileInfo

Has non stat c methods for work ng w th fi es

FileStream

A c ass for read ng and wr t ng fi es by us ng a stream

FileSystemInfo

The abstract base c ass for DirectoryInfo and FileInfo

FileSystemWatcher

Watches for changes to the fi e system and ra ses events
when changes occur

IOException

The except on thrown by c asses n the System::IO
namespace

MemoryStream

A stream c ass that reads and wr tes memory

Path

He ps you work w th d rectory str ngs n a p atform
ndependent way

Stream

The abstract base c ass for a the stream c asses

StreamReader

A TextReader that reads characters from a byte stream

StreamWriter

A TextWriter that wr tes characters to a byte stream

StringReader

A TextReader that reads from a str ng

StringWriter

A TextWriter that wr tes to a str ng

TextReader

The abstract base c ass for StreamReader and
StringReader

TextWriter

The abstract base c ass for StreamWriter and StringWriter

The I/O-or ented c asses n System::IO can be d v ded nto the fo ow ng three groups

The Stream c asses, wh ch are des gned for I/O of streams of bytes
The BinaryReader and BinaryWriter c asses, wh ch are used to nput and output NET pr m t ve
types, such as Int32 and Double, n b nary form
The TextReader and TextWriter c asses, wh ch are used for character-mode I/O

Th s chapter focuses on the atter two groups

282  Microsoft Visual C++/CLI Step by Step

Implementing text I/O by using readers and writers
TextReader and TextWriter are the abstract base c asses for a group of c asses that are used to
read and wr te characters There are four c asses n System::IO that der ve from these two bases—
StreamReader, StreamWriter, StringReader, and StringWriter, as we as w th severa other much more
spec a zed wr ter c asses n other namespaces

Using TextWriter
The TextWriter c ass has a number of usefu methods, as summar zed n the fo ow ng tab e
Method

Description

Close

C oses the wr ter and re eases any resources that t s us ng

Dispose

Re eases a unmanaged resources used by the wr ter and
opt ona y re eases managed resources, as we

Flush

Causes a buffered data to be wr tten to the under y ng
dev ce

FlushAsync

Causes a buffered data to be wr tten asynchronous y to
the under y ng dev ce

Synchronized

Creates a thread safe wrapper for the wr ter

Write

Wr tes text w thout a new ne

WriteAsync

Wr tes text w thout a new ne asynchronous y

WriteLine

Wr tes text w th a new ne

WriteLineAsync

Wr tes text w th a new ne asynchronous y

As you m ght guess from the nc us on of the Write and WriteLine funct ons n the tab e, the
Console c ass uses a TextWriter object to perform output

Asynchronous I/O
You m ght have not ced that the TextWriter c ass conta ns severa methods whose names end
w th Async Norma y, I/O operat ons prevent your code from execut ng further unt they fin sh,
a cond t on known as blocking Asynchronous I/O he ps overcome th s by perform ng I/O n the
background, ett ng your code cont nue execut ng wh e the nput or output operat on runs n
para e Th s s very usefu when you don’t need to know that the operat on has fin shed, a though t s poss b e to find out when the operat on fin shes Sett ng up and work ng w th asynchronous I/O can be comp ex and s beyond what we can cover n th s ntroductory chapter

To show you how the I/O c asses work together, et’s ook at how you use the StreamWriter c ass
Before we start, though, t’s mportant that you understand how the NET Framework mp ements I/O
Rather than create a number of c asses that each perform an end-to-end I/O task—such as “wr te a

Chapter 16  Work ng w th fi es   283

str ng to a fi e” or “read a number from the keyboard”— NET mp ements a number of sma er spec a purpose c asses that you can p ug together to ach eve the effect you want Th s means that NET
doesn’t have a “wr te characters to a fi e” c ass Instead, t has a “wr te characters to a byte stream”
c ass and a “read bytes from a stream and wr te them to a fi e” c ass If you p ug the output from the
first c ass nto the nput of the second, you end up wr t ng characters to a fi e
Th s mode s flex b e because you can take b nary or character data, convert t nto bytes, and then
pass the bytes to any of severa c asses to output them to fi es, memory, or a str ng Data s transferred
between the c asses as streams of bytes, a method that prov des a flex b e base on wh ch to bu d The
bas c funct ona ty for hand ng byte streams s prov ded by the Stream c ass, and you can bu d your
own spec a zed I/O c asses on top of Stream, f you need to
W th that nformat on n m nd, the exerc se that fo ows shows you how to wr te character data to
a text fi e by us ng a TextWriter Us ng the p ug-and-p ay mode for I/O that the NET Framework uses,
you need to create the fo ow ng two objects

A FileStream object that takes bytes as nput and wr tes them to a fi e

A StreamWriter object that takes text and converts t to a byte stream

So, et’s get started
1. Start M crosoft V sua Stud o 2012 and create a new CLR Conso e App cat on project named

CppWriter
2. The TextWriter and fi e I/O c asses are part of System::IO, so nc ude a using dec arat on at the

beg nn ng of the app cat on, as shown here
using namespace System::IO;

3. In the main funct on, create a FileStream object to wr te to a fi e
// Create a FileStream
try
{
FileStream ^fs = gcnew FileStream("output.txt", System::IO::FileMode::Create);
}
catch(System::Exception ^pe)
{
Console::WriteLine(pe->ToString());
}

The FileStream constructor takes a fi e name and a mode In th s case, the fi e s go ng to be
created f t doesn’t ex st or overwr tten f t does I’ve used output txt as the fi e name, but you
can spec fy any path and fi e name you ke for the new fi e

Note  See the section “The FileStream class” later in this chapter for more details on
how to construct FileStream objects.

284  Microsoft Visual C++/CLI Step by Step

The code s enc osed n a try b ock because a ot of th ngs cou d go wrong when try ng to
open th s fi e
4. After you have n t a zed the FileStream object, create a StreamWriter that uses the FileStream,

as demonstrated here
try
{
// Create a FileStream
FileStream ^fs = gcnew FileStream("output.txt", FileMode::Create);
// Create a StreamWriter
StreamWriter ^sw = gcnew StreamWriter(fs);
}
catch(System::Exception ^pe)
{
Console::WriteLine(pe->ToString());
}

The StreamWriter constructor takes a hand e to a Stream object as ts one argument
5. You can now use the Write and WriteLine funct ons to output text to the fi e P ace the fo ow-

ng nes ns de the try b ock
// Write some text
sw->WriteLine("First line");
sw->WriteLine("Second line");
sw->WriteLine("Third line");

6. Ensure that a output s flushed to the fi e and c ose the stream
// Close the file
sw->Flush();
sw->Close();

Note  WriteLine performs buffered output, which means that it doesn’t necessarily
write lines to the file every time you call the function. Instead, it maintains an internal buffer and writes the buffer to hard disk as necessary. One hard disk access per
buffer is more efficient than writing individual lines, but you need to call Flush at the
end of the code to ensure that output currently in the buffer is transferred to the
file.

7. Bu d and run the app cat on

A text fi e named output txt shou d appear n the CppWr ter project d rectory The fi e conta ns the three nes of text wr tten by the CppWr ter app cat on

Chapter 16  Work ng w th fi es   285

1. Create a new CLR Conso e App cat on project named CppReader
2. Inc ude a using dec arat on for System::IO at the top of the project
using namespace System::IO;

3. Add code to main to ensure that the user has entered a fi e name

The argument to main s an array of the command- ne arguments, not nc ud ng the app cat on name
// Check for required argument
if (args->Length < 1)
{
Console::WriteLine("Usage: CppReader path");
return 0;
}
String ^path = args[0];

If the user hasn’t g ven an argument, an error message s pr nted and the app cat on ex ts If
the user has prov ded t, the argument s saved for ater use
4. It’s w se to check that the path represents an ex st ng fi e before cont nu ng, so add the fo ow-

ng code
if (!File::Exists(path))
{
Console::WriteLine("Invalid filename!");
return -1;
}

The File::Exists method checks whether a fi e w th the spec fied name ex sts, return ng fa se f
t doesn’t It w a so return fa se f you g ve the name of a d rectory rather than a fi e Not ce
the return va ue of –1 It’s a common convent on for C/C++ app cat ons to return 0 to nd cate
success, w th negat ve va ues be ng used to denote error cond t ons
5. Start st ng the fi e The first step s to create a FileStream and connect t to a StreamReader
try
{
FileStream ^fs = gcnew FileStream(path, System::IO::FileMode::Open);
StreamReader ^sr = gcnew StreamReader(fs);
}
catch(System::Exception ^pe)
{
Console::WriteLine(pe->Message);
}

In th s case, you’re open ng the fi e by us ng FileMode::Open, wh ch w
the fi e doesn’t a ready ex st

288  Microsoft Visual C++/CLI Step by Step

throw an except on f

6. L st ng the fi e s done n th s oop, wh ch you shou d p ace after creat ng the StreamReader

object, ke th s
int count = 0;
for(;;)
{
String ^line = sr->ReadLine();
count++;
// If there are no more lines, break out of the loop
if (line == nullptr) break;
Console::WriteLine(line);
if (count % 20 == 0)
{
Console::Write("--more-- ");
String ^response = Console::ReadLine();
if (response->Equals("q")) break;
count = 0;
}
}
Console::WriteLine("-- end --");

The count var ab e s go ng to be used to count the nes as they’re read so that the app cat on knows where to break The oop reads a ne nto a String by us ng the ReadLine funct on
of StreamReader; f there are no more nes to read, a nu w be returned The ne s then
echoed to the conso e and the count checked I’ve set the number of nes d sp ayed at one
t me to an arb trary va ue of 20; when the count s exact y d v s b e by 20, the app cat on
wr tes “--more--” to the conso e and wa ts for the user to nput someth ng If the user presses
a owercase q, the app cat on stops; otherw se, t outputs the next set of nes
Remember that for(;;) sets up an nfin te oop, wh ch you need to term nate somehow In th s
examp e, when there are no more nes to read, the ca to ReadLine returns nullptr, and th s
causes the oop to term nate
7. Bu d and run the app cat on, g v ng the name of a su tab e text fi e as the argument

You can do th s n one of two ways The first s to open a command prompt, nav gate to the
d rectory conta n ng the executab e fi e, and then execute the app cat on from the command
ne just as you wou d w th any other app cat on
The second s to run the app cat on from w th n V sua Stud o, prov d ng the command- ne
arguments that you need In So ut on Exp orer, r ght-c ck the project name, and then, n the
shortcut menu that appears, c ck Propert es When the Propert es page appears, n the pane
on the eft, se ect Configurat on Propert es, c ck Debugg ng, and then enter the fi e name nto
the Command Arguments box n the center pane

Chapter 16  Work ng w th fi es   289

Working with files and directories
The System::IO namespace conta ns severa c asses to he p you work w th fi es and d rector es

Getting information about files and directories
The Directory and DirectoryInfo c asses prov de you w th funct ons to he p you work w th d rector es
The d fference between them s that the Directory c ass on y conta ns stat c methods, whereas
DirectoryInfo conta ns non-stat c nstance methods Why the need for two d fferent c asses? It’s
necessary for NET to perform a secur ty check before a ow ng you access to a d rectory or a fi e The
Directory c ass performs th s check every t me you use one of ts stat c methods, wh ch can be t meconsum ng Objects of the DirectoryInfo c ass, on the other hand, work w th one d rectory, and the
secur ty check s done once when the object s constructed It can, therefore, be a ot more effic ent to
use DirectoryInfo f you’re go ng to perform mu t p e operat ons on one d rectory The fo ow ng tab e
sts the ma n methods of the Directory c ass
Method

Description

CreateDirectory

Creates a d rectory

Delete

De etes a d rectory and, opt ona y, ts subd rector es

EnumerateDirectories

Returns an enumerab e co ect on of the d rector es n a
spec fied path

EnumerateFiles

Returns an enumerab e co ect on of the fi es n a spec
fied path

EnumerateFileSystemEntries

Returns an enumerab e co ect on of a the fi es and
d rector es n a spec fied path

Exists

Checks whether a d rectory ex sts

GetCreationTime

Gets the creat on t me of a d rectory

GetCurrentDirectory

Returns a str ng represent ng the path to the app cat on s
current d rectory

GetDirectories

Gets an array of str ngs represent ng the names of subd
rector es n a g ven d rectory

GetDirectoryRoot

Returns the root port on of a path

GetFiles

Gets an array of str ngs represent ng the names of the
fi es n a g ven d rectory

GetFileSystemEntries

Gets an array of str ngs represent ng the names of the
fi es and d rector es n a g ven d rectory

GetLastAccessTime

Gets the ast access t me for the d rectory

GetLastWriteTime

Gets the ast wr te t me for the d rectory

GetLogicalDrives

Gets a st of the og ca dr ves on the computer

GetParent

Gets the parent d rectory of a spec fied d rectory

Move

Moves a d rectory and ts contents

SetCreationTime

Sets the creat on t me for a d rectory

290  Microsoft Visual C++/CLI Step by Step

.

.

3.1. When the app cat on s run. bool size = false. and “a” (for the fi e attr butes) You can a so use “v” (for verbose) as a shorthand to nd cate that you want them a It doesn’t matter n what order the opt ons etters are spec fied. “d” (for the ast mod fied date). return 0. atts). the user can supp y opt ons n add t on to a fi e or d rectory path Add the fo ow ng code to main to check that you have the m n mum number of opt ons if (args->Length < 1) { Console::WriteLine("Usage: CppFiles [options] [path]"). “sa” to choose the “s” and “a” opt ons The opt ons supported by th s s mp e app cat on are “s” (for the fi e s ze). date. // If we have two arguments. bool atts = false. options = args[0]. } If the user has spec fied opt ons. for examp e. Because a the fi e and d rectory c asses are part of System::IO. we need to check what they are Each opt on s spec fied by a s ng e etter. bool date = false. add a using dec arat on at the beg nn ng of the app cat on using namespace System::IO. String ^path = nullptr. // Parse the option string to set the option flags ParseOptions(options. path = args[1]. Add the fo ow ng code to main String ^options = nullptr. and mu t p e opt ons are spec fied as a str ng. bool hasOptions = false. size. or even f they are repeated 4. } else path = args[0]. we have options if (args->Length == 2) { hasOptions = true. p ac ng t before main 294  Microsoft Visual C++/CLI Step by Step . Create a new CLR Conso e App cat on named CppFiles 2. 5. Add the funct on that s go ng to process the opt ons.

} Chapter 16  Work ng w th fi es   295 . bool &date. as ustrated here if (isAFile) { ProcessFile(fi. Now that you know what k nd of object you have and what opt ons the user wants. you can pr nt out the deta s The first case s that for a s ng e fi e. } Th s sn’t qu te as stra ghtforward as you m ght th nk You have to create both FileInfo and DirectoryInfo objects and then use the r Exists propert es to check whether e ther of them recogn zes the path If ne ther of them returns true. if (fi->Exists) isAFile = true.void ParseOptions(String ^opts. the most ke y exp anat on s that the path doesn’t ex st. thus sett ng them n th s funct on w change the r va ue back n the main funct on 6. so you pr nt an error message and ex t 7. if (opts->Contains("a")) atts = true. if (opts->Contains("d")) date = true. else { Console::WriteLine("No such file or directory"). atts). bool &size. bool &atts) { opts = opts->ToLower(). } } The three bool var ab es are passed n by reference rather than by va ue. if (opts->Contains("v")) { size = date = atts = true. DirectoryInfo ^di = gcnew DirectoryInfo(path). return -1. bool isADirectory = false. FileInfo ^fi = gcnew FileInfo(path). and the code for that s very s mp e. Check whether the path represents a fi e or a d rectory by add ng the fo ow ng code to the main funct on bool isAFile = false. else if (di->Exists) isADirectory = true. size. date. } else { if (opts->Contains("s")) size = true.

bool atts) { // Echo the filename and length Console::Write("{0. Aga n. if (size) Console::Write(" {0. fi->Name). } Console::WriteLine(). else { if ((fa & FileAttributes::Archive) == FileAttributes::Archive) Console::Write("a"). f t s negat ve. and t wou d be s mp e to extend the app cat on to check for them 9. st ts contents We w st subd rector es first. bool date. use the stat c GetAttributes method on the File c ass to obta n the FileAttributes You can then use the b tw se AND operator (&) to match aga nst the var ous va ues defined n the FileAttributes c ass Th s code on y checks for four attr butes There are many more. File::GetLastAccessTime(fi->ToString())).10}". if ((fa & FileAttributes::Normal) == FileAttributes::Normal) Console::Write("<normal>").8. if ((fa & FileAttributes::System) == FileAttributes::System) Console::Write("s"). Console::Write(" "). p ace the code for process ng a fi e n a separate funct on before main void ProcessFile(FileInfo ^fi. format spec fiers can take an opt ona fie d w dth after the fie d number If th s va ue s pos t ve. the va ue s r ght-just fied n the fie d. if ((fa & FileAttributes::ReadOnly) == FileAttributes::ReadOnly) Console::Write("r"). fi->Length). pass ng t the path The eas est way to get the path s to ca ToString on the FileInfo object Observe the use of a fie d w dth when pr nt ng the name.30}". d rectory names w be pr nted n uppercase etters. } } The funct on first pr nts the fi e name and then d sp ays other deta s. If the user has entered a d rectory. if ((fa & FileAttributes::Hidden) == FileAttributes::Hidden) Console::Write("h"). fo owed by fi es. bool size. and fi e names n owercase. but you can obv ous y change th s to d sp ay them however you want Add the fo ow ng code for st ng the subd rector es 296  Microsoft Visual C++/CLI Step by Step . if (atts) { FileAttributes fa = File::GetAttributes(fi->ToString()). n the nterests of modu ar ty. depend ng on the opt ons chosen by the user The ast access t me can be obta ned by ca ng one of the stat c methods on the File c ass. if (date) Console::Write(" {0}". the va ue s eft-just fied A fie d w dth of 30 characters shou d be w de enough for most fi es If the user has requested attr butes.

} // Now do the files } The Directory::GetDirectories funct on returns an array of str ngs represent ng the names of the subd rector es Loop over th s st. } As you can see.. and then pass ng t to the processFile funct on 11. such as the fo ow ng CppFiles v . t s s mp y a case of retr ev ng a st of fi e names by us ng GetFiles. for (int i=0. You shou d see output s m ar to the fo ow ng screen shot. for (int i=0. s mp y pr nt a coup e of dashes 10. i++) { DirectoryInfo ^inf = gcnew DirectoryInfo(dirs[i]). Bu d the app cat on. i<dirs->Length. Console::Write(" {0. and then change to the project’s Debug d rec- tory You can then run the app cat on w th a su tab e command ne. st ng the fi es n the parent d rectory Chapter 16  Work ng w th fi es   297 . atts). i++) { FileInfo ^fi = gcnew FileInfo(files[i]). creat ng a DirectoryInfo object from each entry.30}". String ^name = inf->Name->ToUpper(). and pr nt ng out ts deta s Because there s no s ze for a d rectory. date. // no size for dirs if (date) Console::WriteLine(" {0}". i<files->Length. ProcessFile(fi. Console::Write("{0. Process the fi es by us ng the same funct on you defined ear er P ace the fo ow ng code after the “Now do the fi es” comment array<String^> ^files = Directory::GetFiles(di->ToString()). creat ng a FileInfo object for each fi e.10}". "--"). open a conso e w ndow. Directory::GetLastAccessTime(inf->ToString())). size. name).else if (isADirectory) { // Process the subdirectories array<String^> ^dirs = Directory::GetDirectories(di->ToString()).

as we Flush Causes a buffered data to be wr tten to the under y ng dev ce Seek Sets the seek pos t on w th n the under y ng stream Write Wr tes a va ue to the stream Write7BitEncodedInt Wr tes a 32 b t nteger n a compressed format If you ook at the V sua Stud o 2012 documentat on. the b nary I/O c asses use an under y ng Stream object to prov de a byte stream Both BinaryReader and BinaryWriter have a BaseStream property that g ves access to the under y ng Stream The BinaryWriter class The fo ow ng tab e sts the methods prov ded by BinaryWriter Method Description Close C oses the wr ter and the under y ng stream Dispose Re eases a unmanaged resources used by the wr ter and.Tip  If you want to run the application under the Visual Studio debugger.NET languages must support. you’ see that the Write funct on has no fewer than 18 over oads for you to cope w th when wr t ng the var ous bas c types prov ded by the NET Framework Because not a the types prov ded by NET are comp ant w th the Common Language Spec ficat on (CLS). click the Debugging option. Binary I/O B nary I/O n the NET Framework uses the BinaryReader and BinaryWriter c asses. You can now run the application in debug mode. To do so. and then. you will need to provide the command-line arguments for the application. The most important of these is Microsoft Visual Basic . re eases managed resources.NET languages. in the Command Arguments edit control. you need to be carefu when us ng some of the Write methods f you ntend for the data to be read from code wr tten n other NET anguages Note  The CLS defines types that all .NET. 298  Microsoft Visual C++/CLI Step by Step . enter the arguments. opt ona y. bring up the property pages for the project. which doesn’t support any of the non–CLS-compliant types. wh ch read and wr te NET pr m t ve types n b nary format As w th the TextReader and TextWriter c asses. The signed byte and unsigned integer types are not included in the CLS. In the Configuration Properties section. so they might not be usable from some .

.

and there’s a set of read-on y propert es to a ow access to the data members The Read and Write funct ons use BinaryReader and BinaryWriter objects to read and wr te the state of the object n b nary format 300  Microsoft Visual C++/CLI Step by Step .0) { } Customer(String ^n. bw->Write(balance). accNo(0). accNo = br->ReadInt32(). } }. accNo(ac). long ac. a long for the account number. The c ass has three data members a String for the name. } } // Write object void Write(BinaryWriter ^bw) { bw->Write(name).public: // Default constructor Customer() : name(nullptr). and a double for the ba ance There are constructors to create defau t and fu y popu ated objects. balance(bal) { } // Properties to retrieve instance data property String ^Name { String ^get() { return name. double bal) : name(n). balance(0. balance = br->ReadDouble(). bw->Write(accNo). } } property long AccountNumber { long get() { return accNo. } // Read object void Read(BinaryReader ^br) { name = br->ReadString(). } } property double Balance { double get() { return balance.

2345678. } catch(IOException ^iex) { Console::WriteLine(iex->Message).0). return 0.0). 1234567.0). Create some Customer objects // Create some Customer ^c1 = Customer ^c2 = Customer ^c3 = customers gcnew Customer("Fred Smith". return -1.4. } String ^path = args[0]. you need a BinaryWriter and a FileStream to do the output to the fi e FileStream ^fs = nullptr. gcnew Customer("Jane Doe". FileAccess::ReadWrite). gcnew Customer("Gill Evans". } finally { if (fs != nullptr) fs->Close(). 6. 500. try { // Create a FileStream to write to the file fs = gcnew FileStream(path. Th s code s very s m ar to the argument-hand ng code that has been used n other exerc ses n th s chapter Note that for s mp c ty I’m not check ng the path for va d ty. FileMode::Create. no matter what happens. but you obv ous y do not want to do th s f creat ng the FileStream fa ed Chapter 16  Work ng w th fi es   301 . creat ng t f necessary. // Create a BinaryWriter BinaryWriter ^bw = gcnew BinaryWriter(fs). but t’s easy— and adv sab e—to add such a check n a rea app cat on 5. Add the fo ow ng code to main to check that the user passes n a fi e name and save the path as a String if (args->Length == 0) { Console::WriteLine("Usage: CppBinRead [path]"). To wr te the objects. t’s good pract ce to put the I/O c ass creat on code n a try b ock to catch any prob ems that m ght occur The finally b ock ensures that the fi e s c osed. 3456789. 100. 1000. } The FileStream wr tes to a fi e. and the fi e w be opened w th read/ wr te access because you’ be read ng from t ater n the app cat on Aga n.

the s gn reflect ng whether the offset shou d move toward the start (negat ve) or end (pos t ve) of the stream The poss b e pos t ons are members of the SeekOrigin enumerat on. create a BinaryReader object and attach t to the same FileStream. ready for the next wr te If you want to read from the stream. and they can be SeekOrigin::Current (the current pos t on). g v ng t an offset n bytes and a pos t on where the offset shou d be app ed Offsets can be pos t ve or negat ve. but t’s a so poss b e to move th s po nter yourse f f you need to (and f you know what you’re do ng) The most ke y t me you’ need to move the po nter s when you open a stream for read/ wr te access After you’ve wr tten to the stream. read the exp anat on n the fo ow ng s debar Streams and seek pointers Every stream n NET has a seek pointer assoc ated w th t. pass ng n a po nter to the BinaryWriter Add the fo ow ng code at the end of the try b ock // Write the objects to the file c1->Write(bw). you have to move the pos t on of the seek po nter // Move back to the beginning br->BaseStream->Seek(0. SeekOrigin::Begin (the start of the Stream). Wr t ng the object data to the fi e s s mp y a case of ca ng the Write funct on. SeekOrigin::Begin). the seek po nter s pos t oned at the end. 9. you’ have to repos t on the po nter You repos t on the po nter by us ng the Seek method of the Stream object. Before you can read from a fi e to wh ch you’ve wr tten. 8. c2->Write(bw). 7. you can now read from the fi e To do so. wh ch represents the pos t on n the stream at wh ch the next read or wr te operat on w take p ace Th s po nter s automat ca y repos t oned when you use Stream c ass methods to read or wr te the stream. Not ce that th s code uses the BaseStream property and ts assoc ated seek po nter to get at the under y ng Stream object If you haven’t encountered seek po nters before. Because the fi e was opened w th read/wr te access. as shown here // Create a BinaryReader that reads from the same FileStream BinaryReader ^br = gcnew BinaryReader(fs). or SeekOrigin::End (the end of the Stream) 302  Microsoft Visual C++/CLI Step by Step .Note  You might find that Visual Studio complains that the FileMode and FileAccess enumerations are ambiguous. c3->Write(bw). You can ignore this because the code will compile perfectly well.

12. you can expect to get an except on thrown Tip  If you want to save the state of objects in a real-world application. you wouldn’t do it manually like this. sw->Close(). Create a StreamReader that reads from a FileStream and then use the ReadLine member of StreamReader. StreamReader ^sr = gcnew StreamReader(fs). String ^line = sr->ReadLine(). c4->Read(br). c4->Name. as fo ows Customer ^c4 = gcnew Customer(). Create a new empty Customer object and read ts deta s from the fi e. Read text from a fi e. Bu d and run the app cat on. The new Customer object has a ts fie ds set to defau t va ues The ca to Read d rects t to read ts data from the current pos t on n the fi e The obv ous potent a prob em s that the Read funct on w read from wherever the BinaryReader s current y pos t oned If t sn’t at the beg nn ng of a Customer object’s data. FileMode::Open). sw->WriteLine("Some text"). FileMode::Append). c4->AccountNumber.txt". Console::WriteLine("Balance for {0} (a/c {1}) is {2}".10. Chapter 16  Work ng w th fi es   303 .txt". c4->Balance). Cont nue w th the project from the prev ous exerc se 11. Create a StreamWriter that outputs to a FileStream and then use the Write and WriteLine members of StreamWriter. For ex amp e: FileStream ^fs = gcnew FileStream("foo. For examp e: sw->Flush(). F ush and c ose the StreamWriter when you re fin shed w th t. For examp e: FileStream ^fs = gcnew FileStream("foo. prov d ng a su tab e fi e name Quick reference To Do this Wr te text to a fi e. The System::Runtime::Serialization namespace contains classes that help you save and restore the state of objects in an efficient way. StreamWriter ^sw = gcnew StreamWriter(fs).

.

ndependent when NET s ported to other p atforms XML p ays a major part n th s p an by act ng as a s mp e. ■ Wr te XML by us ng XmlTextWriter. you might want to consult a book such as XML Step by Step. and all the other paraphernalia that make up XML. validation.C HAP TE R 17 Reading and writing XML After comp et ng th s chapter. portab e g ue ayer that’s used to pass data around n d str buted app cat ons 305 . you w be ab e to ■ Understand why XML s so mportant to M crosoft NET ■ Descr be the c asses that make up the NET XML namespaces ■ Parse XML fi es by us ng XmlTextReader. Second Edition by Michael Young (Microsoft Press. XML and .NET One of the major features of the NET Framework s that t makes t poss b e for you to eas y produce d str buted app cat ons that are anguage. so if you haven’t worked with it before. ■ Va date XML by us ng XmlValidatingReader.ndependent and that w be p atform. You should be comfortable with elements. 2002) before reading further. ■ Use the XmlDocument c ass to man pu ate XML n memory T h s chapter ntroduces you to the XML capab t es of the M crosoft NET Framework XML p ays a major ro e n NET as an enab ng techno ogy. There isn’t ample space to give you a complete foundation in XML and the XML technologies. attributes. namespaces. and the NET Framework prov des fu support for just about everyth ng you’ need to do w th XML Note  This chapter assumes that you already know something about XML.

.

recogn z ng e ements as t reads Very tt e data s cached n memory. w th no context So. you m ght need to use the XmlDocument c ass. f you need to keep track of where an e ement occurs w th n the document structure.Note  There are other. and you might see these being used in older code. wh ch s d scussed n the sect on “Us ng XmlDocument” ater n th s chapter XmlReader uses a pull model. ■ ■ XmlTextWriter prov des a fast. forward-on y way to wr te XML to streams or fi es The XML produced conforms to the W3C XML 1 0 spec ficat on. you’ need to do t yourse f If e ther of these consequences sounds ke m tat ons to you. It is now recommended that you use the XmlReader class. instead. mean ng that t fires events at ca back funct ons that you prov de The fo ow ng tab es st the ma n propert es and methods of the XmlReader c ass Property Description AttributeCount Returns the number of attr butes on the current node Depth Returns the depth of the current node n the tree Encoding Returns the character encod ng of the document EOF Returns true f the reader s at the end of the stream HasAttributes Returns true f the current node has any attr butes HasValue Returns true f the current node can have a va ue IsEmptyElement Returns true f the current e ement has no va ue Item Gets the va ue of an attr bute LocalName Returns the name of the current e ement w thout a namespace prefix Name Returns the fu name of the current e ement NamespaceURI Gets the namespace UR for the current node Chapter 17  Read ng and wr t ng XML   307 . such as XmlTextReader and XmlValidatingReader. wh ch uses a push model. concrete reader classes in System::Xml. comp ete w th namespace support XmlDocument mp ements the W3C Document Object Mode (DOM). but the forwardon y sty e has two ma n consequences The first s that t sn’t poss b e to go back to an ear er po nt n the fi e w thout read ng from the beg nn ng aga n The second consequence s s ght y more subt e E ements are read and presented to you one by one. wh ch means that you ca a funct on to get the next node when you’re ready Th s mode s n contrast to the w de y used S mp e API for XML (SAX) API. prov d ng an n-memory representat on of an XML document Parsing XML by using XmlReader Let’s start by ook ng at how you can parse XML by us ng the XmlReader c ass An XmlReader prov des you w th a way to parse XML data that m n m zes resource usage by read ng forward through the document.

.

.

.

0" ?> <!-. set DtdProcessing to Parse If you want to va date the nput aga nst a DTD. Add the fo ow ng ne to the top of CppXm Reader cpp using namespace System::Xml.■ ■ ■ If the nput conta ns ent t es or other features defined n a DTD. Antarctica</location> <height value="3794" unit="m"/> <type>stratovolcano</type> <eruption>constant activity</eruption> <magma>basanite to trachyte</magma> </volcano> <volcano name="Hekla"> <location>Iceland</location> <type>stratovolcano</type> <height value="1491" unit="m"/> <eruption>1970</eruption> <eruption>1980</eruption> <eruption>1991</eruption> <magma>calcalkaline</magma> <comment>The type is actually intermediate between crater row and stratovolcano types</comment> </volcano> <volcano name="Mauna Loa"> <location>Hawaii</location> <type>shield</type> <height value="13677" unit="ft"/> <eruption>1984</eruption> <magma>basaltic</magma> </volcano> </geology> 1. Start M crosoft V sua Stud o 2012 and create a new CLR Conso e App cat on project named CppXmlReader 2.Volcano data --> <geology> <volcano name="Erebus"> <location>Ross Island. set ValidationType to DTD and set DtdProcessing to Parse If you want to va date the nput aga nst one or more schemas. set ValidationType to Schema and set Schemas to an XmlSchemaSet object that references the schema set The fo ow ng exerc se shows you how to read an XML document by us ng an XmlReader Fo ow ng s the samp e XML document used by th s exerc se and the other exerc ses n th s chapter Th s document sts deta s of three vo canoes and conta ns many common XML constructs <?xml version="1. It’s eas er to use the c asses f you nc ude a using d rect ve for the System::Xml namespace Chapter 17  Read ng and wr t ng XML   311 .

str ngs.. create an XmlReader to parse the fi e We start w th a s mp e parser. settings->ConformanceLevel = ConformanceLevel::Document. wh ch requ res a fu XML document rather than a fragment but doesn’t do any va dat on try { // Create the settings object XmlReaderSettings ^settings = gcnew XmlReaderSettings(). 4. } String ^path = gcnew String(args[0]). streams. } catch (Exception ^ex) { Console::WriteLine(ex->Message). } The settings object s set to requ re a fu document and to gnore any comment nes Because the XmlReader constructor takes the name of the document you want to parse. settings). Now that you have the path. or you can use the Debugg ng page of the project’s propert es to enter the fi e name and run t from w th n V sua Stud o Keep n m nd that XmlReader sn’t m ted to read ng from fi es You can over oad Create to take XML nput from URLs. and other XmlReader objects 5. // Create the reader. Pars ng the fi e s mp y means mak ng repeated ca s to the Read funct on unt the parser runs out of XML to read The s mp est way to do th s s to put a ca to Read ns de a while oop Add th s code to the end of the code ns de the try b ock // Read nodes while (rdr->Read()) { // do something with the data } 312  Microsoft Visual C++/CLI Step by Step . return -1. nc ud ng pass ng the constructor a bad path name You can bu d and run the app cat on from the command ne at th s stage f you want to check that the fi e opens correct y. XmlReader ^rdr = XmlReader::Create(path. Add th s code to the beg nn ng of the main funct on to check the number of arguments and save the path // Check for required arguments if (args->Length == 0) { Console::WriteLine("Usage: CppXmlReader [path]"). t’s a good dea to catch except ons here because severa th ngs can go wrong at th s stage..3.

case XmlNodeType::Document: Console::WriteLine("-> Document node"). break. case XmlNodeType::EndElement: Console::WriteLine("-> End element node. just those that occur n the samp e document Observe that the Name and Value propert es are used for some node types Whether a node has a Name and a Value depends on the node type For examp e. } } Every t me a new node s read. name={0}". break. value={1}". break. wh ch dent fies severa of the most common node types // Read nodes while (rdr->Read()) { switch (rdr->NodeType) { case XmlNodeType::XmlDeclaration: Console::WriteLine("-> XML declaration"). name={0}". so the app cat on pr nts noth ng when t encounters a wh te space node Chapter 17  Read ng and wr t ng XML   313 . value={0}". the switch statement checks ts type aga nst members of the XmlNodeType enumerat on I haven’t nc uded the cases for every poss b e node type. break. default: Console::WriteLine("** Unknown node type"). and you can then query the NodeType property to determ ne the type of node w th wh ch you are dea ng Add the fo ow ng code. but the CppXm Reader app cat on sn’t rea y nterested n wh te space. rdr->Name). e ements have names and can have va ues. Each ca to Read pos t ons the XmlReader on a new node. name={0}. case XmlNodeType::Element: Console::WriteLine("-> Element node. break. rdr->Name). case XmlNodeType::Comment: Console::WriteLine("-> Comment node. break. case XmlNodeType::Whitespace: break. rdr->Name. and comments have a va ue (the comment text) but not names Process ng nstruct ons norma y have both names and va ues A so not ce that nodes of type XmlNodeType::Whitespace are s mp y d scarded The vo canoes xm fi e conta ns p enty of wh te space to make t readab e to humans.The Read funct on returns true or fa se depend ng on whether there are any more nodes to read 6. rdr->Value). case XmlNodeType::Text: Console::WriteLine("-> Text node. break. rdr->Value).

t w throw an XmlException to a ert you as to what t th nks s wrong As w th a pars ng errors. wh ch means that e ements are correct y nested and that every e ement tag has a match ng end-e ement tag If the XmlReader encounters bad y formed XML. name=type Text node. the volcano e ement has a name attr bute. value=Ross Island. value= Volcano data Element node. Antarctica End element node. you’re go ng to have to put code n p ace to do that Verifying well-formed XML XML that s correct y constructed s ca ed well-formed XML. name=location Text node. name=location Element node. and the height e ement has value and unit attr butes To process the attr butes on an e ement. w th the content of a node represented by a nested Text node You can see that the nodes are presented to you n near sequence. name=geology Element node. value=stratovolcano End element node. value=constant activity The first node s the XML dec arat on at the beg nn ng of the document. name=. so f you want to keep track of the h erarch ca structure of the document. the p ace where t’s reported m ght be some d stance from the actua ocat on of the error Handling attributes XML e ements can nc ude attr butes.7. name=height Element node. Bu d the app cat on and run t from the command ne. name=volcano Element node. name=eruption Text node. name=type Element node. g v ng the name of an XML fi e CppXmlTextReader volcanoes. add code to the Element case n the switch statement so that t ooks ke th s 314  Microsoft Visual C++/CLI Step by Step .xml The first few nes of the output shou d ook ke th s -> -> -> -> -> -> -> -> -> -> -> -> -> XML declaration Comment node. wh ch s fo owed by a comment whose va ue s the comment text Each XML e ement n the document produces a match ng pa r of Element and EndElement nodes. wh ch cons st of name/va ue pa rs and are a ways str ng data In the samp e XML fi e.

height. rdr->Value). you can use the MoveToElement method to pos t on the reader back to the parent e ement When you run the code. rdr->Name).eruption+. rdr->Name. } break. you can use the MoveToAttribute funct on to pos t on the reader on a part cu ar attr bute by spec fy ng e ther a name or a zero-based ndex Attr butes are read a ong w th the e ement node of wh ch they’re a part When read ng attr butes. each of wh ch has a name and a va ue A ternat ve y.comment?)> volcano name CDATA #IMPLIED> location (#PCDATA)> height EMPTY> height value CDATA #IMPLIED unit CDATA #IMPLIED> type (#PCDATA)> eruption (#PCDATA)> magma (#PCDATA)> comment (#PCDATA)> Note  I’ve used a DTD for simplicity. Console::WriteLine(). name={0}". name=height value=13677 unit=ft Parsing XML with validation There are a number of ways to va date the correctness of XML documents.type. and XmlReader supports the two most common standards DTDs and W3C schemas The fo ow ng exerc se mod fies the app cat on to va date the XML as t’s parsed To perform va dat on. if (rdr->AttributeCount > 0) { Console::Write(" "). you need to have a DTD or a schema aga nst wh ch to va date Here’s a DTD for the vo cano XML data (th s s n a fi e named geo ogy dtd) <!ELEMENT <!ELEMENT <!ATTLIST <!ELEMENT <!ELEMENT <!ATTLIST <!ELEMENT <!ELEMENT <!ELEMENT <!ELEMENT geology (volcano)+> volcano (location.case XmlNodeType::Element: Console::WriteLine("-> Element node. and the MoveToNext Attribute method makes t poss b e for you to terate over the co ect on of e ements. you shou d see output s m ar to th s for nodes that have attr butes -> Element node. The AttributeCount property nd cates how many attr butes an e ement has. Chapter 17  Read ng and wr t ng XML   315 . while (rdr->MoveToNextAttribute()) Console::Write(" {0}={1}". but a schema can be used in exactly the same way.magma.

validationSettings->ValidationType = ValidationType::DTD. The constructor for the second reader takes a reference to the n t a reader. as shown here using namespace System::Xml::Schema. wh ch t uses to perform the bas c pars ng tasks Not ce how you must enab e DTD pars ng n the second sett ngs object as we as the first 5. rdr 6. validationSettings). as demonstrated n the fo ow ng // Create settings for DTD validation XmlReaderSettings ^validationSettings = gcnew XmlReaderSettings(). you can add va dat on by cha n ng two readers together. validatingReader. s ocat on-type-he ght rather than the ocat onhe ght-type order demanded by the DTD So.Ed t the vo canoes xm fi e to add a DOCTYPE reference at the top of the fi e <?xml version="1. and the nc us on of the using dec arat on makes t eas er to refer to them n code 3.0" ?> <!DOCTYPE geology SYSTEM "geology. Ed t a the code that parses the XML to use the new reader. Add a using dec arat on to the top of the CppXm Reader cpp. validationSettings->DtdProcessing = DtdProcessing::Parse. when you parse th s XML w th va dat on.dtd"> <!-. t shou d throw an except on when t finds the nva d e ement order ng n the document The element 'volcano' has invalid child element 'type'. Hek a. you’ not ce that there’s a prob em The e ement order ng for the second vo cano. 316  Microsoft Visual C++/CLI Step by Step . 4. Add another property to the XmlReaderSettings to cause the reader to parse the DTD If you do not set th s. // Create a validating reader and wrap the existing one XmlReader ^validatingReader = XmlReader::Create(rdr. If you a ready have a reader. pars ng w fa because the defau t sett ng proh b ts DTD pars ng settings->DtdProcessing = DtdProcessing::Parse. If you now bu d and run the app cat on. you’d expect a va dat on error from the parser 1. Cont nue w th the project from the prev ous exerc se 2.Volcano data --> If you check the samp e XML document aga nst the DTD. Some of the c asses and enumerat ons are part of the System::Xml::Schema namespace. List of possible elements expected: 'height'. rather than the or g na reader.

you’ be ab e to hand e the va dat on errors yourse f and take appropr ate act on 7. The ValHandler c ass conta ns one stat c member. the hand er s passed a ValidationEventArgs object that conta ns deta s about the parser va dat on error Th s samp e code sn’t do ng anyth ng except pr ntng the error message. so create a new c ass to host a stat c hand er funct on Add th s code before the main funct on // Validation handler class ref class ValHandler { public: static void ValidationHandler(Object ^sender. ValidationEventArgs ^args) { Console::WriteLine("Validation Event: {0}".You can mprove on th s error hand ng by nsta ng an event hand er The parser fires a ValidationEvent whenever t finds someth ng to report to you. L nk up the hand er to the sett ngs object n the usua way // Set the handler validationSettings->ValidationEventHandler += gcnew ValidationEventHandler(&ValHandler::ValidationHandler). wh ch s the hand er for a ValidationEvent As usua . but n pract ce. but you w see the messages pr nted out from the event hand er as t finds va dat on prob ems 10. and f you nsta a hand er for th s event. the hand er has two arguments a po nter to the object that fired the event. the reader w not know about the va dat on 9. you’d dec de what act on to take based on the Severity property of the ValidationEventArgs object 8. Bu d and run the app cat on Th s t me. Ensure that you set up the hand er before the ca to XmlReader::Create. Correct the order ng of the e ements n the XML fi e and then run the app cat on aga n You shou dn’t see any va dat on messages th s t me through Chapter 17  Read ng and wr t ng XML   317 . Event hand er funct ons must be members of a managed c ass. args->Message). you won’t get the except on message. otherw se. } }. and an argument object In th s case.

Namespaces Determ nes whether to support namespaces. start tags and end tags. The va ue w be nu f there s no xml:lang attr bute n the current scope. f any WriteAttributes Wr tes out a set of attr butes WriteAttributeString Wr tes an attr bute w th a spec fied va ue WriteBase64. or Content ( t s wr t ng e ement content) Method Description Close C oses the wr ter and the under y ng stream Flush F ushes whatever s n the buffer LookupPrefix Returns the current namespace prefix. XmlSpace Represents the va ue of the xml:space attr bute. The state of the wr ter nd cates what the wr ter s do ng at the po nt where you query the property It w report one of the va ues from the WriteState enumerat on. such as Start (no wr te methods have been ca ed yet). The defau t s Formatting::None. respectively Property Description BaseStream Gets the under y ng stream object Formatting Determ nes whether the XML s output w th ndentat on.Writing XML by using XmlTextWriter If you’ve read about XML. The va ue must be a s ng e or doub e quotat on mark. you’re probab y aware that the W3C XML 1 spec ficat on descr bes the ser a zed form of XML—the way that XML appears when rendered as text—comp ete w th ang e brackets. and namespace and XML dec arat ons If you have some data that you want to wr te as XML. The defau t s true. XmlLang Gets a str ng that represents the va ue of the xml:lang attr bute. QuoteChar Represents the character used to quote attr bute va ues. Closed. but the NET Framework prov des you w th the XmlTextWriter c ass to he p w th a ot of the formatt ng chores such as keep ng track of ndentat on and nsert ng namespace nformat on everywhere t’s needed The tab es that fo ow st the propert es and methods of the XmlTextWriter class. Indentation Determ nes the ndentat on eve . The defau t s a space. WriteBinHex Encodes b nary bytes as Base64 or B nHex. t sn’t hard to do t manua y. IndentChar Represents the ndentat on character. Settings Gets the XmlWriterSettings object used when crea ng th s XmlWriter nstance WriteState Gets the state of the wr ter (d scussed n the fo ow ng text). The defau t s 2. and wr tes the text 318  Microsoft Visual C++/CLI Step by Step . The defau t s doub e. Attribute ( t s wr t ng an attr bute).

.

4. such as UTF-7 or ASCII. writer->Close(). } catch (Exception ^ex) { Console::WriteLine(ex->Message). 5. } String ^path = gcnew String(args[0]). XmlTextWriter can produce output that emp oys ndents or that has no formatt ng The defau t s no formatt ng. return -1.3. Let’s wr te the XML dec arat on to the fi e Add the fo ow ng nes to the end of the code ns de the try b ock // Set the formatting writer->Formatting = Formatting::Indented. } The wr ter s created by spec fy ng the path for the new fi e and the character encod ng that shou d be used Pass ng a nu po nter means that the wr ter w use the defau t UTF-8 encodng. // Use the default encoding XmlTextWriter ^writer = gcnew XmlTextWriter(path.. Create an XmlTextWriter by add ng the fo ow ng code (wh ch s very s m ar to the code used to create the XmlReader n the prev ous exerc se) try { // Create the writer. // Write the standard document start writer->WriteStartDocument(). you can specify a System::Text::Encoding object of the appropriate type. so you need to set the Formatting property f you want ndentat on The defau ts for the ndentat on character (a space) and the ndentat on eve (two characters) are usua y qu te acceptab e 320  Microsoft Visual C++/CLI Step by Step .. nullptr). th s s a good defau t cho ce Note  If you want to use another encoding. // Flush and close writer->Flush(). Add th s code to the start of the main funct on to check the number of arguments and save the path // Check for required arguments if (args->Length == 0) { Console::WriteLine("Usage: CppXmlWriter [path]").

0"?> <geology /> 8.xml You’ see that the app cat on wr tes an empty root e ement <?xml version="1.WriteStartDocument produces a standard XML dec arat on To ensure that a the text s output to the fi e.Helens"). // Close the root element writer->WriteEndElement(). as shown here // Write the standard document start writer->WriteStartDocument(). writer->WriteEndElement(). // Start the root element writer->WriteStartElement("geology"). // Do the name attribute writer->WriteAttributeString("name". // Write the location element writer->WriteStartElement("location"). // Write the height element writer->WriteStartElement("height"). but you st need both ca s Bu d and run the app cat on at th s stage. as ustrated n the fo ow ng // Start the root element writer->WriteStartElement("geology"). "ft"). g v ng the name of the XML fi e CppXmlWriter test1. writer->WriteEndElement(). USA"). writer->WriteAttributeString("value". Wr te the root e ement to the document. The content of the root e ement w go between the ca s to WriteStartElement and WriteEndElement There sn’t any content n th s case. writer->WriteAttributeString("unit". you shou d ca Flush and Close before ex t ng 6. To see how some of the other methods of XmlTextWriter are used. // Start the volcano element writer->WriteStartElement("volcano"). writer->WriteEndElement(). "9677"). writer->WriteString("Washington State. "Mount St. writer->WriteString("stratovolcano"). Chapter 17  Read ng and wr t ng XML   321 . add one of the vo cano entr es to the root e ement. // Write the type element writer->WriteStartElement("type"). 7.

writer->WriteString("1980").0"?> <geology> <volcano name="Mount St. prov d ng t w th a su tab e fi e name The fi e shou d conta n XML that ooks very much ke th s <?xml version="1. and you have to be carefu to nest a the ca s correct y 9. and how everyth ng s proper y ndented Using XmlDocument Our hand ng of XML so far has been forward-on y. I’ve eft n the root e ement code so that you can see how everyth ng nests Add ng extra e ements sn’t hard. writer->WriteEndElement(). writer->WriteEndElement(). how they are nested correct y. wh ch s very ght on resource usage but sn’t so usefu f you need to move around w th n the XML document The XmlDocument c ass s based on the W3C DOM. but t’s rather ong-w nded. // Write the magma element writer->WriteStartElement("magma"). or create an XML document 322  Microsoft Visual C++/CLI Step by Step . writer->WriteString("basalt. // Close the volcano element writer->WriteEndElement(). Bu d and run the app cat on. // Close the root element writer->WriteEndElement(). writer->WriteStartElement("eruption"). writer->WriteEndElement(). writer->WriteString("1857"). andesite and dacite"). mod fy. and t’s the c ass that you want to use f you need to browse. andesite and dacite</magma> </volcano> </geology> You can see how a the e ements conta n the r attr butes. USA</location> <height value="9677" unit="ft" /> <type>stratovolcano</type> <eruption>1857</eruption> <eruption>1980</eruption> <magma>basalt.Helens"> <location>Washington State.// Write the eruption elements writer->WriteStartElement("eruption").

.

.

.

.

.

but t does show how to use severa XmlDocument and XmlNode methods and propert es 8. } 7.5. Add some code to the main funct on to create an XmlBuilder object Ensure that you are pre- pared to hand e any except ons that occur // Create a Builder and get it to read the file try { XmlBuilder ^builder = gcnew XmlBuilder(path). add an XmlNode^ member to the XmlBuilder c ass. Cont nue work ng on the CppDom project Start work ng w th the tree by gett ng a hand e to ts root Because you’ use th s root severa t mes. but except ons are eft for the ca er to hand e 6. Console::WriteLine("Document loaded"). } Un ke XmlReader. the XmlDocument c ass reads and parses the fi e when t’s constructed Note that you’re not catch ng except ons here Someth ng m ght go wrong when open ng or pars ng the fi e. what you’ do s find the second e ement and nsert a new e ement after t There are a number of ways n wh ch you cou d do th s. 328  Microsoft Visual C++/CLI Step by Step . Try bu d ng and runn ng the app cat on at th s po nt F rst copy the vo canoes xm and geo ogy dtd fi es you created ear er from the debug fo der nto the project fo der If you see the “Document oaded” message d sp ayed when you run the app cat on. you know that the document has been oaded and parsed The next step s to access the nodes n the tree The current XML document conta ns three vo cano e ements. ke th s private: XmlNode ^root. Add a constructor that creates an XmlDocument object. // Load the data doc->Load(path). } catch(Exception ^ex) { Console::WriteLine(ex->Message). I’ just ustrate one method It sn’t the most effic ent way to do the job. but for now. and nstruct t to oad the fi e that was spec fied on the command ne public: XmlBuilder(String ^path) { // Create the XmlDocument doc = gcnew XmlDocument().

add an XmlNodeList^ member to the c ass to ho d the st private: XmlNodeList ^nodelist.9. wh ch s one eve down 10. Be certain that you don’t remove the line that assigns the value to nodelist! Chapter 17  Read ng and wr t ng XML   329 . You a so need to get the st of ch d nodes for the root Because you’ be us ng th s st aga n. the DOCTYPE dec arat on. so you need to add the fo ow ng code near the top of the CppDom cpp fi e. wh ch means that you can get an enumerator to terate over the nodes The code terates over the ch d nodes. after the other using d rect ves using namespace System::Collections. The ChildNodes property returns a st of ch d nodes as an XmlNodeList The XmlNodeList s a typ ca NET co ect on c ass. you shou d see output s m ar to the fo ow ng Document loaded Child: xml Child: geology Child: #comment Child: geology The root of the tree has four ch d nodes the XML dec arat on. you can remove the lines that declare and use the enumerator because you won’t need them again. 13. If you run th s code on the vo canoes xm fi e. while (ie->MoveNext() == true) Console::WriteLine("Child: {0}". The IEnumerator nterface s part of the System::Collections namespace. a comment. t has to be cast to an XmlNode^ before you can use the Name property 12. pr nt ng the name of each Note that because Current returns an Object hand e. DocumentElement returns you the top of the DOM tree Note that th s s not the root e ement of the XML document. IEnumerator ^ie = nodelist->GetEnumerator(). The code that fo ows shows how you can get a st of ch d nodes and terate over t Add th s to the constructor // get the child node list nodelist = doc->ChildNodes. 11. Add the fo ow ng code to the constructor to get the root node // Get the root of the tree root = doc->DocumentElement. (dynamic_cast<XmlNode^>(ie->Current))->Name). and the root node Note  After you’ve verified the existence of the child nodes.

// Create a new volcano element XmlElement ^newVolcano = CreateNewVolcano(). // See if it is the root if (node->NodeType == XmlNodeType::Element && node->Name->Equals("geology")) { Console::WriteLine(" Found the root"). ProcessRoot(node). } The funct on s passed n the root node I know that the fi e I’m work ng w th has more than two vo cano e ements. you’d obv ous y need to put n a ot more check ng to ensure that you were retr ev ng the des red node After the node has been retr eved. // Link it in root->InsertBefore(newVolcano. I can get a d rect reference to the second e ement by us ng the Item property on ChildNodes to access a ch d node by ndex In rea code. the pub c funct on ProcessRoot s then used to process the ch dren of the root XML e ement void ProcessRoot(XmlNode ^rootNode) { XmlNode ^node = dynamic_cast<XmlNode^>(rootNode->ChildNodes->Item(1)).14. you need to find the root e ement of the XML by us- ng a pub c c ass member funct on named ProcessChildNodes. you ca CreateNewVolcano to create a new volcano e ement Then. } } } The funct on creates an enumerator and terates over the ch dren of the root node The root XML e ement w be of type XmlNodeType::Element and w have the name geology 15. After you’ve dent fied that e ement. as shown here void ProcessChildNodes() { // Declare an enumerator IEnumerator ^ie = nodelist->GetEnumerator(). while (ie->MoveNext() == true) { // Get a handle to the node XmlNode ^node = dynamic_cast<XmlNode^>(ie->Current). and I know that I want to nsert a new one before the second e ement So. Now that you have the root of the tree. node). you use InsertBefore to nsert the new one mmed ate y before the node you just retr eved by ndex 330  Microsoft Visual C++/CLI Step by Step .

xtw->Flush(). wh ch creates a new volcano e ement To save space. however. so you need to create them by ca ng the appropr ate factory method The name attr bute s appended to the e ement’s co ect on of attr butes. so add a pub c funct on named PrintTree to the c ass. Console::WriteLine(). xtw->Formatting = Formatting::Indented. and so on—don’t have pub c constructors. as shown n the preced ng code Chapter 17  Read ng and wr t ng XML   331 . return newElement. newElement->AppendChild(locElement). I have om tted some the code for creat ng the ent re e ement. doc->WriteTo(xtw). It wou d be usefu to be ab e to pr nt out the mod fied tree. and then the location e ement s created w th ts content Bu d ng DOM trees ke th s s a process of creat ng new nodes and append ng them to one another 17. // Set the name attribute XmlAttribute ^att = doc->CreateAttribute("name"). Add the pub c CreateNewVolcano funct on. att->Value = "Mount St. XmlComment. USA").Helens". XmlText ^xtext = doc->CreateTextNode("Washington State. locElement->AppendChild(xtext). newElement->Attributes->Append(att). // Create the location element XmlElement ^locElement = doc->CreateElement("location"). I’ve nc uded enough so that you can see how t works XmlElement^ CreateNewVolcano() { // Create a new element XmlElement ^newElement = doc->CreateElement("volcano"). } You’ve a ready seen the use of XmlTextWriter to create XML manua y You can a so use t to output XML from a DOM tree by nk ng t up to an XmlDocument. as shown here void PrintTree() { XmlTextWriter ^xtw = gcnew XmlTextWriter(Console::Out).16. } The funct on creates a new XmlElement for the vo cano Not ce that the node c asses— XmlElement.

you can see that the new node has been added to the tree Remember that th s operat on has mod fied on y the DOM tree n memory. use the sett ngs to n t a ze an XmlReader.18. use the Read method to read nodes from the fi e. and set ts ValidationType property to ValidationType::DTD. Create an XmlReader.} catch(Exception ^ex) { Console::WriteLine(ex->Message). and pass t the name of a fi e. Add ca s to ProcessChildNodes and PrintTree to the main funct on. You must a so set the DtdProcessing property to DtdProcessing::Parse. Work w th XML n memory. Create an XmlReaderSettings object. 332  Microsoft Visual C++/CLI Step by Step . builder->ProcessChildNodes(). Then. Then. Create an XmlDocument and use ts Load or LoadXml funct on to parse XML nto a DOM tree n memory. } When you run the app cat on. the or g na XML fi e has not been changed Quick reference To Do this Parse XML w thout va dat on. and then bu d and test the app cat on try { XmlBuilder ^builder = new XmlBuilder(path). builder->PrintTree(). Create a hand er funct on for va dat on events and attach t to the ValidationEventHandler event of the XmlReader. Parse XML w th DTD va dat on.

you w be ab e to ■ Connect to a database ■ Execute SQL statements to query the database ■ Execute SQL statements to update the database ■ Create d sconnected app cat ons. you w earn how to use ADO NET to connect to a data source. oad data nto t from the database. DataReaders are easy to use but requ re that you rema n connected to the database as ong as you are us ng the reader A ternat ve y. mak ng t poss b e for d str buted app cat ons and serv ces to exchange data eas y and re ab y ADO NET offers two d st nct programm ng mode s. and perform database update operat ons You w a so earn how to use a DataSet n a d sconnected app cat on You w see how to fi a DataSet w th data from a database and d sp ay that data n a gr d 333 .CHAPTER 18 Using ADO. read-on y access to the data.NET After comp et ng th s chapter. and then d sconnect If you ed t the DataSet. th s can make t a more sca ab e so ut on In th s chapter. execute quer es. you can use a DataReader to terate over the resu ts of a query As you’ see. depend ng on the type of app cat on you need to bu d ■ ■ If you requ re forward-on y. you can a so update the database by us ng the changed data One major advantage of the DataSet s that you on y need to be connected to the database wh e exchang ng data. you can use a DataSet to represent an n-memory cache of data from the data source You can create a DataSet. wh ch use a DataSet to cache tab es n memory ■ Create a report d sp ay ng data from the database A DO NET s the data access API from M crosoft for the NET Framework ADO NET has been opt m zed to work w th NET.

However.Data.SqlClient Conta ns c asses that g ve opt m zed access to SQL Server 7 and ater System.ODBC Conta ns c asses that g ve access to Open Database Connect v ty (ODBC) data sources System.EntityClient Conta ns c asses that support the Ent ty Framework (d scussed n Chapter 24.Note  ADO. nc ud ng M crosoft SQL Server. Sybase. a so prov des access to databases such as Orac e. Sybase. Sybase.Data.NET? ADO NET s a strateg c API from M crosoft for data access n the modern era of d str buted. and if you write your code correctly.NET data providers ADO NET uses the concept of a data prov der to fac tate effic ent access to d fferent types of databases Each data prov der nc udes c asses to connect to a part cu ar type of database The NET Framework nc udes s x data prov ders. and so on System. Orac e. I want to emphasize that the principles are exactly the same whether you’re using Access or Microsoft SQL Server. and so on ADO. Internetbased app cat ons ADO NET conta ns a set of nterfaces and c asses w th wh ch you can work w th data from a w de range of databases.OleDb Conta ns c asses that g ve access to SQL Server 6.Data.Data.SqlServerCe Conta ns c asses that work w th SQL Server Compact Ed t on In add t on. and PostgreSQL 334  Microsoft Visual C++/CLI Step by Step . Access.NET provides access to any kind of relational database. SQL te.Data. “L v ng w th COM”) System.OracleClient Conta ns c asses that g ve access to Orac e databases System.Data.5 and ear er. To avoid the need to download and install database engines and deal with complex setups. Access. F reb rd. data prov ders are ava ab e for a number of other databases through th rd-party vendors Supported databases nc ude MySQL. IBM DB2. you should only have to change the configuration file to change to another database type. the examples in this chapter use a Microsoft Access database. Inform x. What is ADO. as shown n the fo ow ng tab e Data provider Description System.

.

such as n the fo ow ng examp e #using <System.NET assemblies Many of the ADO NET c asses are n the System::Data assemb y.Data. you w create a C++/CLI app cat on that connects to an Access database You w see how to set up the database connect on and prov der deta s n the app cat on configurat on fi e and then use a DbConnection object to estab sh a connect on 336  Microsoft Visual C++/CLI Step by Step .ADO.dll will be provided for you.Entity. c ck the Add New Reference button In the Add Reference d a og box that opens. as shown n the fo ow ng examp e using System::Data::SqlClient. or even from another assemb y that you’ve created n the same so ut on You can add references to a these types of assemb y n the same way On the Project menu.dll> #using <System. you need to nc ude the appropr ate using statements n your app cat on. c ck Framework And References At the bottom of the w ndow.Data. Creating a connected application In the next few pages. n the pane on the eft pane. the reference to System. n the pane on the eft. from a th rd-party brary assemb y. you w see the new dependency n the st After you have mported the assemb es you requ re.dll> // This assembly contains ADO. you can add using d rect ves for the namespaces. c ck one of the opt ons For examp e. Referencing external assemblies If you want to use a type defined n another assemb y. se ect ng Assemb es and then Framework d sp ays a the CLR brary assemb es for you to browse Se ect the entry you requ re and then press OK tw ce to d sm ss both d a og boxes If you now expand the Externa Dependenc es tem n So ut on Exp orer. both the comp er and the runt me need to know where that assemb y s ocated You m ght want to reference types from a Common Language Runt me (CLR) brary assemb y. a though some of the newer features (such as LINQ and Ent ty Framework) have the r own assemb es To use these assemb es.Data.NET classes // This assembly contains the // Entity Framework provider classes Note  If you are creating projects by using Microsoft Visual Studio 2012. c ck propert es to open the Project Propert es d a og box Se ect Common Propert es and then.

after the using namespace System. In the ConnectedApp cat on cpp fi e. Connecting to a database In th s exerc se. statement. 3. add the fo ow ng statements // Generic ADO. and then se ect Configurat on fi e (app config) as the fi e type Press Add. wh ch prov des fast. copy this file to a directory on your hard disk.w After you are connected. you w create a new app cat on to perform a the operat ons descr bed n the preced ng sect on The first step s to connect to the database 1.NET definitions using namespace System::Data. in the sample code files for this book. Before starting the exercise. Start M crosoft V sua Stud o 2012 and create a new CLR Conso e App cat on project named ConnectedApplication 2. r ght-c ck the project name to open the Add New Item d a og box (v a the shortcut menu) In the pane on the eft. and a fi e named app config w be added to the project and opened n the ed tor Chapter 18  Us ng ADO. c ck Ut ty. blog. forward-on y access to the rows n the resu t set You w use th s DbDataReader object to process the resu t set Note  You can find the sample database for this exercise. Add an app cat on configurat on fi e to the project In So ut on Exp orer. you w create a DbCommand object to represent a SQL statement You then perform the fo ow ng tasks ■ ■ ■ Use the ExecuteScalar method on DbCommand to execute a statement that returns a s ng e va ue Use the ExecuteNonQuery method on DbCommand to execute a statement that updates the database Use the ExecuteReader method to execute a statement that quer es the database Execute Reader returns a DbDataReader object.mdb. // Provider-independent classes using namespace System::Data::Common.NET   337 .

OleDb prov der 338  Microsoft Visual C++/CLI Step by Step . and wh ch s ocated n the same d rectory as the executab e For examp e. and f that s the case and you forget to put them n. we are defin ng a connect on str ng. and cop ed to the output d rectory Unfortunate y. wh ch connects to an Access database fi e by us ng the System.exe.eve configurat on sett ngs The configurat on fi e can a so be used to store configurat on nformat on such as connect on str ngs and error messages You can add a configurat on fi e to a project and ed t t to add the appropr ate sett ngs When the project s bu t.Data Source=C:\path\to\blog. the configurat on fi e needs to be renamed to nc ude the executab e name.Jet.config extens on. dent fied by the name Blog. Ed t the app config fi e to add a connect on str ng <?xml version="1. c ck Bu d Events And Post-Bu d Event Ed t the Command entry to read as fo ows copy app. the command w fa to execute 4. however. config The app cat on configurat on fi e conta ns sett ngs spec fic to an app cat on These sett ngs m ght overr de or add to computer.exe wou d have a configurat on fi e ca ed MyApp.config "$(TargetPath).4.OleDb" /> </connectionStrings> </configuration> Remember to ed t the path to the ocat on where you stored the b og mdb database fi e The connectionStrings sect on ho ds connect on str ng nformat on The clear e ement c ears out the co ect on n case any have been nher ted from computer configurat on sett ngs In th s examp e. n the co umn on the eft. toward the end of the bu d Note the doub e quotes around the dest nat on They are needed f the path to the executab e conta ns spaces.Application configuration files An app cat on can have an XML configurat on fi e whose name cons sts of the name of the app cat on w th a .0" encoding="utf-8" ?> <configuration> <connectionStrings> <clear/> <add name="Blog" connectionString= "Provider=Microsoft. add th s as a custom bu d step to your project Open the Project Propert es d a og box and choose Configurat on Propert es Then.Data. V sua Stud o 2012 does not perform th s copy ng and renam ng automat ca y when bu d ng a C++ project You can.config" When you next bu d your project you shou d see the message “1 fi e(s) cop ed” d sp ayed n the Output pane.0. an app cat on ca ed MyApp.OLEDB.Data.mdb" providerName="System.

7. if (settings == nullptr) { Console::WriteLine("Couldn't get settings"). } Console::WriteLine("Have settings"). return -1. Console::WriteLine("Connection opened").dll Do th s by fo ow ng the nstruct ons g ven n the s debar “Referenc ng externa assemb es” ear er n the chapter 6. } Chapter 18  Us ng ADO. After you have the factory. you can use ts ProviderName property to get a DbProviderFactory // Get the factory object for this provider type DbProviderFactory ^fac = DbProviderFactories::GetFactory(settings->ProviderName). retr eve the connect on str ng sett ngs from the config fi e ConnectionStringSettings ^settings = ConfigurationManager::ConnectionStrings["Blog"]. t ma nta ns a co ect on of ConnectionStringSettings objects. regard ess of the actua prov der be ng used underneath 9. The ConfigurationManager c ass s respons b e for nteract ng w th sett ngs stored n configurat on fi es. try { // Create a connection and set its connection string conn = fac->CreateConnection(). you need to add a reference to System.5. and as such.Configuration. Add a using namespace d rect ve for System. conn->ConnectionString = settings->ConnectionString.} catch (Exception ^ex) { Console::WriteLine(ex->Message). and so on You use DbProviderFactory the same way. commands. there sn’t an entry w th that name n the config fi e 8. use t to create a connect on and open t DbConnection ^conn = nullptr. The DbProviderFactory s a factory that creates the var ous other objects that we need— connect ons. At the top of the main funct on. } finally { if (conn != nullptr) conn->Close(). Console::WriteLine("Connection closed"). wh ch you can access by us ng an ndexer If the ca returns nu . After you have the ConnectionStringSettings object.Configuration using namespace System::Configuration. To work w th configurat on fi es. conn->Open().NET   339 .

you w create a DbCommand object that represents the fo ow ng SQL statement SELECT COUNT(*) FROM Entries Th s statement returns an nteger nd cat ng how many rows are n the Entries tab e You w ecute th s statement by us ng the ExecuteScalar method on the command object ex- 1. on the conso e. cmd->Connection = conn. after the statement that opens the database connect on // Count the entries DbCommand ^cmd = fac->CreateCommand(). you see the message shown n the figure that fo ows Creating and executing a command In th s exerc se. Run the app cat on If a s we . In the main funct on. so you shou d a ways enc ose your database code n a try b ock Connect ons need to be opened before they are used. as opposed to a stored procedure The Connection property spec fies wh ch database connect on to use when execut ng the command 340  Microsoft Visual C++/CLI Step by Step . wh ch ensures that the connect on s c osed whether or not an except on occurs 10. add the fo ow ng code to the try b ock. Th s code creates and configures a DbCommand object that encapsu ates a SQL statement The CommandText property defines the SQL to be executed. and CommandType says that th s s a SQL command.Just about everyth ng you do w th databases can generate an except on. Bu d your app cat on and fix any comp er errors 11. cmd->CommandText = "SELECT COUNT(*) FROM Entries". cmd->CommandType = CommandType::Text. Cont nue w th the project from the prev ous exerc se 2. and t s mportant to c ose them afterward so that you free up resources The best way to do th s s to use a finally b ock.

4. [Text]. F nd the code you wrote n the prev ous exerc se and add the fo ow ng statement // Update the prices of products cmd->CommandText = "INSERT INTO [Entries] ([Date].3. [Author]) VALUES ('Dec 02. You w use the ExecuteNonQuery method to execute th s statement. 'Julian')". 'A blog entry'. Run the app cat on The message shown n the fo ow ng figure shou d appear on the conso e Executing a command that modifies data In th s exerc se. [Text]. Bu d your app cat on and fix any comp er errors 5. [Author])" " VALUES ('Dec 02. 2012'. numberOfEntries). Console::WriteLine("Number of entries: {0}". 2012'. you w add a new entry nto the database by us ng the fo ow ng SQL statement INSERT INTO [Entries] ([Date]. 'Some text'. 'Julian') Note  Some fields in the SQL are surrounded with square brackets in case they have the same name as predefined entities or types within Access. Add the fo ow ng code to execute the SQL statement and d sp ay the resu ts on the conso e // Print the result int numberOfEntries = (int)cmd->ExecuteScalar().NET   341 . wh ch w return an nteger to nd cate how many rows the statement affected Because you are nsert ng a s ng e row. Chapter 18  Us ng ADO. you’d expect th s va ue to be 1 1. Cont nue w th the project from the prev ous exerc se 2.

wh ch s a fast. Cont nue w th the project from the prev ous exerc se 2. you w execute a command that retr eves nformat on from the database by us ng the fo ow ng SQL statement SELECT * FROM Entries You w use the ExecuteReader method to execute th s statement Th s w return a DbDataReader object. Add the fo ow ng code to execute the SQL statement and d sp ay the resu ts on the conso e int rowsAffected = cmd->ExecuteNonQuery().Th s code reuses the DbCommand object from the prev ous exerc se but spec fies a d fferent SQL statement Tip  It is a little-known feature of C++ that if the preprocessor sees two string literals on adjoining lines. Console::WriteLine("Added {0} rows". 4. F nd the code you wrote n the prev ous exerc se and add the fo ow ng statement // Query the database cmd->CommandText = "SELECT * FROM Entries". it will combine them. This is a useful way to split up and format long strings. 3. rowsAffected). forward-on y reader that reads through each row n the resu t set n turn 1. Bu d your app cat on and fix any comp er errors 5. Run the app cat on The message shown n the fo ow ng figure shou d appear on the conso e Executing queries and processing the results In the fina part of th s connected app cat on exerc se. 342  Microsoft Visual C++/CLI Step by Step .

6. Console::WriteLine(" {0}". Add the fo ow ng code to execute the SQL statement and return a DbDataReader object DbDataReader ^reader = cmd->ExecuteReader(). output the va ues of a four co umns The first. After the oop. but the other three (Date. s an nteger. } Console::WriteLine("--------------------------------------"). reader->GetString(2)). Add the code that fo ows to oop through the resu ts one row at a t me For each row. Text and Author) are a str ngs Console::WriteLine("\n------------------------------------"). Run the app cat on The message shown n the fo ow ng figure shou d appear on the conso e (You m ght get d fferent va ues than what’s shown here ) Chapter 18  Us ng ADO.Th s code reuses the DbCommand object from the prev ous exerc se but spec fies a d fferent SQL statement 3. reader->GetString(1). reader->GetInt32(0). the record ID. c ose the reader reader->Close().NET   343 . reader->GetString(3)). while (reader->Read()) { Console::WriteLine("{0}: {1} by {2}". 4. The Read method steps through the record set one row at a t me Not ce the use of the strong y typed methods GetString and GetInt32 5.

but as you’d expect. however. you work w th the prov der. sett ng up a schema us ng Data Columns. and so on The DataRow objects actua y conta n the data for the DataSet You can create a DataSet from scratch. wh ch s ts between the database and the DataSet The adapter knows how to retr eve data from the database and how to nsert and update data Each prov der has ts own data adapter c ass. much more common to use a DataSet w th a database The key to do ng th s s the data adapter. creat ng DataTables. such as ts name. oca data store The fo ow ng figure shows the DataSet object mode A DataSet s an n-memory co ect on of DataTable objects and the re at onsh ps between them You can create many DataTables n a DataSet to ho d the resu ts of more than one SQL query Each DataTable has a co ect on of DataRows and DataColumns Each DataColumn conta ns metadata about a co umn. data type. defau t va ue. the DataSet c ass represents a d sconnected. we’ turn our attent on to d sconnected app cat ons A d sconnected app cat on s one that does not have a permanent y ava ab e connect on to the data source App cat ons are much more sca ab e when they on y need a database connect on to retr eve or send data back.ndependent DbDataAdapter type 344  Microsoft Visual C++/CLI Step by Step . and then add ng DataRows It s. and t s poss b e for an app cat on such as a webs te to support many users w th on y a handfu of database connect ons In ADO NET.Creating a disconnected application For the rest of the chapter.

each of wh ch encapsu ates a SQL command The fo ow ng tab e descr bes these command objects Command object in a data adapter Description SelectCommand Conta ns a SQL SELECT statement to retr eve data from the database nto the DataSet tab e InsertCommand Conta ns a SQL NSERT statement to nsert new rows from the DataSet tab e nto the database UpdateCommand Conta ns a SQL UPDATE statement to mod fy ex st ng rows n the database DeleteCommand Conta ns a SQL DELETE statement to de ete rows from the database Disconnected operation using a DataSet Th s exerc se shows you how to create a DataSet. one each for the se ect. Start a new CLR Conso e project project named DataSetApp 2. and extract data from the tab es n the DataSet The deta s of sett ng up the configurat on and gett ng a connect on are exact y the same as for the prev ous exerc se. and update operat ons.NET   345 .The fo ow ng figure shows how data adapters work w th DataSets Each data adapter works w th a s ng e DataTable n a DataSet You ca the Fill method on a data adapter to fi the DataSet w th data from the database You ca the Update method on a data adapter to save any changes n the DataSet back to the database Interna y. Add an externa reference to the System::Configuration assemb y by us ng the Propert es d a- og box. de ete. as deta ed n the s debar “Referenc ng externa assemb es” ear er n the chapter Chapter 18  Us ng ADO. nsert. fi t by us ng a DataAdapter. the data adapter has four command objects. so you w be ab e reuse a ot of the code 1.

using namespace System::Data::Common. and then c ck Ut ty In the center pane. // Get the factory object for this provider type DbProviderFactory ^fac = DbProviderFactories::GetFactory(settings->ProviderName). return -1. 4. Copy the code to read the connect on str ng sett ngs and create the DbProviderFactory (The code s g ven here. Remember to add the post-bu d step to the project sett ngs so that app config w be renamed to match the executab e name You can find deta s on how to do th s n the prev ous exerc se 6. // For reading the configuration data using namespace System::Configuration.4. Add using statements to the top of the source fi e for the assemb es that you are go ng to be us ng // ADO.NET namespaces using namespace System::Data. if (settings == nullptr) { Console::WriteLine("Couldn't get settings").0" encoding="utf-8" ?> <configuration> <connectionStrings> <clear/> <add name="Blog" connectionString= "Provider=Microsoft. c ck V sua C++. } Console::WriteLine("Connection settings OK").mdb" providerName="System. but t s exact y the same as for the prev ous exerc se ) // Get the connection settings ConnectionStringSettings ^settings = ConfigurationManager::ConnectionStrings["Blog"].Data. po nt to Add. Add an app cat on configurat on fi e to the project In So ut on Exp orer. // For printing the content of the DataSet using namespace System::IO. 346  Microsoft Visual C++/CLI Step by Step .Jet.Data Source=C:\path\to\blog. and then c ck New Item In the New Item d a og box that opens. “Creat ng a connected ap- p cat on ” Here s the content that you need <?xml version="1. n the pane on the eft. r ght-c ck the project name On the shortcut menu that appears.0.OLEDB.OleDb" /> </connectionStrings> </configuration> Remember to ed t the path to reflect wherever you have stored the b og mdb fi e 7.3. Copy the content of the app config fi e from the prev ous exerc se. c ck Configurat on fi e (app config) 5.

fi s t w th the resu t of the query. adapter->SelectCommand = cmd.NET   347 . Console::WriteLine("Connection opened"). W th that setup comp ete. You can now create a DataSet and ask the adapter to fi t DataSet ^dataset = gcnew DataSet("Blog"). try { // Create a connection and set its connection string conn = fac->CreateConnection(). you can beg n retr ev ng data Start by ask ng the factory to create a DataAdapter // Create a DataAdapter and set its select command DbDataAdapter ^adapter = fac->CreateDataAdapter(). but you shou d be ab e to copy t from the prev ous exerc se ) DbConnection ^conn = nullptr. adapter->Fill(dataset. 11.8. but because you are on y go ng to be retr ev ng data. I have reproduced the code here. Console::WriteLine("Connection closed"). wh ch creates a DataTable ca ed “Entr es”. The first ne creates an empty DataSet ca ed “B og” Ca ng Fill on the adapter causes t to execute ts SelectCommand. you on y need to set the Select command Do th s by creat ng a DbCommand object. conn->Open(). and a finally b ock to c ose the connect on (Aga n. A DataAdapter can have four commands assoc ated w th t. a catch b ock to hand e any errors. cmd->Connection = conn. and then adds t to the DataSet’s co ect on of DataTables Chapter 18  Us ng ADO. } finally { if (conn != nullptr) { conn->Close(). cmd->CommandText = "SELECT * FROM Entries". as n the prev ous exerc se. Add a try b ock n wh ch you create a connect on. 10. "Entries"). } catch (Exception ^ex) { Console::WriteLine(ex->Message). conn->ConnectionString = settings->ConnectionString. and then ass gn ng t to the SelectCommand property of the adapter DbCommand ^cmd = fac->CreateCommand(). cmd->CommandType = CommandType::Text. } } 9.

or use the fu name System::Xml::XmlTextWriter Note  The null second argument to the constructor means that the default UTF-8 encoding will be used. t s very use- Note  In a larger application.xml". but as you w fu when bu d ng XML documents from DataSet data see short y. xwriter->Close(). t wou d be usefu to ook at what t conta ns The WriteXml funct on wr tes the content of a DataSet n XML format to any stream The XmlTextWriter c ass prov des a usefu stream for our purposes because t wr tes the output to a fi e n proper y formatted form XmlTextWriter ^xwriter = gcnew XmlTextWriter("c:\\SbS\\dataset. If you want to use another encoding. XmlWriteMode::IgnoreSchema). nullptr). so you will need to add a using declaration if you don’t want to use the fully qualified name. 13.xml". table->WriteXml(xwriter. 12. Now that you have a DataSet.G v ng names to DataSets and DataTables s opt ona . 2009</Date> 348  Microsoft Visual C++/CLI Step by Step . you shou d see that the first few nes ook ke th s <Blog> <Entries> <ID>2</ID> <Date>Jul 01. Use the tab e’s WriteXml method to wr te the data out to the fi e DataTable ^table = dataset->Tables[0]. xwriter->Formatting = Formatting::Indented. Encoding::Unicode). The first two nes create an XmlTextWriter and ensure that t wr tes out the XML w th ndentat on Ed t the path to put the XML fi e n a su tab e ocat on Remember that you need to add a using namespace statement for System::Xml. specify it like this: XmlTextWriter ^xwriter = gcnew XmlTextWriter("c:\\SbS\\dataset. you cou d a so spec fy the name here rather than the ord na The second argument to WriteXml shows that you on y want the data and not the schema 14. The dec arat on of the DataTable hand e makes the fo ow ng code s mp er and shows how the tab e created by the adapter s the first one n the DataSet’s Tables co ect on Because you gave the tab e a name when the adapter created t. Bu d and run the app cat on and then open the XML fi e n Notepad. The Encoding class is in the System::Text namespace. you could now close the connection to the database because you have the data locally in the DataSet.

Chapter 18  Us ng ADO.w3. Change the WriteXml statement so that t nc udes the schema n the generated data table->WriteXml(xwriter.. Bu d and run the app cat on aga n. 2009</Date> <Text>A first entry</Text> <Author>Julian</Author> </Entries> ..<Text>A first entry</Text> <Author>Julian</Author> </Entries> <Entries> <ID>3</ID> <Date>Jun 27. XmlWriteMode::WriteSchema).. The root e ement has the same name as the DataSet. you shou d see that the output fi e conta ns an XML schema that descr bes the data <Blog> <xs:schema id="Blog" xmlns="" xmlns:xs="http://www. the root e ement wou d have been ca ed “NewDataSet” and each row wou d have been ca ed “Tab e” 15. 2009</Date> <Text>Second entry</Text> <Author>Julian</Author> </Entries> . and each row s named after the tab e If you hadn’t ass gned names to the DataSet and DataTable..org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xs:element name="Blog" msdata:IsDataSet="true" msdata:MainDataTable="Entries" msdata:UseCurrentLocale="true"> <xs:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="Entries"> <xs:complexType> <xs:sequence> <xs:element name="ID" type="xs:int" minOccurs="0" /> <xs:element name="Date" type="xs:string" minOccurs="0" /> <xs:element name="Text" type="xs:string" minOccurs="0" /> <xs:element name="Author" type="xs:string" minOccurs="0" /> </xs:sequence> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> </xs:element> </xs:schema> <Entries> <ID>2</ID> <Date>Jul 01.NET   349 .

using namespace System::Data::Common. DataSet^ ds = gcnew DataSet("Titles"). and Connection propert es. conn->ConnectionString = connString.Jet.0" encoding="utf-8" ?> <configuration> <connectionStrings> <add name="NWind" connectionString= "Provider=Microsoft. 350  Microsoft Visual C++/CLI Step by Step .config fi e. ca ExecuteScalar. you w need to add on y a us ng d rect ve for the appropr ate assemb es. f the command performs a query. For examp e: using namespace System::Data. and then set ts connect on. Add an app cat on configurat on fi e to the project. Create a DataSet and fi the DataSet by us ng the data adapter.0. For examp e: DbDataReader ^reader = cmd->ExecuteReader(). f the command mod fies the database. ca ExecuteReader. add DbCommands to access the database. daTitles->Connection = conn. Obta n the prov der factory by us ng the prov der name. For examp e: DbConnection ^conn = factory->CreateConnection(). Create a DbCommand object and configure ts CommandText. and add a post bu d event to rename t: copy app. daTitles->Fill(ds).Quick reference To Do this Use ADO. } Use data n a d sconnected app cat on. add one or more connect on str ng sect ons to the .NET c asses. For examp e: <?xml version="1. Execute a command.4." "Data Source=C:\SbS\Blog.config $(TargetPath).mdb" providerName="System. Store connect on str ngs n the app cat on configurat on fi e. Create a DbDataAdapter. daTitles->SelectCommand = cmd. ca Execute NonQuery. CommandType. Then create a DbConnection object.OLEDB. while (reader->Read()) { Console::Write(reader->GetString(0)).Data.config Then. f the command returns a sca ar va ue.OleDb" /> </connectionStrings> </configuration> Connect to a database. Ass gn the resu t to a DbDataReader object and use th s reader to oop through the resu t set. For examp e: DbProvideFactory ^factory = DbProviderFactories::GetFactory(name). For examp e: DbDataAdapter ^daTitles = factory->CreateDataAdapter(). Create a SQL command. f you are us ng V sua Stud o 2012. and configure ts ConnectionString property.

you have n effect created a d str buted app cat on Your browser prov des the user nterface. published by Microsoft Press. the web server prov des the m dd e t er. you w be ab e to ■ Descr be what W ndows Commun cat on Foundat on s ■ Wr te serv ces by us ng W ndows Commun cat on Foundat on ■ Wr te c ents to use W ndows Commun cat on Foundat on serv ces What is Windows Communication Foundation? W ndows Commun cat on Foundat on (WCF) s M crosoft’s p atform for wr t ng d str buted. and this chapter can only provide an introduction. and that server n turn m ght be us ng other servers to prov de t w th resources When you do th s. serv cebased app cat ons Prev ous y known as Ind go.CHAPTER 19 Writing a service by using Windows Communication Foundation After comp et ng th s chapter. and there can be other back-end servers prov d ng the data t er One very mportant feature of systems ke th s s that you can connect comp ete y separate p eces together at run t me to get the funct ona ty that you want 351 . If you want to read more. t prov des a framework for wr t ng serv ces and c ents More Info  WCF is a very complex topic. your browser connects across the Internet to a server. I would suggest Windows Communication Foundation 4 Step by Step by John Sharp. We ve n an ncreas ng y connected and d str buted wor d When you v s t a webs te.

you can define contracts that spec fy. the wor d has moved toward a need for more connect v ty and ndependence. n a anguage and p atform. such as TCP/IP and HTTP. and so serv ce-based systems have become ncreas ng y popu ar Services One of the ha marks of modern serv ce-based systems s the ab ty to compose parts together that have been deve oped ndependent y Th s s done through the use of standards rather than propr etary techno og es So. and these define the nterface of your component to the outs de wor d The mp ementat on deta s are mmater a to the user Distributed systems Ear y frameworks for d str but on tended to be propr etary M crosoft’s D str buted Component Object Mode (DCOM) was ntended to connect components wr tten by us ng M crosoft techno og es runn ng on W ndows Java’s Remote Method Invocat on (RMI) was ntended to do the same th ng n the Java wor d A though these are st n use. not the deta s of the r mp ementat on W th WCF. and run on d fferent operat ng systems A that s mportant s the funct ona ty that they prov de. we can use XML and HTTP to connect two components rather than RMI. and data representat ons.These p eces m ght be wr tten by us ng d fferent anguages and frameworks.ndependent manner. wh ch was des gned to work between Java components You w see short y how WCF supports a w de range of the most popu ar and w de y used standards. what serv ces your components can prov de. mak ng t poss b e for you to create any type of serv ce that you m ght need Characteristics of services Serv ces have the fo ow ng d st ngu sh ng character st cs ■ ■ ■ Platform and language independence  Serv ces are wr tten n such a way that they are not dependent on c ents us ng a part cu ar anguage or framework to access them Independent and autonomous  Serv ces are ndependent n the same way that a webs te s ndependent Use well-known standards  Serv ces make use of standard protoco s. such as XML Do ng th s decoup es c ents of the serv ce from the mp ementat on 352  Microsoft Visual C++/CLI Step by Step . for examp e.

however. when proper y des gned they can be comb ned nto new d str buted app cat ons Connectivity A component that you want to nteract w th cou d res de n another process on the same computer. you cou d use TCP/IP for b nary commun cat on or HTTP for text commun cat on In the enterpr se wor d. us ng d fferent brar es and techn ques A deve oper exper enced n us ng TCP wou d have to earn how to use messag ng WCF s mp fies th s by ett ng deve opers nd cate how they want the r components to be connected and eav ng t up to the framework to mp ement the connect on For examp e.■ ■ Discoverability  Many serv ces pub sh metadata so that potent a c ents can d scover what they offer and how to access them Reusability  Because serv ces are ndependent. and WCF w generate a the requ red code and configurat on The ABCs of WCF WCF conta ns a ot of deta —a ot of mov ng parts—and t s very easy to ose s ght of what s mportant n a mass of deta There s. on another computer on your oca network. whereas for components dep oyed on other computers. you wou d use an nter-process commun cat on (IPC) mechan sm such as named pipes. you can use an attr bute to say that a c ass shou d be exposed as a web serv ce us ng HTTP. and apprec ate other features of WCF that you m ght want to use n future projects Endpoints A serv ce n WCF s ca ed an endpoint Endpo nts are character zed by three facets ■ Address  Where to find the serv ce ■ Binding  How to ta k to the serv ce ■ Contract  What the serv ce can do Chapter 19  Wr t ng a serv ce by us ng W ndows Commun cat on Foundat on   353 . or out on the Internet You have severa opt ons for connect ng to such components For components that res de on the same computer. and so n th s sect on I present enough deta s on how WCF works and what t does that you w be ab e to wr te and consume a s mp e serv ce. t s a so common to use messag ng systems such as M crosoft MSMQ or IBM MQ to connect components ocated on d fferent dev ces The prob em here s that each of these commun cat on mechan sms s mp emented n a d fferent way. a certa n number of th ngs that you need to know to work w th WCF.

.

.

356  Microsoft Visual C++/CLI Step by Step . but f you want to use a Person type as an operat on parameter or return type.n types. that you wanted to expose a funct on ke the fo ow ng as an operat on Person^ GetPersonById(int id). wh ch makes them ava ab e to c ents Any funct on that sn’t marked w th OperationContract w not be exposed to c ents The operat on SomeFunction on y uses bu t. WCF w need to know what a Person object conta ns Fault contracts  A fau t contract s used to define error behav or You use contracts dec arat ve y. This can involve converting it to an intermediate form for transmission over a network. The nterface s annotated w th the ServiceContract attr bute.Contract Contracts define what a serv ce can do. by add ng attr butes to code Here s a s mp e examp e of a serv ce contract [ServiceContract] interface class Foo { [OperationContract] int SomeFunction(double d). Note  Marshaling is the process of converting data and sending it to another component. and it can result in the receiver getting a different representation than that of the sender. and WCF knows how to marsha those Suppose. }. and contract deta s are expressed n metadata for c ents to use WCF supports four k nds of contracts ■ ■ ■ ■ Service contracts  A serv ce contract exposes a NET c ass or nterface as a serv ce Operation contracts  An operat on contract exposes a method on a type as a serv ce (You can on y make methods nto operat ons. wh ch nforms WCF that you are defin ng a set of operat ons Ind v dua funct ons w th n the nterface are marked w th Operation Contract. such as numbers and str ngs. not propert es) Data contracts  A data contract s used to nstruct WCF how to use custom types n serv ce ca s WCF knows about a range of bas c types. though.

5. cons der th s operat on Person^ GetPersonById(int id). don’t annotate t. The DataContract c ass defines th s as be ng a ser a zab e c ass. and s typ ca y used when the c ent expects a rep y from the serv ce For examp e. as demonstrated n the fo ow ng ustrat on Chapter 19  Wr t ng a serv ce by us ng W ndows Commun cat on Foundat on   357 .In th s case. and you cou d do th s by us ng a DataContract [DataContract] ref class Person { [DataMember] String ^name. The c ent ca s the serv ce w th an ID and expects to get a Person back Us ng request-response messag ng. you often don’t have to annotate your types with DataContract and DataMember. th s w cut down the amount of data be ng sent over the w re Note  As of . and you app y DataMember to a fie ds that you want to be ser a zed If you don’t want or need to send a fie d. Message exchange patterns Commun cat on between c ents and serv ces can be one-way or b -d rect ona WCF supports three message exchange patterns (MEPs) that govern how c ents commun cate w th serv ces ■ Request-response ■ One-way (a so ca ed simplex) ■ Dup ex (a so ca ed bi-directional) Request-response s the defau t.NET 3. making explicit those members that you want passed to clients. … }. But it might be wise to still use it. the c ent w b ock (and the connect on w be ma nta ned) unt e ther the response has been rece ved or a fau t has been sent Th s means that request-response message s synchronous. because public members will be made available by default. you wou d have to nstruct WCF how to marsha objects of type Person.

.

Examp es of behav ors nc ude ■ How serv ce objects are created Is there just one or s there a new object created per ca ? ■ How the serv ce hand es concurrent ca s ■ L m t ng the number of s mu taneous connect ons ■ Hand ng transact ons A deta ed descr pt on of behav ors and how to use them s beyond the scope of th s book Creating a service In th s exerc se. and use t to define the fo ow ng nterface #ifndef IMATHSERVICE_H #define IMATHSERVICE_H [ServiceContract] public interface class IMathService { [OperationContract] virtual double Square(double d). the serv ce w be defined as an nterface. you w see how to create and test a s mp e serv ce that prov des mathemat ca operat ons To fo ow best pract ces. 3. [OperationContract] virtual double Cube(double d).h to the project. #endif Th s dec ares a serv ce as an nterface It s good pract ce to define serv ces us ng an nterface because th s decoup es the mp ementat on from the defin t on Th s s be ng dec ared n a separate header fi e because the c ent w need the nterface defin t on. }. Add an externa reference to System::ServiceModel and then add the fo ow ng two using dec arat ons using namespace System::ServiceModel. as we Chapter 19  Wr t ng a serv ce by us ng W ndows Commun cat on Foundat on   359 . Add a header fi e named IMathService. w th the mp ementat on n a separate c ass 1. Create a CLR Conso e App cat on project named MathService 2. using namespace System::ServiceModel::Channels.

you can end up w th mu t p e nc us ons Suppose that you’ve wr tten A h to nc ude B h and C h. n comp ex code. } }. } virtual double Cube(double d) { return d*d*d.Include files and the preprocessor You m ght not have encountered th s use of the preprocessor before One of the prob ems w th nc ude fi es s that. You can now start to mp ement the main method to host the serv ce int main(array<System::String ^> ^args) { WSHttpBinding ^binding = gcnew WSHttpBinding(). Uri ^baseAddress = gcnew Uri("http://localhost:8080/MathService"). 5. and th s means that f another attempt s made to nc ude the same fi e w th n th s comp at on. such as the one defined n the prev ous examp e The first ne says that f the preprocessor symbo IMATHSERVICE H s not defined. and t can be a hass e to sort out The recommended way around t s to use an include guard. you create a WSHttpBinding and an HTTP address 360  Microsoft Visual C++/CLI Step by Step . and you’ probab y get errors due to mu t p e defin t ons Th s usua y happens deep y nested n a tree of nc ude fi es. } These first two nes create a b nd ng and a base address for the serv ce Because th s s a bas c HTTP serv ce. but t s common to base t on the name of the nc ude fi e to avo d any poss b e dup cat on. nc ude the contents of the fi e up unt the #endif The second ne then defines the symbo .h" ref class MathService : IMathService { public: virtual double Square(double d) { return d*d. the first #ifndef w fa and the code won’t be nc uded You can make the symbo just about anyth ng you ke. and that both of those nc ude D h That fi e w be nc uded tw ce. and t s convent on to define symbo s n cap ta s 4. Open the MathServ ce cpp fi e and add the defin t on for a c ass that mp ements the serv ce You’ need to add an include statement to get the nterface defin t on #include "IMathService.

6. host->AddServiceEndpoint(IMathService::typeid. c ck Run As Adm n strator Writing a service client The next step s obv ous y to wr te a c ent to test out the serv ce There s a WCF Test C ent nc uded w th V sua Stud o. Create a ServiceHost object and add an endpo nt to t ServiceHost ^host = gcnew ServiceHost(MathService::typeid. on the appbar menu that s des up from the bottom of the screen. baseAddress). so you need to run the app cat on w th suffic ent pr v ege There are two ways to do th s one s to reg ster the serv ce by us ng the netsh command so that W ndows w a ow t to run. because adm n strators have r ghts to run serv ces To do that. you shou d find that t crashes w th an except on of type System::ServiceModel::AddressAccessDeniedException Th s s because W ndows wants to prevent poss b y ma c ous code runn ng w thout author zat on. Console::ReadLine(). the other s to run the app cat on as an adm n strator.. baseAddress). and we w eave that unt ater n the chapter 1. you can e ther start a command prompt as adm n strator and run the app cat on from the command ne or run V sua Stud o as adm n strator and run the app cat on from there To run app cat ons as adm n strator n W ndows 8. The ca to Open starts the serv ce sten ng for connect ons But th s s not a b ock ng ca .. r ght-c ck the app cat on’s t e on the Start screen and then. ensure that you c ose the host to free resources 8. Console::WriteLine("Service running. Create another CLR Conso e App cat on named TestClient Chapter 19  Wr t ng a serv ce by us ng W ndows Commun cat on Foundat on   361 . Run the serv ce host->Open(). Bu d the app cat on and run t to check that you have no errors When you try to run the app cat on. so you need to keep the app cat on runn ng unt you’re ready to c ose the connect on An easy way to do th s s s mp y to output a prompt and wa t for the user to press Enter When the user does press Enter. The ServiceHost s the object that mp ements the WCF behav or for you It s n t a zed w th deta s of the serv ce mp ementat on c ass (so that t knows what to ca when requests come n) and the base address You can then add an endpo nt to the ServiceHost so that t knows to support the WSHttpBinding on the g ven base address and that t s support ng the IMathService contract 7. but you won’t be ab e to use that unt you’ve added metadata support to the serv ce. host->Close(). binding. press Enter to terminate").

String ^url = "http://localhost:8080/MathService". Add the two using d rect ves for the System::ServiceModel and System::ServiceModel::Channels namespaces using namespace System::ServiceModel. Ca an operat on on the serv ce double value = channel->Square(3. po nt to Add. po nt to Ex st ng Item.2. 5.0). IMathService ^channel = factory->CreateChannel(). Add an #include statement for IMathServ ce h to the source fi e TestC ent cpp 6. using namespace System::ServiceModel::Channels. Add an externa reference to the System::ServiceModel assemb y. Run the MathService executab e that you created n the prev ous exerc se. Note how the channe mp ements the nterface of the serv ce you want to ca . address). and then c ck the header fi e You need to add th s fi e because your c ent code needs the defin t on of the nterface 3. You need to cast the channe to an IChannel hand e because the IMathService doesn’t mp ement the Close funct on 10. and a so has a b nd ng and address It therefore has a the deta s t needs to contact the serv ce and use the operat ons t prov des 8. copy the IMathServ ce h fi e to the project d rectory and add t to the project R ght-c ck the project name On the shortcut menu. Bu d the app cat on to ensure that you have no errors 11. In W ndows Exp orer. and you get one of those from a ChannelFactory ChannelFactory<IMathService^> ^factory = gcnew ChannelFactory<IMathService^>(binding. c ose the channe ((IChannel^)channel)->Close(). Console::WriteLine("Value is {0}". wh ch you’ find ocated n the Debug d rectory of the project When th s has started. Commun cat on s hand ed by a Channel. Start mp ement ng the main funct on by creat ng a WSHttpBinding and EndPointAddress WSHttpBinding ^binding = gcnew WSHttpBinding(). value). EndpointAddress ^address = gcnew EndpointAddress(url). just ke you d d when creat- ng the serv ce 4. When you’re done. run the c ent as adm n strator and you shou d see the resu t message pr nted out 362  Microsoft Visual C++/CLI Step by Step . 9. 7.

and you can configure how t exposes th s data In th s case.asp. but if you are interested. Ear er n the chapter. you can choose wh ch transports (HTTP. but your serv ce needs to pub sh metadata through an MEX endpo nt before you can use th s Th s next exerc se adds an MEX endpo nt to the serv ce It then shows how you can see the metadata and then use the WCF Test C ent to exerc se the serv ce 1. TCP) that you want to support. Add the fo ow ng nes after the ca to AddServiceEndpoint and before the ca to Open // Add MEX endpoint ServiceMetadataBehavior ^mex = gcnew ServiceMetadataBehavior(). wh ch descr bes the serv ce n XML More Info  It isn’t important for you to understand WSDL to create and use services. mex->HttpGetEnabled = true. you earned that behav ors are used to mod fy the behav or of a serv ce The ServiceMetadata behav or makes t poss b e for the serv ce to expose ts metadata v a an MEX endpo nt. 3.com/wsdl/wsdl intro. The next quest on s how you ask a serv ce for ts metadata WCF serv ces expose the r metadata through an MEX endpo nt When you add such an endpo nt. you can learn more about it at the w3schools website at http://www. host->Description->Behaviors->Add(mex). "http://localhost:8080/MathService/mex"). Add a using d rect ve for System::ServiceModel::Description to MathServ ce cpp using namespace System::ServiceModel::Description. w3schools. what t can do and how to ca t The standard way to prov de th s metadata s as a WSDL document. and then you add a serv ce endpo nt The endpo nt exposes the IMetadataExchange contract at the URL by us ng HTTP at the g ven address Note how the standard MEX endpo nt address s the serv ce address w th /mex appended Chapter 19  Wr t ng a serv ce by us ng W ndows Commun cat on Foundat on   363 .Adding metadata to the service One of the character st cs of serv ces s that they are d scoverab e Th s means that there s some way for potent a c ents to get deta s of the serv ce. I’ve chosen to a ow c ents to access t v a an HTTP GET request The behav or object s added to the host’s Behaviors co ect on. Cont nue w th the project from the prev ous exerc se 2. host->AddServiceEndpoint( IMetadataExchange::typeid. and prov de the URL You can use the WCF Test C ent to exam ne and ca serv ce operat ons. MetadataExchangeBindings::CreateMexHttpBinding().

on the shortcut menu that appears. t w be n C \Program F es (x86)\M crosoft V sua Stud o 11 0\Common7\IDE) 6. c ck Add Serv ce 7. r ght-c ck the MyServ ce Projects entry.4. WcfTestC ent exe. Start Internet Exp orer and type the fo ow ng URL n the address bar http://localhost:8080/MathService?wsdl By sett ng the HttpGetEnabled property. wh ch you can find n C \Program F es\M crosoft V sua Stud o 11\Common7\IDE (or f you are runn ng a 64-b t vers on of W ndows. enter the serv ce URL (http://localhost:8080/ MathService) nto the text box and press OK After a short nterva . you shou d see deta s of the serv ce contract appear n the pane on the eft n the WTF Test C ent app cat on w ndow 364  Microsoft Visual C++/CLI Step by Step . you shou d see the fo ow ng WSDL descr bng your serv ce n the browser You can now run the WCF Test C ent. you can request the metadata us ng HTTP by pass ng the wsdl parameter When the request executes. and then. When the app cat on starts. n the pane on the eft s de of the w ndow. Bu d the project and then start the serv ce as adm n strator 5. In the Add Serv ce d a og box that opens.

you don’t have to wr te a s ng e ne of C# n order to make t work Chapter 19  Wr t ng a serv ce by us ng W ndows Commun cat on Foundat on   365 . ask ng V sua Stud o to add a serv ce reference to your project. you shou d see the response appear n the ower part of the pane.8. n th s way. as shown n the fo ow ng figure Accessing a service by using a proxy You have seen how to connect to a serv ce manua y by us ng the WCF APIs It s a so poss b e to get V sua Stud o to create a proxy c ass for you. you don’t have to be concerned w th the ow. but t turns out to be qu te s mp e to do f you use a C# wrapper Creating the wrapper DLL In th s next exerc se. one that encapsu ates the deta s of where the serv ce s and what the endpo nts are. Doub e-c ck one of the operat ons—for examp e. Square The pane on the r ght s de shows you deta s of how to ca the operat on Enter a number n the Value fie d and press Invoke After a short pause. you w be ab e to use t from C++/CLI code And even though you create a C# project. and then us ng the generated proxy c ass The prob em s that th s feature sn’t supported by C++/CLI n V sua Stud o. you w create a s mp e C# Dynam c-L nk L brary (DLL) project and add a reference to the MathServ ce project Th s w add a proxy c ass to the project.eve mechan cs Th s s often the way that you wou d do t n C# and M crosoft V sua Bas c NET. but because t s a pub c c ass.

You don’t need to add anyth ng e se to th s project. and then. wh ch by defau t s ServiceReference1 the generated code w be p aced n th s namespace You can change t f you want. so just bu d t to create the DLL Using the wrapper You now have a DLL that conta ns a the code necessary to ca MathServ ce In the second part of the exerc se. In the Add Serv ce Reference d a og box that opens. but you’ need to remember t for subsequent steps 5. c ck Add Serv ce Reference 4. When you’re happy that you have a reference to the appropr ate serv ce. on the shortcut menu. Create a CLR Conso e App cat on project named TestWcf 366  Microsoft Visual C++/CLI Step by Step . you’ see how to use th s DLL n a C++/CLI app cat on 1.1. under the project. Create a C# C ass L brary project named WcfClientLib 3. Cont nue w th the project (MathServ ce) from the prev ous exerc se 2. r ght-c ck References. Add a reference to MathServ ce In So ut on Exp orer. press OK and V sua Stud o w generate a proxy c ass and app cat on configurat on fi e for you 6. you shou d see the MathService added to the Serv ces pane You can expand th s entry and c ck on IMathService to see the operat ons n the pane on the r ght Observe the Namespace name at the ower eft. type the URL of the serv ce nto the ad- dress box and press Go After a few seconds.

Add an externa reference to System::ServiceModel. n the Ut ty sect on.ServiceReference1. The proxy c ass s dr ven by configurat on nformat on. so open that n the ed tor and copy the <system. Open the project properties and then. If you changed the namespace for the generated proxy code. and specify the following command line: copy app. c ck Configurat on fi e (app config) Note  You need to edit the project properties so that the app.config "$(TargetPath). The configurat on deta s you need are n the DLL’s app config fi e.serviceModel> The entr es n the configurat on fi e g ve a the deta s that the proxy needs to contact the serv ce Ensure that you rep ace the va ue of userPrincipalName w th your deta s Chapter 19  Wr t ng a serv ce by us ng W ndows Commun cat on Foundat on   367 . on the shortcut menu. ed t the using d rect ve appropr ate y 5.config file is properly processed at build time. c ck to Add New Item 6.ServiceModel> e ement shown here <system. In the d a og box that opens. using namespace WcfClientLib::ServiceReference1. and then. click Post-Build Event. Add a second externa reference to the WcfC entL b DLL. 3.IMathService" name="WSHttpBinding_IMathService"> <identity> <userPrincipalName value="WIN8PREVIEW\Julian" /> </identity> </endpoint> </client> </system.serviceModel> <bindings> <wsHttpBinding> <binding name="WSHttpBinding_IMathService" /> </wsHttpBinding> </bindings> <client> <endpoint address="http://localhost:8080/MathService" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IMathService" contract="ServiceReference1. wh ch you’ find n the WcfC entL b/ b n debug d rectory 4. Add a using d rect ve for the namespace WcfClientLib.2. under Configuration Properties. so add an app cat on configurat on fi e to the project R ght-c ck the project name.config" 7.

Console::WriteLine("Result: {0}".8. Create a C# DLL project. . Define an nterface and annotate t w th [ServiceContract]. Access ng a serv ce us ng a proxy c ass. Test A WCF serv ce. Ensure that the serv ce s st runn ng and then bu d and run the c ent You shou d see the resu t d sp ayed on the conso e Quick reference To Do This Define a serv ce nterface. Annotate the methods on the nterface w th [OperationContract]. ca methods on the channe . result). Create a serv ce. You are now ready to use the serv ce Add the fo ow ng code to the main funct on try { MathServiceClient ^msc = gcnew MathServiceClient(). based on the name of the serv ce w th “C ent” appended Th s c ass d rect y mp ements the operat ons exposed by the serv ce. Then. } The proxy c ass s ca ed MathServiceClient. double result = msc->Cube(3. so you can just ca the Square and Cube funct ons w thout even hav ng to know that t s a serv ce 9. and add a reference to the ser v ce us ng the Add Serv ce Reference d a og.0). Use the the WCF Test C ent. Create a ServiceHost object Creat ng a serv ce c ent Create a ChannelFactory and use t to create a channe . Host a serv ce. } catch(Exception ^ex) { Console::WriteLine(ex->Message). Add the Serv ce Metadata behav or to your serv ce. Create a c ass that mp ements the serv ce nterface. Expose metadata from a serv ce.

the s mp e task of creat ng a w ndow on the screen enta ed ca ng a funct on that took no fewer than 12 parameters. HINSTANCE hInstance. nc udng touch screens and cameras Th s chapter ntroduces you to the wor d of wr t ng W ndows Store app cat ons for the new W ndows 8 env ronment A (brief) history of writing Windows user interface applications The way n wh ch W ndows user nterface (UI) app cat ons have been wr tten has evo ved over the years. DWORD dwStyle. enab ng them to wr te app cat ons that make fu use of the capab t es of mob e dev ces. 369 . you w be ab e to ■ Exp a n essent a features of the W ndows Store user nterface ■ Create user nterfaces by us ng XAML ■ Create. HWND hWndParent. and run a s mp e W ndows Store app ■ Descr be the essent a features of C++/CX T he re ease of W ndows 8 has presented deve opers w th new opportun t es and cha enges. LPVOID lpParam). HMENU hMenu.CHAPTER 20 Introducing Windows Store apps After comp et ng th s chapter. int y. then M crosoft NET. LPCTSTR lpWindowName. as demonstrated here HWND WINAPI CreateWindowEx( DWORD dwExStyle. and now W ndows 8 Th s sect on g ves you a br ef overv ew and h story and a so prov des nformat on to he p you dec de wh ch techno ogy you shou d cons der us ng for a UI app cat on The Win32 API The ear est W ndows UI app cat ons were usua y wr tten n C by us ng the W n32 API Th s was an exact ng task.eve brary tak ng care of the housekeep ng for you For examp e. somewhat equ va ent to wr t ng code n assemb y anguage There was a tremendous amount of bo erp ate code needed to do a most anyth ng. from the ear est app cat ons wr tten n C. int nHeight. int x. and you had to know just what was go ng on because there was no h gher. int nWidth. through a move to C++. LPCTSTR lpClassName. dep oy.

but t does perform most of the ted ous housekeep ng for you MFC made t poss b e to create app cat ons that ooked ke M crosoft Office and W ndows Exp orer.You can probab y guess what some of the parameters mean (x and y are the n t a pos t on of the w ndow. and wh ch cou d nteroperate w th Office app cat ons by us ng a comp ex techno ogy ca ed Object L nk ng and Embedd ng (OLE) MFC 9 ntroduced a number of new features nc ud ng support for dock ng w ndows s m ar to those found n M crosoft V sua Stud o. and other resources Windows Forms The first vers ons of NET ntroduced a new UI brary ca ed W ndows Forms (or WinForms). but there are many app cat ons that st use t Vers ons 7 through 9 were des gned to he p deve opers m grate to NET. n t a y re eased n 1992 and now at vers on 10 MFC prov des a th n C++ wrapper around the W ndow APIs. wh ch was mode ed on the M crosoft V sua Bas c way of creat ng UIs. you cou d wr te W ndows Forms app cat ons n any NET anguage W ndows Forms app cat ons can have mu t p e w ndows. d a ogs. and (as the name mp es) t was targeted at produc ng form-based app cat ons Because t was a NET brary. and a the other features that you wou d expect n a desktop W ndows app cat on A W ndows Forms app cat on cons sts of one or more w ndows ca ed forms. and a r bbon too bar s m ar to that used n M crosoft Office MFC has been deprecated n favor of NET. a though there are ed tors for cons. and so t s regarded as a egacy framework One drawback for MFC deve opers s that MFC has never had a UI des gner n V sua Stud o. and then ed t ng the bus ness og c parts Microsoft Foundation Classes M crosoft’s first C++ user nterface brary was M crosoft Foundat on C asses (MFC). and nWidth and nHeight spec fy ts s ze). but there are some obscure parameters and types here Creat ng app cat ons by us ng the W n32 API often means copy ng an ex st ng app cat on to get a the bo erp ate startup and housekeep ng code. and compile from the command line. Microsoft designed it so that you could create the entire UI in code if you wanted to. 370  Microsoft Visual C++/CLI Step by Step . b tmaps. and you typ ca y deve op t by dragg ng contro s from a too box onto a form and then us ng the Propert es ed tor to set contro propert es and event hand ers W ndows Forms was the first t me that C++ deve opers had a v sua des gner for creat ng UIs Note  Although you’d usually use the designer in Visual Studio to create Windows Forms applications. menus and too bars.

n common w th the way that many other mob e p atforms make content ava ab e Chapter 20  ntroduc ng W ndows Store apps   371 . an XML anguage. because the anguage acks support for part a c asses. WPF sn’t easy to use from C++/CLI. and th s feature s essent a f you are to work w th XAML I’m not ent re y certa n why th s wasn’t added— t wou d certa n y be poss b e—but t seems that M crosoft dec ded that t d dn’t want C++/CLI used for modern front-end deve opment Whatever the reason. wh ch was ntended to bu d on the success of W ndows Forms as we as add extra funct ona ty M crosoft S ver ght s a subset of WPF for wr t ng components to embed n webpages. and so there s no “WPF App cat on” project type Windows 8 and Windows Store A though W ndows 8 fu y supports the fam ar W ndows desktop env ronment. nc ud ng r ch support for med a (vector and raster mages. but for the t me be ng f you want to use W nForms. and v deo). and the V sua Stud o des gner creates the code that w generate the des red ayout at run t me Note that V sua Stud o 2012 does not support W ndows Forms for C++/CLI It s poss b e that support m ght be added back n a ater vers on. an mat on. to descr be UI ayout Th s makes t poss b e to a most comp ete y separate the presentat on and og c parts of an app cat on WPF supports many advanced features that do not appear n W ndows Forms. aud o. you w need to use V sua Stud o 2010 Windows Presentation Foundation Vers on 3 0 of the NET Framework saw the re ease of W ndows Presentat on Foundat on (WPF. t a so prov des a new way of wr t ng UI app cat ons W ndows Store apps use a brary ca ed Windows RT (or W nRT) wh ch prov des a UI brary that s a med at touch dev ces and the sty e of nterface made popu ar by the Pad and other tab ets It s ca ed W ndows Store because t s env saged that deve opers w create app cat ons and se them on ne through M crosoft’s W ndows Store. wh ch makes for much faster render ng and offers the ab ty to use hardware graph cs acce erat on when ava ab e WPF uses XAML. and advanced text render ng WPF’s support for data-b nd ng s far more powerfu and extens b e compared to W ndows Forms WPF can have a steep earn ng curve because t s ntended as a profess ona graph cs brary w th wh ch deve opers can create any UI they want rather than a brary that makes t easy to perform common tasks and bu d s mp e bus ness app cat ons Unfortunate y. codenamed “Ava on”). there has never been a C++/ CLI des gner for WPF n V sua Stud o.A form and ts ch d contro s are represented by objects n code. and wh ch prov de the same k nd of funct ona ty as Adobe F ash A though you can use t to des gn form-based app cat ons. b tmap effects such as drop shadows. WPF s very d fferent from W ndows Forms Here are some of the ma n d fferences ■ ■ ■ ■ WPF uses D rectX rather than the o der GDI graph cs subsystem.

f you want an up-to-date. such as acce erometers and cameras that users w expect to use Th s means that you need to get used to new ways of wr t ng app cat ons Of course. you w n some ways have an eas er task because you have ess to un earn If you read about deve opment w th W nRT. W ndows 8 supports two d fferent sty es of UI app cat on desktop and W ndows Store Note that they are comp ete y separate Among other th ngs. an mat on. that s the way to go. and they produced a d agram s m ar to the fo ow ng ustrat on 372  Microsoft Visual C++/CLI Step by Step . or med a fi e support. you w have to jump through qu te a few hoops to get there And. f you’re new to wr t ng W ndows UI app cat ons. they are des gned for d fferent types of app cat on I can’t see anyone produc ng a W ndows Store-sty e vers on of V sua Stud o any t me soon! Introducing Windows Store apps The W ndows Store UI br ngs a comp ete y new sty e of user nterface to W ndows app cat ons Many of the ways n wh ch UIs have been constructed s nce the first vers ons of W ndows are no onger supported For examp e. and there are few t mes when you wou d cons der start ng a new project us ng e ther of them (a though MFC does have some support for nteract ng w th Office that the newer brar es don’t have) If your app cat on s go ng to have a trad t ona form-based UI. there are no menus or d a og boxes. cons der W ndows Store Oh. “More about W ndows Store apps ” So. tab et-sty e nterface that w su t touch dev ces as we as desktop computers. and don’t et anyone te you that W ndows Store rep aces WPF. wh ch UI brary shou d you choose for your app cat ons? For most deve opers. cons st ng ma n y of text boxes and buttons. th s means that a W ndows Store app won’t appear on the desktop and needs to run n the W nRT env ronment Which UI library to choose? So. nc ud ng a v sua des gner If you want a desktop app cat on but w th the advanced features that WPF prov des. you w hear ta k of the “green and b ue stacks ” Th s phrase arose from how M crosoft descr bed how W nRT was go ng to fit w th the ex st ng W ndows deve opment techno og es. and doesn’t need fancy graph cs. a though f you are us ng C++. they requ re a d fferent approach to deve opment. or W ndows Store At th s po nt. n the W ndows Store UI. W ndows Forms w be su tab e You w find everyth ng you need n V sua Stud o. W n32 and MFC are rea y egacy techno og es. WPF. the cho ce w come down to W ndows Forms.W ndows Store app cat ons are very d fferent to trad t ona W ndows app cat ons. so how do you et users make cho ces? And then there are a the new modes of nteract on supported by handhe d dev ces. as you w see n th s and Chapter 21.

b ue sect on. depend ng on the stack that you choose You w not ce that NET s p aced n the o der.The area on the eft. then you shou d be ab e to apprec ate why these have been ntroduced App behavior Apps are secure and sandboxed. apps need to hand e mov ng to and from the background and term nat on gracefu y M crosoft s sett ng up a W ndows Store for W ndows 8 app cat ons. w th none of the wa t ng common to desktop app cat ons In fact. so you can sw tch back to t nstant y Suspended apps can be term nated f resources are needed. thus. ater n the chapter And f you’re go ng to d str bute your apps through the W ndows Store. and can’t wreck other app cat ons If users are go ng to down oad apps from an on ne store. they w a so need to be s gned w th a d g ta s gnature because anonymous app cat ons aren’t a owed Chapter 20  ntroduc ng W ndows Store apps   373 . s the new W nRT techno ogy stack. such as sockets and fi e I/O Apps oad qu ck y. you don’t start and stop apps ke you do the r cous ns on the desktop After you run an app t stays n memory but s suspended f you sw tch away from t. apps must be approved before be ng accepted. I’ st some of the major features of W ndows Store apps If you th nk of an app runn ng on a typ ca tab et dev ce or mob e phone. but you w to wr t ng W ndows Store apps find that t s st re evant Main features of Windows Store apps In th s sect on. n green n the or g na d agram. s m ar to the App Store used on App e dev ces In common w th most of these stores. and deve opers need to obta n a cense to be ab e to create apps You w see how to do th s when you create your first app. whereas the area on the r ght (or g na y n b ue) shows ex st ng techno og es Th s does mean that deve op ng for W ndows 8 now has two d st nct mode s. they need to be confident that a new one won’t affect what they a ready have nsta ed Down oad ng and nsta ng apps s made s mp er by us ng s ng e-fo der nsta at on One consequence of sandbox ng s that some APIs are not ava ab e.

have more than one w ndow. and m ght need perm ss on from the user n order to run W nRT p aces a prem um on app response Part of th s s ach eved by suspend ng apps and ett ng you resume them qu ck y In add t on. they can turn the desktop nto a dashboard Two types of UI are supported Code-based nterfaces can be wr tten n C#. such as those that affect data or user sett ngs or use dev ce features They must be dec ared by the app. a though t s poss b e to create the UI manua y n code Web-based nterfaces are wr tten n JavaScr pt and constructed by us ng HTML5 and CSS3 Contracts and charms W ndows 8 apps can work together us ng contracts. so there are some restr ct ons and un que aspects that you need to keep n m nd ■ ■ ■ Apps do not support over app ng w ndows An app can. Us ng C# or V sua Bas c NET and a subset of the NET Framework brar es 374  Microsoft Visual C++/CLI Step by Step . wh ch express capab t es (such as search or copy and paste) n a anguage. the UI s usua y constructed dec arat ve y by us ng XAML. and every app has access to five standard charms The WinRT APIs API ca s can be d rect or brokered Brokered ca s are those that m ght have secur ty concerns. C++. there are no menus or d a ogs T es are used to represent programs on the desktop Un ke cons.Hardware usage The W nRT APIs make t poss b e for deve opers to take advantage of hardware features such as mot on sensors and cameras. however. t es are act ve and can d sp ay content (such as weather or a stock report) By do ng so. any API ca that m ght take more than 50 m seconds s mp emented as an asynchronous ca so that deve opers are forced to adopt a respons ve cod ng sty e Writing a Windows Store app Most peop e w wr te W ndows Store apps n one of three ways 1. and you can move from w ndow to w ndow as you wou d n a browser Cont nu ng the browser ana ogy. or V sua Bas c. and apps can adapt to the hardware context.ndependent way Charms are UI e ements that nvoke contracts. such as sca ng to su t screen reso ut on or us ng the mouse and keyboard when touch nput s not ava ab e The UI model The W nRT UI mode s ntended for use w th touch dev ces that have a m ted d sp ay area.

This is not the case when writing Windows Store apps. There is some functionality available in JavaScript that isn’t available in C# or C++. but th s w show you the bas cs Remember that to create and run W ndows Store apps. c ck W ndows Store 3. for which there are very real differences in the three aforementioned approaches. In the pane on the eft. For now. This means that to use DirectX to write games. you see how to add more funct ona ty. In the So ut on Exp orer. you need to have V sua Stud o 2012 nsta ed on W ndows 8 Be aware that you m ght a so be prompted to get a deve oper cense when you create your first project For more nformat on about deve oper censes.2. and you then see a screen w th a v sua representat on of the UI n the upper ha f. Us ng JavaScr pt and HTML5 3. and the XAML n the ower ha f The UI has a b ack background because of the defau t theme that s used for app cat ons The XAML s s mp y an XML document cons st ng of a Page e ement that represents the ent re page. and vice versa. open Ma nPage xam The des gner oads (wh ch can take a few seconds). a Grid can contain multiple items laid out in rows and columns. Creating your first Windows Store app Th s exerc se shows you how to wr te the s mp est of W ndows Store apps. all languages are equivalent because they all compile down to Microsoft Intermediate Language (MSIL. or IL for short). Chapter 20  ntroduc ng W ndows Store apps   375 . and then name the project HelloXaml 4. In V sua Stud o 2012. In fact. open the New Project d a og box 2. wh ch n th s case cons sts of a s ng e screen and two contro s In Chapter 21. c ck B ank App (XAML). but the main difference is that if you want to use any Win32 and COM libraries you can only do it from C++. As you’d expect. the language that you choose reflects the syntax you prefer. Us ng C++ We are obv ous y go ng to be concentrat ng on the th rd opt on Note  When writing . you will need to use C++. let’s just note that a Page can only contain one content item. In the center pane. and wh ch conta ns a Grid e ement that w conta n the content for the page Note  You will learn about XAML in more detail later in the chapter. you could say that to a very large extent. and this will usually be some sort of layout control such as a Grid.NET applications. read the s debar at end of th s exerc se 1.

and adjust ts s ze because the defau t s rather sma You m ght a so want to adjust the font s ze for the TextBlock as we . P Now. ed t the Button’s Content attr bute to someth ng more su tab e. on the V ew menu. c ck Too box or press Ctr +W. Drag a TextBlock from the Too box to the page. which style you use is up to you. By specifying the first two. pos t on t next to the button. The Margin property determines how much space is left on all four sides of a component. the upper pane s s mp y a graph ca nterpretat on of the XAML. you shou d see that the Name fie d at the top of the Propert es w ndow d sp ays <No Name> Enter a su tab e name such as TxtHello and press Enter The XAML updates w th an x:Name attr bute. you’ll need to use the second form. the upper pane w update tse f accord ng y Note The Grid control can lay components out using rows and columns. c ck the Too box tab to d sp ay the Too box If the tab sn’t v s b e. Drag a button from the Too box to the page A button appears. the Button’s propert es n the XAML are updated to reflect any changes you make In fact. but if the content is going to be something other than text (such as another XAML element). wh e at the same t me a Button e ement s added to the XAML You can drag the button around to pos t on t wherever you ke. In the XAML pane. On the eft s de of the V sua Stud o w ndow. To work w th the TextBlock n code... because the defau t m ght be too sma when runn ng on a desktop computer You’ find the font sett ngs under the Text sect on n the Propert es w ndow 9. 8. /> <Button>Second One</Button> In this example. either by using the Content attribute or by providing it as the content of the element. you need to g ve t a name Ensure that the Propert es w ndow s v s b e by se ect ng Propert es W ndow from the V ew menu or typ ng Ctr +W. 7. f you ed t the XAML. such as in the following example: <Button Content="First One" . X to d sp ay t 6. and you can a so res ze t. you are effectively defining the position of the button. such as “C ck Me!” Note  You can provide the content to a control such as a button in two ways.5. in the order left-top-right-bottom. but this example is using absolute positioning. so converse y. se ect the TextBlock. as shown n the fo ow ng figure 376  Microsoft Visual C++/CLI Step by Step .

but you don’t need much deta for now. You now want the TextBlock to be updated when you press the button To do th s. To change the text n the TextBlock. on y c ck ng t n the UI at run t me 12. because you aren’t go ng to use e ther of the arguments 11. c ck Bu d So ut on to bu d the app and ensure that you have no errors Chapter 20  ntroduc ng W ndows Store apps   377 . and then. c ck the Button.10. add th s ne of code to the hand er TxtHello->Text = "Hello. c ck the sma ghtn ng-bo t button at the upper r ght Th s d sp ays a the events that the Button can ra se In th s case you just want to hand e the c ck event. you need to add a hand er for the Button’s c ck event In the des gner pane. On the Bu d menu. wh ch ooks ke th s void HelloXaml::MainPage::Button_Click_1(Platform::Object^ sender. so doub e-c ck ns de the text box. you d dn’t g ve a name to the Button because you aren’t nteract ng w th t n code. The name that you gave the TextBlock s used as the name for the object that represents t n code Any UI e ement that you want to nteract w th n code has to have a name. XAML!". Windows::UI::Xaml::RoutedEventArgs^ e) { } You’ earn more about event hand ng n Chapter 21. next to C ck Th s adds a hand er w th a defau t name to the Page c ass. n the Propert es w ndow.

Running a Windows Store app doesn’t just start it.13. you can a ways execute t by us ng the A Apps charm on the command bar 378  Microsoft Visual C++/CLI Step by Step . a though t doesn’t ook exc t ng because we haven’t defined any content for the t e yet If you c ck the t e you’ be back at your app’s UI. as dep cted n the screen shot that fo ows Press the button and check that the TextBlock updates Note  Windows Store apps work differently than traditional Windows applications. wh ch you can use to get back to the Start screen When you get there. r ght-c ck ts t e and then. it also adds it to the Start screen as an installed application. you m ght be wonder ng how you get back to V sua Stud o after you’ve performed test ng Mov ng the mouse to the ower. If you’re new to W ndows 8 apps. you’ not ce that your app has been added to the st of ava ab e app cat ons on the r ght of the page. and you w probab y find that the TextBlock st shows “He o. c ck Unp n From Start Even f an app cat on sn’t on the Start screen. XAML!” Th s s because apps stay act ve after they’re started I say “probab y” because apps can be term nated f there s pressure on resources. n wh ch case t wou d be restarted f you c cked t aga n If you dec de that you don’t want the app to appear on the Start screen. so you’ see the ent re screen taken up w th your app’s UI.eft corner of the screen d sp ays the Start con. Run the app n the norma way. on the shortcut menu that appears. us ng Ctr +F5 W ndows Store apps run fu screen.

for examp e. App xam h and App xam cpp The manifest file: Package. Different compilers (and even different versions of Microsoft C++) use their own ways of handling precompiled headers. and then reference the compiled version. you can get a 90-day deve oper cense Examining the project When you create a W ndows 8 app n V sua Stud o.microsoft. wh ch ones you can ed t and wh ch you shou d eave a one The fo ow ng fi es are those that you can ed t ■ ■ ■ ■ ■ XAML files  App xam for the app cat on.cpp  You can add your own headers to pch h.appxmanifest  Th s conta ns metadata descr b ng the app cat on You can doub e-c ck th s to open t n the Man fest Des gner The Assets folder  Th s conta ns Portab e Network Graph cs (PNG) fi es conta n ng defau t mages for the app cat on You can rep ace these w th your own mages to custom ze the appearance of your app cat on Precompiled headers: pch.com/en-us/library/windows/apps/hh974578.h will be precompiled. A lot of code is included in header files.Developer licenses When you create a W ndows Store project. and n part cu ar. whereas pch cpp s there s mp y to nc ude pch h Note  Precompiled headers are a feature of many C++ compilers. Ma nPage xam for the defau t page Each page of the app cat on has ts own XAML fi e. you m ght be prompted to obta n a deve oper cense Th s s needed to create W ndows Store apps It ets you nsta and test apps on your deve opment computer and then subm t them to the W ndows Store when you’re ready to show your code to the wor d You can find out more deta s on deve oper censes and how to obta n them at http://msdn. but for Windows Store apps any header files that are included in pch. Many of these header files will never change.aspx Be aware that f you s gn n by us ng a M crosoft Account (former y M crosoft L ve ID). a ot of fi es are created It s usefu to know someth ng about what they are. Chapter 20  ntroduc ng W ndows Store apps   379 . and so precompiled headers let the compiler process these once.h and pch. whereas App xam ho ds code and XAML that represents the app cat on tse f Code-behind files  A h and cpp fi e for each XAML fi e. and in a typical application the same header files can be compiled for each source file. you w be ssued a cense that needs to be renewed every 30 days If you create a W ndows Store account.

h and App. and the g cpp and g h fi es represent the parts of c asses that are generated by V sua Stud o ■ ■ ■ ■ App. thus. it is also used to describe workflows within Windows Workflow Foundation. I ntroduce the concepts beh nd XAML and ts grammar What is XAML? XAML (Extens b e App cat on Markup Language) s used n W ndows RT and WPF to descr be user nterfaces The dea beh nd XAML s that you create the user nterface dec arat ve y n XML. understand ng how XAML works w make you a much more product ve deve oper. and the one that we use here Create the UI comp ete y n code. and you’ a so find that there are some th ngs that you can on y do by ed t ng the XAML yourse f In th s sect on.g.cpp  Generated part a c ass defin t ons for the defau t page Another pa r of g h and g cpp fi es are added for every page you add to the app cat on XamlTypeInfo.xaml  Predefined sty es and temp ates You can der ve from these.h and MainPage. w th event hand ng code prov d ng the og c beh nd the UI Th s s the most common y used approach.h  Type nformat on generated by the XAML ed tor Introducing XAML A though you can do a ot by just us ng the drag-and-drop funct ona ty n V sua Stud o and ett ng t generate the XAML for you. it provides a general way to describe the relationships and properties of objects. but don’t change them MainPage.g. wh ch makes t poss b e for you to create soph st cated UIs w thout wr t ng any code Create the ayout n XAML.g.g. There are three ways by wh ch you can create UIs ■ ■ ■ Create the UI comp ete y n XAML The markup anguage nc udes features such as data-b ndng and tr ggers. the defau t approach taken by V sua Stud o. and the comp er then generates the code to create the UI at run t me Note  Although XAML is mainly used for creating UIs. but t can be usefu for comp ex and dynam c UIs 380  Microsoft Visual C++/CLI Step by Step . w th no XAML Th s s not the recommended approach.g.There are a so a number of fi es that you shou dn’t touch XAML app cat ons make heavy use of part a c asses.cpp  The ma n funct on and XAML oad ng code StandardStyles.

mak ng t poss b e for des gners to work on the XAML w thout hav ng to be concerned w th the code XAML’s event hand ng ets you nk contro events to hand er funct ons n code. wh ch means that they can be reused eas y If p aced n resource dictionaries. you have a powerfu way to create un que and respons ve UIs Temp ate and sty e deta s can be defined as resources n XAML.ke styles and triggers that can change sty es when events occur. you can define ayout and v sua behav or temp ates that can then be app ed to contro s across one or more app cat ons When comb ned w th CSS.. where the font s ze property of a contro can be bound to the pos t on of a s der You can a so b nd to co ect ons of objects. resources can be reused across projects F na y.. and you do th s us ng the x:Name attr bute. you don’t need to wr te any code at a Us ng Control templates. t must have a name. as demonstrated n the fo ow ng <ListBox> <ListBoxItem>Item 1</ListBoxItem> <ListBoxItem>Item 2</ListBoxItem> </ListBox> If you want to nteract w th a contro from code. mak ng t poss b e for you to b nd propert es on objects to data that can come from a var ety of sources I have a ready ment oned one examp e. but you can a so make event nks n XAML tse f For examp e. and the object’s propert es are defined by attr butes For examp e <Button Content="Click!" Click="Button_Click"/> Th s e ement represents a Button object It a so sets ts Content property and the name of the funct on used to hand e the c ck event It s easy to use custom c asses from XAML. an object s represented by an XML e ement. you can have a abe d sp ay the text of wh chever tem you se ect n a st box or for the font s ze of a abe to be determ ned by the pos t on of a s der Th s means that for many s mp e nteract ons between contro s. prov ded the runt me can ocate the assemb y conta n ng the object code Re at onsh ps between objects are shown by nest ng e ements For examp e. you can spec fy the name of a button’s c ck event hand er w thout hav ng to know n wh ch anguage t s go ng to be mp emented Th s a so makes t easy to separate the UI des gn and bus ness og c mp ementat on. or you can b nd to data retr eved from a data source XAML syntax In XAML. as shown n th s examp e <TextBlock x:Name="txtHello" . /> Chapter 20  ntroduc ng W ndows Store apps   381 . a ListBox can have a number of ListBoxItems. data-b nd ng s one of the most powerfu features of XAML.XAML has a number of features that are espec a y usefu for construct ng UIs Us ng XAML for declarative UI layout separates the UI’s ook and fee Th s way. so that a st box can d sp ay an array of tems.

> <TextBlock x:Name="TxtHello" .The x: prefix nd cates that th s s the XAML Name attr bute. > XAML a so makes use of markup extensions.. t s norma y used to create or man pu ate objects XAML controls A XAML UI s made up of contro s Everyth ng s a contro . as shown n the fo ow ng ustrat on 382  Microsoft Visual C++/CLI Step by Step . a Button can conta n a StackPanel wh ch ho ds both an mage and some text.. A content contro can on y conta n one other tem as ts content.. and the nk between the XAML and the c ass s prov ded by the x:Class attr bute <Page x:Class="HelloXaml. wh ch w be a conta ner such as a Window or Page We can d v de contro s nto two broad types content controls (wh ch can on y conta n one tem) and items controls (wh ch can conta n more than one) Note  There are a number of commonly used controls that don’t belong to these two groups (such as the Calendar and DatePicker) but for the purposes of explaining XAML. each page of a UI s represented by an object of a c ass der ved from Page The defin t on of th s c ass s n a code-behind fi e. because a contro cou d have ts own Name attr bute The prefix w be defined n one of the parent e ements of the TextBlock..com/winfx/2006/xaml" /> <Grid . for the moment. for nstance.MainPage" . xmlns:x="http://schemas. a Button can d sp ay a p ece of text or an mage...eve w ndow to the mage d sp ayed on a button Here’s an mportant pr nc p e XAML UIs are constructed by nest ng contro s w th n one another. ke th s <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> Th s syntax nforms XAML that the attr bute va ue sn’t s mp y text. I’ll keep it simple. as shown here <Page .microsoft. wh ch are attr bute va ues enc osed n cur y brackets. /> </Grid> </Page> In a W ndows RT app cat on.. and there s on y one contro at the top eve . from the top. but th s can be an tems contro As an examp e..

.

.

but a of the objects w st be created The VirtualizingStackPanel manages th s effic ent y by on y creat ng ch d contro s when they’re v s b e The Grid s one of the most common y used ayouts Items are arranged by row and co umn. t ays out ts ch dren hor zonta y By defau t.The StackPanel st fi s a the ava ab e space. but th s t me. you won’t see the contro s that fa outs de the bounds of the StackPanel. and ce s can have d fferent s zes You can spec fy the number of rows and co umns as we as wh ch ce a ch d contro shou d occupy The ustrat on that fo ows d sp ays how three buttons ook when d sp ayed n a Grid Chapter 20  ntroduc ng W ndows Store apps   385 . the ch d contro s are centered vert ca y If you have so many tems n a StackPanel that they aren’t a v s b e at one t me.

The XAML for th s ayout shows some nterest ng features <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}" > <Grid.Row="0" HorizontalAlignment="Center"/> <Button Content="Second" FontSize="24" Background="Green" Grid.Column="1" Grid. the aster sk (*) denotes a proport on.RowDefinitions> <RowDefinition Height="60*" /> <RowDefinition Height="40*"/> </Grid.Row="1" HorizontalAlignment="Center"/> </Grid> You can see how RowDefinition and ColumnDefinition e ements are used to define the rows and co umns n the gr d There are severa ways to define the w dth and he ght. such as by us ng percentages or abso ute va ues In th s case.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="60*" /> <ColumnDefinition Width="40*" /> </Grid.ColumnDefinitions> <Button Content="First" FontSize="24" Background="Blue" Grid. so t fi s a the ava ab e space The other mportant concept shown by th s examp e s the way n wh ch the row and co umn va ues are spec fied for the buttons Th s s done by us ng attached properties. wh ch are exp a ned n more deta n the s debar that fo ows 386  Microsoft Visual C++/CLI Step by Step .Row="1" HorizontalAlignment="Center"/> <Button Content="Third" FontSize="24" Background="Red" Grid. so the w dths of the two co umns are d str buted proport ona y n the rat o 60 40 L ke the StackPanel. there s no s ze spec fied for the Grid tse f.

the Grid.Row="1" ./> In code. but the one that you w encounter most s ett ng a ch d e ement spec fy a va ue for a property that actua y be ongs to the parent For examp e..SetRow(btn1..Attached properties Attached propert es are an nterest ng feature of XAML They are used for severa purposes. each gr d ce s 150 w de. and the MaximumRowsOrColums says that t w wrap at three tems To ach eve a n ce ayout. th s w be rendered someth ng ke th s Grid. but t ooks ke you’re sett ng a property on the Button tse f The VariableSizedWrapGrid s a var ant on the Grid It a so ays tems out n rows and co umns but w automat ca y wrap tems to the next row or co umn as necessary Th s s obv ous y usefu when the v ew ng area s ze changes.Column property that the buttons are us ng n the prev ous examp e s referr ng to the Column property on the Grid Suppose that you have the fo ow ng defin t on n the XAML <Button x:Name="btn1" Grid. You are nform ng the Grid that btn1 s go ng to be n row 1. such as when sw tch ng your tab et from andscape to portra t mode The fo ow ng mage shows five Button contro s n a VariableSizedWrapGrid The XAML ooks ke th s <VariableSizedWrapGrid Background="{StaticResource ApplicationPageBackgroundThemeBrush}" MaximumRowsOrColumns="3" Orientation="Horizontal" ItemWidth="150"> <Button Content="First" FontSize="24" Background="Blue" HorizontalAlignment="Center"/> <Button Content="Second" FontSize="24" Background="Green" HorizontalAlignment="Center"/> <Button Content="Third" FontSize="24" Background="Red" HorizontalAlignment="Center"/> <Button Content="Fourth" FontSize="24" Background="Cyan" HorizontalAlignment="Center"/> <Button Content="Fifth" FontSize="24" Background="Magenta" HorizontalAlignment="Center"/> </VariableSizedWrapGrid> The hor zonta or entat on shows that th s contro w ay ts ch dren out n rows. 1). and the buttons are centered w th n the r ce s If you dec de that you want a ayout that ooks more ke the W ndows 8 Start screen. you cou d change the XAML to the fo ow ng <VariableSizedWrapGrid Background="{StaticResource ApplicationPageBackgroundThemeBrush}" MaximumRowsOrColumns="3" Orientation="Horizontal" ItemWidth="150" ItemHeight="150" > <Button Content="First" FontSize="24" Background="Blue" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/> <Button Content="Second" FontSize="24" Background="Green" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/> Chapter 20  ntroduc ng W ndows Store apps   387 .

Top="100" Background="Blue"/> <Button Content="Second" FontSize="24" Canvas. but t sn’t used as often as the others because t doesn’t adapt automat ca y to chang ng d sp ay cond t ons Here s an examp e of some Buttons a d out on a Canvas Here’s the XAML for the ayout <Canvas Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <Button Content="First" FontSize="24" Canvas.Left="180" Canvas.Top="180" Background="Red" /> </Canvas> You can see that the pos t ons of the Buttons are g ven by the Canvas.Left="100" Canvas. so that the tems w fi the r respect ve ce s You can c ear y see the d fference n the fo ow ng mage The ast ayout contro we’ cons der s the Canvas W th th s contro . and the hor zonta and vert ca a gnments have been set to Stretch.Top attached propert es The objects are d sp ayed n the order n wh ch they are dec ared. resu t ng n the th rd Button over app ng the second If you want to spec fy the order ng exp c t y.Left and Canvas.<Button Content="Third" FontSize="24" Background="Red" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/> <Button Content="Fourth" FontSize="24" Background="Cyan" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/> <Button Content="Fifth" FontSize="24" Background="Magenta" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/> </VariableSizedWrapGrid> The d fference s that both he ght and w dth have been set. you can spec fy abso ute pos t ons for ts ch dren.Top="150" Background="Green"/> <Button Content="Third" FontSize="24" Canvas.Left="150" Canvas. you can use the ZIndex property to determ ne the order n wh ch e ements w be rendered 388  Microsoft Visual C++/CLI Step by Step .

you’re actua y c ck ng an Image on top of a StackPanel on top of a Button. hand ers for keyboard events w be sent a KeyRoutedEventArgs object whose Key property nd cates wh ch key was pressed In the case of s mp e c ck-type not ficat ons. and the second s a hand e to an object. and you probab y want to hand e th s event n the Button’s c ck hand er The event s first passed to the Image Then. and so on. whose name is based on the control and event names. of type RoutedEventArgs or one of ts subc asses. the first argument s a hand e to the object that ra sed the event. bubb ng up the tree unt t e ther reaches the top or someone says they’ve hand ed t C++/CX and Windows RT Wr t ng W ndows Store apps exposes you to yet another var ety of C++. t’s passed to ts parent (the StackPanel). The word “routed” n RoutedEventArgs refers to the fact that events can be routed to more than one contro Cons der the examp e you saw ear er n the chapter. t comp es down to nat ve code rather than IL. as in the previous example. there s no other nformat on. and you are free to use any name you like for event handlers. you use attr butes on contro s to nk events to event hand ng funct ons. they do not make use of the CLR When you wr te a W ndows Store app.Event handling When creat ng a UI n XAML. n wh ch a Button’s content cons sted of a StackPanel conta n ng an Image and a TextBlock If you c ck the Image. so you can gnore th s argument Note  Visual Studio will generate a handler for you. thus. Windows::UI::Xaml::RoutedEventArgs^ e) Every event hand er has the same s gnature the return type s vo d. known as C++/CX (Component Extens ons) You m ght we wonder (as I have myse f on more than one occas on) why M crosoft needed to create yet another set of extens ons to C++ when they had on y recent y ntroduced C++/CLI The ma n reason for th s s that W ndows Store apps do not use managed code. but this is simply a convention. so C++/CLI s not appropr ate Chapter 20  ntroduc ng W ndows Store apps   389 . the Button’s c ck event s be ng hand ed by a funct on ca ed Button Click n the assoc ated code-beh nd fi e Reca the examp e of an event hand er funct on n the He oXam that you saw ear er void HelloXaml::MainPage::Button_Click_1(Platform::Object^ sender. wh ch m ght ho d nformat on about the event For examp e. such as n the fo ow ng examp e <Button Content="Click!" Click="Button_Click"/> Here.

Th s means that you cou d wr te W ndows Store apps n standard. but you’d have to prov de a ot of housekeep ng code to work w th the under y ng Component Object Mode (COM)based nfrastructure For th s reason. use the ref new keyword. wh ch has no fac ty for nc ud ng metadata For th s reason. and so nterop w th unmanaged code s eas er. but it is more complex to use and beyond the scope of this book. so you can nspect them by us ng the IL d sassemb er too (ISDASM) C++/CX syntax C++/CX s a ghtwe ght set of extens ons to C++. you can still write WinRT apps in C++ by using a library called Windows Runtime Library (WRL). and NET (for C# and VB NET) Metadata A W nRT objects support reflect on through metadata. and you can eas y m x C++/CX and nat ve C++ types You m ght a so wonder where C++/CLI and NET fit nto the new wor d of W ndows RT app cat ons It turns out that C++/CX app cat ons can use a subset of the NET APIs. C++/CX does not support garbage co ect on Th s means that objects won’t move around n memory. M crosoft dec ded to add some extens ons to C++ to hand e these housekeep ng tasks. This can be useful if you want to access low-level features not exposed by C++/CX. unmanaged C++. so they can be used from dynam c anguages such as JavaScr pt W nRT uses the same metadata format as the CLR. n part cu ar manag ng object fet mes Note  If you don’t want to use the C++/CX extensions. wh ch makes t eas er and faster to use W nRT APIs from NET w thout hav ng to use P/Invoke W nRT code comp es down to nat ve code. Un ke C++/CLI. the metadata for W nRT code res des n separate fi es w th a w nmd extens on These are CLI assemb es conta n ng on y metadata. JavaScr pt. so there sn’t too much to cover n th s sect on To create an object. and there s a c ent profi e prov ded n V sua Stud o so that you can code aga nst th s subset Th s makes t poss b e for NET deve opers to wr te W ndows RT app cat ons by us ng fam ar APIs Windows RT W ndows RT s a new runt me on top of the W ndows kerne It doesn’t use W n32 It s comp ete y new It covers the same funct ona ty as W n32 (wh ch was ntroduced n 1993!) but s object-or ented and wr tten n C++ The W nRT APIs conta n a subset of the W n32 and COM APIs You can use W nRT APIs from severa anguages. as demonstrated n the fo ow ng 390  Microsoft Visual C++/CLI Step by Step . and anguage b nd ngs are now ca ed projections There are current y three project ons ava ab e nat ve (for C++).

n wh ch the GUI des gner n V sua Stud o generates code to represent a page The deve oper then creates the second ha f of the c ass to add UI og c Note  The lack of support for partial classes in C++/CLI is one of the reasons why it is not simple to create WPF applications in that language by using Visual Studio. by wh ch a c ass can be sp t nto more than one part and comb ned by the comp er Th s s necessary to support XAML. t needs to decrement the reference count When the count reaches zero. as you do w th C++/CLI public ref class MyClass { }.private. formed of two separate tokens. If a c ass s go ng to conta n W nRT components. and th s was a common source of error The W ndows Runt me now manages th s for you. The caret (^) s the same symbo used for managed hand es n C++/CLI. one part s dec ared by us ng the partial keyword and p aced n ts own header fi e // MyClass. t was up to deve opers to ensure that reference counts were ma nta ned correct y.MyClass ^mc = ref new MyClass().h #pragma once partial ref class MyClass { private: // use the 'partial' keyword Chapter 20  ntroduc ng W ndows Store apps   391 . so you no onger need to be concerned about object fet mes Classes You create run-t me c asses by us ng the ref keyword. but these are d fferent because they are po nt ng to unmanaged code We need a hand e here rather than a po nter because C++/CX objects are reference counted Observe the use of ref new to create objects Th s s an examp e of a compound keyword. and so t can destroy tse f In the past. t must be dec ared as a ref class C++/CX a so ntroduces the concept of partial classes. and s not s mp y new w th a ref mod fier Reference counting The COM mechan sm that under es W nRT uses a system of reference count ng to manage object fet mes Each t me c ent code obta ns a hand e to an object. the object knows that no one has a reference to t anymore. the object ncrements ts reference count When the c ent has fin shed w th the object. Here’s how you m ght use a part a c ass In the fo ow ng examp e.

and the typename n ang e brackets shows that T s the type parameter wh ch s used n the body of the c ass Strings Whereas n C++/CLI code you use a System::String to represent str ngs. t generates h and cpp fi es You w find that the h fi e (for examp e. you can create one ke th s wchar_t *txt = L"Second string". Or. and both are mmutab e You create a str ng ke th s String ^s = "First string". 392  Microsoft Visual C++/CLI Step by Step .h #pragma once #include "MyClass. whereas the h fi e s the pub c part that you can ed t As you m ght expect.int _implementationDetail. The second part of the c ass s p aced n another header fi e that nc udes the first one // MyClass. . }. but the nterest ng po nt s that anyone mp ement ng the pub c part of the c ass doesn’t have to see or know any deta s about the pr vate part When V sua Stud o creates the code for a XAML user nterface. there s a so a g cpp fi e. String ^s2 = ref new Platform::String(txt). }.h" ref class MyClass // don't use the 'partial' keyword here { public: int GetDetail(). n C++/CX you use a Platform::String Both types of str ng prov de the same bas c funct ona ty... }. just ke those you’ve met n C++/CLI generic <typename T> public ref class List { property T item. Anyone w sh ng to use the c ass w nc ude MyC ass h. wh ch conta ns the mp ementat on of the funct ona ty defined n the g h fi e Generics C++/CX supports run-t me gener cs.private. The generic keyword ntroduces a gener c type. MyPage h) nc udes another header (MyPage g h) The g h fi e s the part a c ass generated by the des gner conta n ng the pr vate part of the page defin t on.

.

.

n the pane on the eft. se ect the B ank App (XAML) project type. hor zonta y or vert ca y. Doub e c ck the contro to add a hand er for the defau t event. n the center pane. Use a StackPanel conta ner w th the Orientation set appropr ate y.Quick reference To Do This Create a s ng e page W ndows Store app. Lay out e ements n a row. or ed t the XAML d rect y. n the New Project d a og box. Then. Lay out e ements n a gr d Use a Grid conta ner. use the event st n the Property ed tor. Chapter 20  ntroduc ng W ndows Store apps   395 . c ck W ndows Store. To add hand ers for other events. Add contro s to the page. Hand e events from contro s. Drag contro s from the Too box to the page.

.

you w be ab e to ■ Create a more comp ex app by us ng XAML and code-beh nd ■ Hand e events from a more comp ex user nterface ■ Use W ndows Store app features. and wh ch can be dep oyed onto any M crosoft Surface tab et dev ce As we as show ng you how to create a rea st c W ndows 8 app. but we’re go ng to m t the add t ons to the ab ty to work n d fferent number bases (dec ma . and b nary) In add t on.CHAPTER 21 More about Windows Store apps After comp et ng th s chapter. such as ar thmet c operat ons and be ng ab e to save va ues n memory. such as app bars ■ Share content w th other app cat ons I n th s chapter you w create a more comp ex W ndows Store app. but t w a so add some funct ons that are often usefu to programmers There s a ot that cou d be added. hexadec ma . you w a so earn about some of the new features that the W ndows Store nterface has added to W ndows programm ng Building the basic calculator The app you’ be bu d ng dur ng the course of th s chapter s a programmer’s ca cu ator Th s w offer the features of a norma ca cu ator. programmer’s ca cu ators often work on y w th ntegers because they are used to man pu ate addresses. so that’s what we’ do here The screen shot that fo ows shows how the fin shed app w appear 397 . one that uses a touch nterface.

w th a TextBlock at the top to d sp ay the current va ue. it is designed for use in landscape orientation only. the UI does not adapt itself to portrait mode. First. f the user has se ected b nary mode. it is only going to be a single page app.As you des gn and code th s app. but you need to expend some effort to ensure that the UI works n the correct way For examp e. the keys “0” through “9” and “A” through “E” shou d be enab ed Laying out the number buttons Our UI s a d out n typ ca ca cu ator sty e. you w see how apps w th a graph ca UI ke th s are often not that comp ex n what they’re do ng. and we can’t consider all of them without turning this chapter into a book. That means that this app is going to be limited in several respects. 398  Microsoft Visual C++/CLI Step by Step . number keys a d out n a gr d Note  There are a lot of features that you need to consider—and lots of ways of implementing them—when designing a touch-based app for the Windows Store and the Microsoft Surface tablet. on y the “0” and “1” number keys shou d be enab ed When he sw tches to hexadec ma . and be ow that. Second.

Drag a TextBlock to the form and drop t nto the Border. In the ed tor. and ay out the number buttons 1. and then p ace the TextBlock ns de t 4. as opposed to V sua Stud o’s codeor ented approach B end takes a more v sua approach to UI des gn than V sua Stud o. set ts BorderThickness property to 2. you actually don’t need to give the Border a name. wh ch prov des a more des gn-or ented env ronment for creat ng UIs. To create an area where the numbers you enter and the resu ts of ca cu at ons are d sp ayed. wh ch makes t s mp er to create sty es and other graph ca e ements The dea s that des gners can use B end to create soph st cated ayouts by us ng XAML and then pass them on to deve opers who can add the og c n code In th s first exerc se.Microsoft Blend for Microsoft Visual Studio V sua Stud o comes w th a des gn too ca ed B end for V sua Stud o 2012. drag a Border from the Too box to the ma n page. because you aren’t going to interact with it from code. you shou d find that t expands to fi the Border contro Add the x:Name attr bute to g ve t a name so that you can nteract w th t n the code I’ve ca ed t txtOutput You shou d a so remove the Text attr bute from the XAML and set ts FontSize property to a su tab e va ue such as 72 Note  For this particular app. Chapter 21  More about W ndows Store apps   399 . and then set BorderBrush to Gray (or any other co or you ke) The numbers you enter nto the ca cu ator are go ng to be d sp ayed n a TextBlock. Only those UI elements with which you interact need to have a name. and t wou d ook good to g ve the TextBlock a border The way you do th s n XAML s not obv ous you add a Border contro to represent the border. pos t on ng t at the top w th a eft marg n of about 430 and a top marg n of about 50 Use the hand es to res ze the area to approx mate y 90 un ts h gh by 730 un ts w de. open Ma nPage xam 3. you w and text d sp ay create a project w th a s ng e page. Start V sua Stud o 2012 and create a new “b ank XAML” project named ProgCalc 2.

but they are rather sma for a ca cu ator I ed ted the propert es to make them 100 w de by 108 h gh..0. such as btnOne You shou d end up w th a gr d pos t oned underneath the Border.0. and eft a gned w th t. </Grid> Don’t worry about the exact s zes and pos t ons Where the buttons are and how they ook sn’t mportant to the funct on ng of the app 5.167.0.0.The XAML shou d now ook someth ng ke th s <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <Border BorderBrush="Gray" BorderThickness="2" HorizontalAlignment="Left" Height="89" Margin="432. s m ar to the fo ow ng screen shot The XAML ought to ook s m ar to the fo ow ng <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"> <Border BorderBrush="White" BorderThickness="2" HorizontalAlignment="Left" Height="100" Margin="431.0" VerticalAlignment="Top" Width="731"> <TextBlock x:Name="txtOutput" TextWrapping="Wrap" FontSize="72" HorizontalAlignment="Left"/> </Border> .0.0" VerticalAlignment="Top" Height="108" Width="100" FontSize="72"/> 400  Microsoft Visual C++/CLI Step by Step . and gave them a font s ze of 72 Ensure that you use the x:Name property to g ve each button a descr pt ve name. Drag buttons to the page to start bu d ng up the gr d The buttons d sp ay w th a preset sty e.167.0" VerticalAlignment="Top" Width="731"> <TextBlock x:Name="txtOutput" TextWrapping="Wrap" FontSize="72"/> </Border> <Button x:Name="btnOne" Content="1" HorizontalAlignment="Left" Margin="431.48.50.0" VerticalAlignment="Top" Height="108" Width="100" FontSize="72"/> <Button x:Name="btnTwo" Content="2" HorizontalAlignment="Left" Margin="550.167.0" VerticalAlignment="Top" Height="108" Width="100" FontSize="72"/> <Button x:Name="btnThree" Content="3" HorizontalAlignment="Left" Margin="669..

0" VerticalAlignment="Top" Height="108" Width="100" FontSize="72"/> <Button x:Name="btnFive" Content="5" HorizontalAlignment="Left" Margin="550.0" VerticalAlignment="Top" Height="108" Width="100" FontSize="72"/> <Button x:Name="btnEight" Content="8" HorizontalAlignment="Left" Margin="550.294.0. c ck Start W thout Debugg ng The app starts by show ng a gray sp ash screen. a though noth ng w happen at th s po nt You can get back to the desktop n severa ways you can e ther go v a the Start screen.<Button x:Name="btnFour" Content="4" HorizontalAlignment="Left" Margin="431.0" VerticalAlignment="Top" Height="108" Width="100" FontSize="72"/> <Button x:Name="btnZero" Content="0" HorizontalAlignment="Left" Margin="550.0. and then shows the UI If you move the mouse around you w see that buttons h gh ght as you move over them. you can add the og c beh nd the buttons When the user presses the number keys. on the Debug menu.0.0" VerticalAlignment="Top" Height="108" Width="100" FontSize="72"/> <Button x:Name="btnClear" Content="C" HorizontalAlignment="Left" Margin="431.0" VerticalAlignment="Top" Height="108" Width="100" FontSize="72"/> <Button x:Name="btnSix" Content="6" HorizontalAlignment="Left" Margin="669.0. as out ned n the fo ow ng ■ Get the current str ng from the TextBlock ■ Get the d g t character represented by the number key ■ Add the d g t to the str ng ■ Put the new str ng nto the TextBlock The fo ow ng steps mp ement th s og c n a hand er 1.0. Se ect one of the d g t buttons n the XAML Open the Propert es ed tor by c ck ng the Prop- ert es tab at the s de of the V sua Stud o w ndow and then c ck the ghtn ng-bo t button at the upper-r ght of the ed tor to d sp ay the events for the button Chapter 21  More about W ndows Store apps   401 . use the A t+Tab key comb nat on.422. t can ex st as a str ng on the d sp ay Th s means that hand ng d g t entry s very s mp e.0" VerticalAlignment="Top" Height="108" Width="100" FontSize="72"/> </Grid> 6. Bu d and run the app to check that everyth ng s OK Start t by press ng Ctr +F5 or.0.422. and you can a so press them.550.550.0.422. you want to remember what they have pressed and bu d up the number The eas est way to hand e th s s to rea ze that you don’t need the actua number unt you come to perform an operat on unt that po nt.0" VerticalAlignment="Top" Height="108" Width="100" FontSize="72"/> <Button x:Name="btnEquals" Content="=" HorizontalAlignment="Left" Margin="669.0" VerticalAlignment="Top" Height="108" Width="100" FontSize="72"/> <Button x:Name="btnNine" Content="9" HorizontalAlignment="Left" Margin="669.294.0" VerticalAlignment="Top" Height="108" Width="100" FontSize="72"/> <Button x:Name="btnSeven" Content="7" HorizontalAlignment="Left" Margin="431.0.294. or press W ndows key+X to br ng up a menu from wh ch you can se ect the desktop Handling number input Now that you have a bas c ayout n p ace.0.550.

Bu d and test the app You shou d now be ab e to enter numbers and c ear the d sp ay 402  Microsoft Visual C++/CLI Step by Step . et’s add the og c for the Clear button A th s needs to do for now s to c ear the str ng n the d sp ay 5. so the cast s safe 3. add ng a Click attr bute to the e ements for each button The advantage to do ng t th s way s that you can cut and paste the text rather than hav ng to type t n the ed tor 4. ke th s void ProgCalc::MainPage::ClearButton_Click(Platform::Object^ sender. Imp ement the hand er to c ear the str ng n the d sp ay. Windows::UI::Xaml::RoutedEventArgs^ e) { txtOutput->Text = "". Add a hand er ca ed ClearButton Click to the Click event and then press Enter V sua Stud o creates a new hand er for you 7. open the Propert es ed tor. String ^digit = (String^)btn->Content. wh ch shou d be at the top Type NumberButtons Click n the text box and press Enter Th s causes V sua Stud o to create an empty event hand er Ed t the hand er so that t ends up ke th s void ProgCalc::MainPage::NumberButtons_Click(Platform::Object^ sender. wh ch ho ds the d g t you want You then need to cast the Content to a String Buttons can have a sorts of th ngs as content. Add the same hand er to a 10 number buttons You can e ther do th s by us ng the Property ed tor or by ed t ng the XAML. you can open the Properties editor by selecting Properties Window from the View menu or pressing Ctrl+W and then P. } 8. } You first need to cast the sender hand e to a Button. txtOutput->Text += digit. find the Click entry.Tip  If the Properties tab is not visible. In the st of events. so that you can use ts Content property. and then d sp ay the event st 6. but n th s case you know that t s a str ng. Bu d and run the app You can c ck the number buttons to bu d up a number as a str ng n the TextBlock And wh e we’re th nk ng about the d sp ay. 2. Se ect the Clear button n the XAML. Windows::UI::Xaml::RoutedEventArgs^ e) { Button ^btn = (Button^)sender.

You can then select it and drag it to the right to position it correctly. as ustrated n the fo ow ng screen shot Tip  An easy way to do this is to duplicate a line in the XAML. and then edit it accordingly.Adding arithmetic operations Now that the numbers are d sp ay ng correct y. For example. ass gn them a co or You can do th s by sett ng the Foreground property. I copied the “3” button. renamed it to btnPlus and changed the Content to “+”. a ong the r ght s de of the numbers. Ed t the XAML to add four buttons for the bas c ar thmet c operat ons I p aced them n a ver- t ca co umn. 2. the designer will show you when buttons are aligned correctly. To d fferent ate the ar thmet c buttons from the number keys. and then store t as the eft operand ■ Remember wh ch operat on was se ected ■ C ear the d sp ay and prepare t to accept the r ght operand Adding the arithmetic buttons The fo ow ng exerc se mp ements the aforement oned steps 1. t s gna s that she has fin shed enter ng the first number Th s means that you need to perform the fo ow ng steps ■ Get the str ng from the d sp ay. the next step s to add the buttons and og c for the ar thmet c operat ons When the user presses one of the ar thmet c operat on buttons. convert t to a number. e ther through the Property ed tor or by ed t ng the XAML d rect y (I set my buttons to LightGreen ) Chapter 21  More about W ndows Store apps   403 .

&val). remember ng to p ace t n the pr vate sect on int leftOperand.3. you need to get the str ng from the TextBlock. Add code to the hand er to convert the text to an int and store t n the leftOperand void ProgCalc::MainPage::ArithmeticButtons_Click(Platform::Object^ sender. When you have added a four buttons. L"%d". int val. convert t to an nteger. wh ch you can get from the String object by us ng ts Data funct on The second argument s the format str ng The ead ng L denotes a w de character (as opposed to an ASCII) str ng tera . leftOperand = val. Windows::UI::Xaml::RoutedEventArgs^ e) { String ^txt = txtOutput->Text. and the one I’ve used here w s mp fy us ng other number bases ater n the program The swscanf s funct on takes a str ng and converts t accord ng to a format The first argument s the raw str ng. 2. } There are a number of ways to perform the string-to-int convers on. You should always use the second of these because it does extra checking on its arguments and is less open to misuse. the &val passes the address of the var ab e where the resu t shou d be wr tten Note  There are two versions of sswscanf: swscanf and swscanf s. and store t for ater use 1. p ck one and d sp ay ts events n the Property ed tor Type ArithmeticButtons Click as the hand er name and then press Enter V sua Stud o adds an empty hand er for you 4. 404  Microsoft Visual C++/CLI Step by Step . Ed t the other three ar thmet c operat on buttons so that they use the same hand er Getting the number Now. either accidental or deliberate. Start by add ng an nteger member to the MainPage c ass n Ma nPage xam h. swscanf_s(txt->Data(). and %d a erts the funct on to expect a str ng that represents a dec ma nteger F na y.

.

C ear the d sp ay by sett ng the Text property for the TextBlock to an empty str ng 6. } The enum has one member for each operat on. us ng a cha n of if-else statements Button ^btn = (Button^)sender. TIMES. above the MainPage c ass dec arat on but st w th n the namespace namespace ProgCalc { enum class ArithOp { PLUS. } 4. Open the Ma nPage xam h fi e and add the dec arat on for an enum at the top. sett ng a breakpo nt n the ar thmet c button hand er to check that the convers on s work ng 406  Microsoft Visual C++/CLI Step by Step . Bu d the app to ver fy that there are no errors You can’t see any resu t at th s stage. p us one to nd cate that there s no operat on The names fo ow convent on by be ng n cap ta s 2. if (btn == btnPlus) currentOp = ArithOp::PLUS.Remembering the operation What’s the best way to remember wh ch operat on has been se ected? The obv ous so ut on s to use a var ab e to store the operat on. Add a pr vate member to the MainPage c ass to represent the current operat on ArithOp currentOp. DIVIDE. and the fact that we want to choose one of a sma set of va ues shou d suggest us ng an enum for th s 1. p ac ng t after the ca to InitializeComponent MainPage::MainPage() { InitializeComponent(). but you can f you want run the app n the debugger. Open the Ma nPage xam cpp fi e and set the operat on to NONE n the constructor. public ref class MainPage sealed { … }. NONE }. You can now see wh ch button was pressed Ed t the ArithmeticButtons Click funct on to set the operat on accord ng y. 3. else if … 5. MINUS. currentOp = ArithOp::NONE.

br ng up the propert es for the Equa s button and add a hand er ca ed EqualsButton Click 2. as shown n the fo ow ng int { } ProgCalc::ConvertTextToInt(Platform::String ^str) int val. any t me that you see dup cated code. a process ca ed refactoring Open the Ma nPage xam h fi e and add the prototype for a funct on ca ed ConvertTextToInt. swscanf_s(str->Data().Tip  Checking that your code works by using the debugger is recommended practice. you shou d cons der pu ng t out nto a separate funct on. Because th s s a ut ty funct on and doesn’t need access to nterna deta s of MainPage. return ■ Get the text from the d sp ay and convert t to a number ■ Perform the ca cu at on. but th s wou d ead to dup cat on As a ru e. a though you can make t one f you ke 4. In Ma nPage xam . Chapter 21  More about W ndows Store apps   407 . return val. Writing output by using Console::WriteLine isn’t! Performing calculations You can now comp ete the bas c funct ona ty by mp ement ng the og c beh nd the Equa s button The operat ons you need to perform are as fo ows ■ Check that there s someth ng to do If there s no content n the TextBlock or no current operat on. L"%d". 3. &val). if (txtOutput->Text->Length() == 0) return. Add the mp ementat on to the Ma nPage xam cpp fi e. Get the str ng from the d sp ay and convert t to a number You’ rea ze that you need to use the same code that you mp emented n the ar thmet c button hand er. Add checks at the start of the hand er to determ ne f there s anyth ng to do if (currentOp == ArithOp::NONE) return. us ng the current operat on ■ Echo the resu t to the d sp ay Adding the handler and getting the number 1. p ac ng t ns de the namespace int ConvertTextToInt(Platform::String ^str). th s doesn’t have to be a member of the MainPage c ass.

2. Observe the ca to Reset If you get a d v de by zero. This is reasonable for a tutorial example such as this. d sp ay an error message and return case ArithOp::DIVIDE: if (rightOperand == 0) { txtOutput->Text = "Divide by zero". and another to ho d the resu t int rightOperand = 0. .. Add t on. subtract on.. return. 6. Rep ace the or g na code n the ar thmet c button hand er w th a ca to your new funct on. and mu t p cat on are s mp e. Start by dec ar ng the fo ow ng two var ab es. ke th s leftOperand = ConvertTextToInt(txtOutput->Text). Add a sw tch statement that branches based on the operat on switch(currentOp) { case ArithOp::PLUS: result = leftOperand + rightOperand.Note  There is nothing in the way of error checking here because we’re sure that the only content of the string is digits. 3. but you need to guard aga nst d v d ng by zero If you find that you are about to th s. you can’t cont nue. so conversion should not fail. one to ho d the number current y n the TextBlock. } result = leftOperand / rightOperand. you want to abandon the ca cu at on and reset everyth ng But. t makes sense to put t n a separate funct on 408  Microsoft Visual C++/CLI Step by Step . Bu d the app and confirm that t st works as expected Performing the arithmetic operation At ast you can add the code to EqualsButton Click to perform the operat on 1. but in a real app you’d want to check that the user hadn’t entered a number too large to fit in an integer. because th s can nvo ve severa operat ons. break. break. Store the content of the TextBlock n the rightOperand var ab e rightOperand = ConvertTextToInt(txtOutput->Text). int result = 0. Reset(). 5. } 4.

} The funct on c ears the operat on and saved eft operand The clearOnNextKey var ab e he ps w th contro ng the UI At present. a ong w th a Boo ean member ca ed clearOnNextKey void Reset(). swprintf needs an array of wchar t. 6. 80. finding that in order to do A. clearOnNextKey = false. swprintf(buff. and so on. eventually you do get back to A again! wchar_t buff[80]. the TextBlock w be c eared before proceed ng 8. result). clearOnNextKey = true. as demonstrated here void ProgCalc::MainPage::Reset() { currentOp = ArithOp::NONE. wh ch you need to convert to a Platform::String n order to use t w th the TextBlock Chapter 21  More about W ndows Store apps   409 . But.5. Add the defin t on to the source fi e. L"%d". which requires C. you can comp ete the equa s hand er. Sometimes it feels as if you’re moving backward. txtOutput->Text = ref new String(buff). Th s code uses swprintf—wh ch does the oppos te to the swscanf s funct on that you earned about ear er—tak ng a va ue and convert ng t to a str ng n a g ven format Un ke swscanf s. ready for you to enter a new number What we want to do n th s case s to eave the message on the d sp ay and not c ear t unt the user taps a number key 7. After you’ve done that. Add the fo ow ng code to the start of NumberButtons Click if (clearOnNextKey == true) { txtOutput->Text = "". bool clearOnNextKey. leftOperand = 0. the TextBlock s c eared when you press an operator key. } If the flag s set. turn ng the resu t nto a str ng and putt ng t back n the d sp ay Note  Development is often like this: you start implementing one piece of code and find that there are things you need to do before proceeding. Add the fo ow ng dec arat on of the pr vate Reset funct on to the MainPage c ass n Ma nPage xam h. you need to do B.

so I need to test that th s d sp ays correct y I a so rea ze that I’ have to test for d v s on by zero. you shou d start by mak ng a test p an Th s doesn’t have to be anyth ng comp ex or grand. so I’ add that one My st now ooks ke th s 410  Microsoft Visual C++/CLI Step by Step . so we can start w th the fo ow ng four tests ■ Add t on of two numbers ■ Subtract on of two numbers ■ Mu t p cat on of two numbers ■ D v s on of two numbers Two th ngs mmed ate y spr ng to m nd when I ook more c ose y at th s st A subtract on such as 5 – 8 w y e d a negat ve number. but des gn ng a p an he ps to avo d the prob em of “test ng by p ay ng around. and t s very annoy ng when the prob em s someth ng bas c that ought to have been caught dur ng deve opment To avo d nfl ct ng the same frustrat on on your users. f another test occurs to you. wh ch means that surpr ses m ght be eft n the code for users to find ater A good p ace to start s by mak ng a st of what you want to test Don’t worry about th nk ng of everyth ng stra ght off. not th nk ng about what m stakes the user cou d make. now that you have mp emented the bas c og c for the ca cu ator. you need to test what you’ve done before proceed ng Th s w ensure that you are bu d ng on a so d foundat on When test ng.” when you test what occurs to you at the t me If you do that. there s no reason to suspect that other numbers w behave d fferent y The same s true of the other ar thmet c operators.Testing the calculator Have you ever had a prob em w th a p ece of software and found yourse f th nk ng “d dn’t anyone test th s before they re eased t?” We have a exper enced buggy software that doesn’t work proper y or crashes. you run the r sk of m ss ng out some v ta area because t d dn’t occur to you How do you dec de what needs to be tested? Here are severa areas that you need to cons der ■ Does the bas c funct ona ty work as t shou d? ■ Does the UI render the resu ts correct y and eg b y? ■ Does the app hand e m stakes and errors proper y? ■ Does the UI respond to error cond t ons correct y? Many deve opers make the m stake of on y test ng the first category. 1 + 2 and 3 + 3. add t to the st A first obv ous test s for add t on add ng two numbers resu ts n another number that represents the r sum If you test th s w th. say.

and add ng or subtract ng zero a so has to be cons dered And so we now end up w th the fo ow ng ■ Add t on of two numbers • Add t on of zero g ves r ght answer ■ Subtract on of two numbers • D sp ay of negat ve resu t from subtract on • Subtract on of zero g ves r ght answer ■ Mu t p cat on of two numbers • Mu t p ■ cat on by zero g ves zero D v s on of two non-zero numbers • D v de-by-zero resu ts n correct error That w do for the bas c operat on of the ca cu ator Now.■ Add t on of two numbers ■ Subtract on of two numbers • D sp ay of negat ve resu t from subtract on ■ Mu t p cat on of two numbers ■ D v s on of two non-zero numbers • D v de-by-zero resu ts n correct error Another th ng occurs to me gett ng zero nvo ved n ca cu at ons s not just a spec a case for d v s on Mu t p y ng by zero resu ts n zero. and you shou d ensure that you test as many as you can before cont nu ng Chapter 21  More about W ndows Store apps   411 . you need to th nk about the operat on of the user nterface Here are a few examp es ■ Does the C ear button return the ca cu ator to ts start ng po nt whenever t s pressed? ■ What happens f the user keeps press ng the Equa s button? ■ Does Equa s hand e an empty d sp ay or no operat on? There are a number of other cond t ons that you cou d add.

V sua Stud o nc udes too s w th wh ch you can create a su te of un t tests and run them w th the c ck of a button It s s ght y more comp ex to test UIs. gray square w th a wh te cross n the m dd e Th s s the defau t mage supp ed for you. so good pract ce recommends automat ng the test ng of app cat ons For test ng nd v dua funct ons and c asses.aspx Improving the graphics When you run the app.com/b/ windowsappdev/archive/2012/09/04/automating-the-testing-of-windows-8-apps.appxmanifest fi e to open the man fest ed tor The man fest conta ns deta s of the resources used by the app and s arranged on four tabs The App cat on UI tab s the one n wh ch we’re nterested Th s s where you spec fy deta s of UI e ements such as the t es and sp ash screen 412  Microsoft Visual C++/CLI Step by Step . but f the app needs to show more nformat on. t es are 150x150 p xe s n s ze. but you can find more deta s on the Internet. you can wr te scr pts to s mu ate press ng buttons and then see what the state of the app s D scuss ng how to do th s s beyond the scope of th s book. t can use a w de t e that s 310x150 p xe s Creating and using a tile Doub e-c ck the Package. you’ see that t appears on the Start screen as a rather bor ng. you shou d dea y run your tests every t me you make a change to the code It s obv ous y not dea to have to test your app manua y each t me. and any ser ous deve oper s go ng to want to update that to someth ng more eye-catch ng and usefu But first. but W ndows RT prov des ways to automate the execut on of your app cat ons Us ng them. et’s ta k about t es Anyone who has worked w th a computer s comp ete y fam ar w th cons—those tt e square graph cs that are used to represent and start app cat ons W ndows 8 has taken the usefu ness of cons to a new eve by ntroduc ng t es By defau t. and that your code st works as expected. nc ud ng http://blogs.msdn.Automating tests To ver fy that you haven’t broken anyth ng.

such as n search resu ts and n sts of searchab e apps The sp ash screen (620x300 p xe s) that d sp ays wh e your app s start ng up Because you’re not go ng to subm t th s part cu ar app to the W ndows Store. you don’t need to create a of these But we w address two of them to make the ca cu ator ook a b t more rea st c Chapter 21  More about W ndows Store apps   413 . used w th your app’s d sp ay name n var ous p aces.If you’re go ng to subm t your app to the W ndows Store. used to d sp ay your app n search st ngs n the W ndows Store ■ ■ The sma ogo (30x30 p xe s). you’ need to prov de severa ogos and mages At a m n mum you need to prov de the fo ow ng ■ The standard 150x150-p xe square ogo ■ The store ogo (50x50 p xe s).

Microsoft encourages designers to provide properly scaled versions of the various image files because these will look much better than scaling them programmatically. you can use any program you ke. t s very common to use wh te graph cs on a co ored background. copy t nto the Assets fo der for your app Then. and type the name of the fi e nto the Logo box. There are two ways n wh ch you can prov de a ogo the first s to ed t the defau t graph c created for the project. doub e-c ck the Logo png fi e Th s opens the fi e n the bu t. open the Man fest Ed tor.n graph cs ed tor I created the ogo shown n the fo ow ng ustrat on by us ng a pa nt program. and the second s to create another graph c and mport t To ed t the ogo. and to make the mage background transparent Th s makes t poss b e for users to change the background co or of t es. n So ut on Exp orer. as demonstrated n the fo ow ng screen shot Observe the Background Co or entry n the ed tor A though you can use any mage you want for a t e.Note  The Manifest Editor has several entries for some of the logos under the heading Scaled Assets. prov ded you can produce an mage that s 150x150 p xe s and saved as a Portab e Network Graph cs (PNG) fi e To use t to represent your app. To get the best UI experience. wh e st ma nta n ng a cons stent ook Here’s how the app ooks on the Start screen now 414  Microsoft Visual C++/CLI Step by Step .

the mage s often created w th a transparent background so that users can change the W ndows background co or After you have created an mage of the correct s ze. the t e for a weather app cou d d sp ay the current temperature and a weather symbo . as shown n the fo ow ng You p ck a badge from a m ted set of 11 symbo s and the numbers from 0 to 99 (any number greater than 99 d sp ays as “99+”) In the current vers on of W ndows. not on y can you tap them to start the app. w th app t es reflect ng current content The second tem s badges Badges are sma cons that d sp ay not ficat ons n the owerr ght corner of a t e. n the pane on the eft. c ck Sp ash Screen and then type the name of the mage fi e nto the text box Rebu d and run the app. or an ema app cou d show how many new messages have arr ved Programs can update the r own t es. but they can a so d sp ay “ ve” content when the app sn’t runn ng For examp e. n the man fest Ed tor. just ke ord nary desktop cons. n W ndows 8. but they are most usefu because they can be updated by background processes even when the app sn’t runn ng Th s means that the Start screen s now a dynam c env ronment. there are two features that are worth ment on ng n pass ng The first s updat ng In a more trad t ona operat ng system. you can’t define your own badges As w th content. you shou d see the sp ash screen appear before the ca cu ator nterface opens Updates and badges A though we don’t have the space here to de ve nto everyth ng that you can do w th t es. M crosoft ntroduced the concept of Live tiles W th L ve t es. app badges can be updated by background processes Chapter 21  More about W ndows Store apps   415 . because you ke y wou dn’t want t to f your ogo nc udes the app name The sp ash screen s d sp ayed wh e the app s start ng up It cons sts of an mage 620x300 p xe s that s d sp ayed on a co ored background Aga n. program cons are norma y stat c However. and that the name of the app has been added to the t e You can contro whether th s name s d sp ayed.You can see that the custom ogo appears a ongs de the t es of other apps.

.

.

from the top downward. or hexadec ma Ensure that on y the appropr ate number buttons are enab ed In other words. when n b nary mode. and n hexadec ma mode the “A” through “F” keys are ava ab e. n dec ma mode “0” through “9” are enab ed. Add three buttons next to the ar thmet c operat on keys and under the “E” key Labe them “dec”. }.xaml. on y the “0” and “1” keys are enab ed.h Base base. Add a data member to the MainPage c ass to ho d the current base. BIN }. 2. You need a way to store the base that has been chosen L ke the ar thmet c operat on. 418  Microsoft Visual C++/CLI Step by Step . and n t a ze t to dec ma n the Reset funct on // In MainPage. as we ■ Convert the str ng n the d sp ay to appear n the correct form ■ Change the sma TextBlock to d sp ay wh ch base s be ng used The fo ow ng exerc se shows you how to mp ement th s og c 1. so add a TextBlock to the r ght of the ma n d sp ay G ve t a name (such as txtBase) and set ts font s ze to about 24 5. and you can change the co or to make them stand out Refer back to the first figure n th s chapter to see what the arrangement ooks ke 4. and “b n”. dec ma . “hex”.. you are choos ng from a sma set of va ues. so another enum s appropr ate Open Ma nPage xam h and add an enum w th n the namespace namespace ProgCalc { enum class Base { DEC. and g ve them the names btnDecimal. You’ need to a way to determ ne wh ch base you’re us ng. and add a hand er ca ed BaseButtons Click to a three buttons Changing the base Add ng the og c for chang ng the number base requ res carefu cons derat on Here’s what you need to do whenever the user c cks one of the base buttons ■ ■ Set the base to the appropr ate va ue b nary. HEX. btnHex and btnBinary You’ need to decrease the font s ze for the text to fit on the buttons. Open the Propert es ed tor.3.. .

} } You can see how each of the cases sets the base var ab e and d sp ays the current base n the TextBlock The comments about enab ng buttons are there as p aceho ders. txtBase->Text = "bin". } else if (btn == btnBinary) { // Enable the binary buttons base = Base::BIN. Ed t BaseButtons Click and add the out ne of the og c void ProgCalc::MainPage::BaseButtons_Click(Platform::Object^ sender. Windows::UI::Xaml::RoutedEventArgs^ e) { // Get the button that was pressed Button ^btn = (Button^)sender. base = Base::DEC.// In MainPage. void EnableDecimalButtons(bool enable). because th s s another examp e of code that s best prov ded as separate funct ons 4. leftOperand = 0. if (btn == btnDecimal) { // Enable the decimal buttons base = Base::DEC. } else if (btn == btnHex) { // Enable the hex buttons base = Base::HEX.xaml. void EnableBinaryButtons(). Add three new members to the MainPage c ass dec arat on n Ma nPage xam h void EnableHexButtons(bool enable).cpp void ProgCalc::MainPage::Reset() { currentOp = ArithOp::NONE. txtBase->Text = "hex". txtBase->Text = "dec". clearOnNextKey = true. Not ce the s ght y d fferent form of the b nary funct on I’ve added the Boo ean argument to the dec ma and hexadec ma funct ons to he p avo d code dup cat on Chapter 21  More about W ndows Store apps   419 . } 3.

btnHexC->IsEnabled = enable. } 420  Microsoft Visual C++/CLI Step by Step . btnTwo->IsEnabled = enable. btnZero->IsEnabled = true. btnEight->IsEnabled = enable. btnThree->IsEnabled = enable.5. EnableDecimalButtons(false). btnOne->IsEnabled = enable. btnHexF->IsEnabled = enable. btnHexD->IsEnabled = enable. btnFour->IsEnabled = enable. Ca them from the base hand er For the b nary case. } void ProgCalc::MainPage::EnableBinaryButtons() { EnableHexButtons(false). and for the hexadec ma case. btnSix->IsEnabled = enable. base = Base::DEC. txtBase->Text = "dec". so the eas est so ut on s to d sab e everyth ng and turn on the ones you want 6. btnSeven->IsEnabled = enable. ca both the dec ma and hex funct ons w th true as the argument if (btn == btnDecimal) { // Enable the decimal buttons EnableDecimalButtons(true). respect ve y The b nary funct on on y wants the 0 and 1 keys. btnFive->IsEnabled = enable. btnHexE->IsEnabled = enable. btnOne->IsEnabled = true. Imp ement the fo ow ng funct ons n Ma nPage xam cpp void ProgCalc::MainPage::EnableHexButtons(bool enable) { btnHexA->IsEnabled = enable. } The dec ma and hexadec ma funct ons enab e or d sab e the 0 through 9 and A through F keys. } void ProgCalc::MainPage::EnableDecimalButtons(bool enable) { btnZero->IsEnabled = enable. EnableHexButtons(false). btnHexB->IsEnabled = enable. ca EnableDecimalButtons(true) and EnableHexButtons(false). btnNine->IsEnabled = enable. just ca EnableBinaryButtons For the dec ma case.

else if (btn == btnHex) { // Enable the hex buttons EnableDecimalButtons(true). txtBase->Text = "hex". txtBase->Text = "bin". us ng the new number base. accord ng to wh ch button was pressed ■ Convert the va ue to a str ng. txtBase->Text = "dec". us ng the current number base ■ Change the base. EnableHexButtons(false). you can use the buttons to change the number base. } else if (btn == btnBinary) { // Enable the binary buttons EnableBinaryButtons(). and put t back n the d sp ay The first step s to mod fy the ConvertTextToInt funct on that you wrote ear er so that t takes account of the number base Convert ng from dec ma and hexadec ma str ngs can be done by swscanf s. clearOnNextKey = true. EnableDecimalButtons(true). base = Base::BIN. Add the defau t state to the Reset funct on so that t w be reset to dec ma void ProgCalc::MainPage::Reset() { currentOp = ArithOp::NONE. leftOperand = 0. EnableHexButtons(true). } 7. base = Base::HEX. base = Base::DEC. wh ch means the page w n t a ze proper y 9. Bu d the app to ensure there are no cod ng errors Converting the string in the display At th s po nt. but t sn’t affect ng the va ue shown on the d sp ay You need to mp ement the base hand er so that t works ke th s ■ Get the str ng from the d sp ay and convert t to a va ue. but you need to do b nary yourse f Chapter 21  More about W ndows Store apps   421 . Ca Reset from the OnNavigatedTo funct on. } 8.

1. &n). t w then pass you back a po nter to that character. &n). Ed t the ConvertTextToInt funct on so that t ooks ke the fo ow ng examp e Not ce how t s now a member of the MainPage c ass so that t has access to members of the c ass int ProgCalc::MainPage::ConvertTextToInt(Platform::String^ s) { int n. else if (base == Base::DEC) swscanf_s(s->Data(). wh ch w cope w th nput str ngs n b nary Here s where you see a good examp e of the many str ng convers ons that you m ght need to use n W ndows programm ng the Data funct on gets a wstring out of the Platform::String. Add the mp ementat on to the Ma nPage xam cpp fi e unsigned long ProgCalc::FromBinary(std::wstring s) { wchar_t *stop. long l = wcstol(s. but we must st supp y a var ab e 422  Microsoft Visual C++/CLI Step by Step . } Th s funct on uses the wcstol (W de Character Str ng To Long) funct on for the convers on. we don’t need to use that argument. return l. L"%d". 2). and the c str funct on then gets a wchar t* that represents the content of the wstring Not ce the second argument to the funct on Th s returns a po nter to where the number stopped n the str ng that you passed n The dea s that the funct on w convert as much of the str ng as t can to a number and then stop when t reaches a character t can’t hand e. else if (base == Base::BIN) n = FromBinary(s->Data()). &stop. return n. 3. so you can p npo nt where pars ng stopped Because we know that the ent re str ng s va d. Add a prototype for the FromBinary funct on to Ma nPage xam h Because th s s a ut ty funct on and doesn’t need access to any members of the MainPage c ass.c_str(). you don’t have to make t a member unsigned long FromBinary(std::wstring s). if (base == Base::HEX) swscanf_s(s->Data(). L"%x". } The %x descr ptor converts a hexadec ma str ng. and %d hand es the dec ma case You w prov de your own funct on to dea w th the b nary convers on 2.

Add the mp ementat on to Ma nPage xam cpp String^ ProgCalc::ToBinary(int n) { String ^s = ref new String(). 5. b t by b t. return s. else if (base == Base::BIN) { String ^bf = ToBinary(val). std::reverse( result.end() ). such as shown n the fo ow ng Platform::String^ ConvertOutputString(int val). else if (base == Base::DEC) swprintf(buff. L"%x". do { s += (n & 1) ? L'1' : L'0'.c_str()). } You can see that the structure of th s funct on now m rrors that of ConvertTextToInt It a so uses another he per funct on ca ed ToBinary to convert a va ue to a b nary str ng 6. wh ch s not someth ng you have to do very often. add ng a “1” or “0” character to a str ng. } return ref new String(buff). } while (n >>= 1). return bf. s = ref new String(result. 7. tak ng a va ue and convert ng t to a str ng n the correct format Add a prototype for th s funct on to the header fi e.begin(). 80. val). Add the prototype for ToBinary to Ma nPage xam h String^ ToBinary(int n). You now need to do the oppos te convers on. so t s worth tak ng the opportun ty to use them here The do oop exam nes the code. L"%d". std::wstring result(s->Data()). result.4. if (base == Base::HEX) swprintf(buff. } Th s funct on g ves you a chance to use the b tw se operators. 80. depend ng on whether the b t s set or not The express on (n & 1) does a b tw se AND of the va ue and 1 Remember Chapter 21  More about W ndows Store apps   423 . Add an mp ementat on of the ConvertOutputString funct on to the source code fi e Platform::String^ ProgCalc::MainPage::ConvertOutputString(int val) { wchar_t buff[80]. val).

After chang ng the base. if (txtOutput->Text->Length() > 0) val = ConvertTextToInt(txtOutput->Text). however. so the oop w term nate At th s po nt. th s s check ng whether the owest b t s set The oop cond t on (n >>= 1) does a r ght-sh ft on the va ue by one pos t on Th s sh fts a the b ts one p ace to the r ght. it would be easy to generate a number that would overflow the space in the TextBlock. put the va ue back n the new format // Update the display txtOutput->Text = ConvertOutputString(val). so you can use that. the str ng s n the wrong order because the character represent ng the owest b t s the first. so that b t 2 becomes b t 1. if (txtOutput->Text->Length() > 0) val = ConvertTextToInt(txtOutput->Text). but the Standard L brary has a usefu reverse funct on. Here s the comp ete hand er. as here // Get the value from the display int val = 0. In particular. 424  Microsoft Visual C++/CLI Step by Step ustrated . nstead Note  The way binary conversion is handled here is limited. the number w be eft as a zeros. you need to reverse the str ng. clearOnNextKey = true. for reference void ProgCalc::MainPage::BaseButtons_Click(Platform::Object^ sender. os ng the r ghtmost b t. Windows::UI::Xaml::RoutedEventArgs^ e) { // Get the value from the display int val = 0. return ng 1 f (and on y f) both are set Because “1” on y has a s ng e 1 n the owest b t pos t on. 8. and the others have been added on So. // Get the button that was pressed Button ^btn = (Button^)sender. 9. because binary representations are much longer than their decimal or hexadecimal equivalent. The fina stage s to comp ete the og c for chang ng base and updat ng the d sp ay Add code to the start of the BaseButtons Click hand er to get the number from the d sp ay. you cou d do th s by us ng a oop. and a zero s ntroduced on the far eft to fi n After the oop has exam ned a the b ts.that the AND takes two nteger va ues for each b t pos t on.

n the weather app you m ght want to sw tch from Fahrenhe t to Ce s us. or v ce versa Hav ng these on the ma n UI wou d c utter th ngs up. } else if (btn == btnBinary) { EnableBinaryButtons(). commands. 11. txtBase->Text = "dec". } 10. base = Base::HEX. wh ch shou d ook ke th s wchar_t buff[80]. EnableHexButtons(true). so there s a need for a way to expose these to the user. EnableHexButtons(false).if (btn == btnDecimal) { EnableDecimalButtons(true). txtOutput->Text = ref new String(buff). and test t thorough y! Using app bars The W ndows Store UI mode doesn’t support menus or d a og boxes The dea s that the des gn shou d make t easy for the user to nav gate h s way through the app by us ng the contro s on the page rather than hav ng to pu down menus and use d a og boxes. as needed W ndows Store apps use app bars to present nav gat on. clearOnNextKey = true. } else if (btn == btnHex) { EnableDecimalButtons(true). however. txtBase->Text = "bin". Rep ace them w th the fo ow ng code txtOutput->Text = ConvertToOutputString(result). txtBase->Text = "hex". swprintf(buff. result). and too s to users Chapter 21  More about W ndows Store apps   425 . } // Update the display txtOutput->Text = ConvertOutputString(val). wh ch cou d be awkward on a touch dev ce There are t mes. L"%d". base = Base::BIN. Bu d and run the app. when users need to adjust sett ngs or express preferences For examp e. clearOnNextKey = true. 80. base = Base::DEC. Ed t the EqualsButton Click funct on so that the output w be converted to the r ght base Locate the nes at the end of the funct on that use swprintf and p ace the resu t nto a buffer.

and th s s prov ded by a set of sty es Before add ng the app bar to your app. fonts. g v ng you an a ternat ve way to change the number base Here s what the app w ook ke w th the app bar d sp ayed Defining the button styles The buttons on an app bar are usua y round. and one at the bottom. wh ch work n a s m ar way to how CSS does n HTML A deve oper or des gner can define a sty e for buttons that estab shes the bas c appearance. and other propert es Th s sty e can then be app ed across the app. and prevents dup cat on n the XAML A W ndows Store project comes w th a fi e ca ed StandardSty es xam . nc ud ng co ors. and a form of nher tance means that adjustments can be made Do ng th s makes t poss b e for sty es to be shared across pages and even across app cat ons. borders. you need to ed t the sty es so that they w d sp ay correct y Styles One of the secrets to des gn ng great W ndows Store apps s to use a coherent and cons stent v sua sty e throughout Th s s done n XAML through the bera use of sty es. wh ch s used for commands In th s sect on. wh ch s typ ca y used for nav gat on. you’ add a bottom app bar to the ca cu ator. wh ch w ho d three buttons. wh ch defines a base set of sty es for W ndows Store apps You shou d use these when you can so that your apps b end w th the W ndows Store ook and fee 426  Microsoft Visual C++/CLI Step by Step .These are areas that appear when the user sw pes from top or bottom of the screen (or by r ghtc ck ng or typ ng Ctr +Z) They are not ntended to ho d cr t ca commands the dea s that anyth ng cr t ca ( ke the “take a p cture” command for a camera app) ought to be n the ma n UI App cat ons can have two app bars one at the top of the screen.

Name" Value="Bin"/> <Setter Property="Content" Value="b"/> </Style> 4.Name" Value="Hex"/> <Setter Property="Content" Value="h"/> </Style> Th s creates a sty e for the Hex button. Open StandardSty es xam . remove the comments.Name" Value="Dec"/> <Setter Property="Content" Value="d"/> </Style> <Style x:Key="BinAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}"> <Setter Property="AutomationProperties.AutomationId" Value="BinAppBarButton"/> <Setter Property="AutomationProperties. and then ed t t so that t ooks ke th s <Style x:Key="HexAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}"> <Setter Property="AutomationProperties. Copy one of the sty e entr es.AutomationId" Value="HexAppBarButton"/> <Setter Property="AutomationProperties. wh ch s based on the defau t AppBarButton sty e and whose content s an “h” The Name s the text that w be d sp ayed be ow the button when t appears on the app bar 3.1.BottomAppBar> Chapter 21  More about W ndows Store apps   427 . Add th s XAML to the bottom of the Page e ement.BottomAppBar> <AppBar x:Name="bottomAppBar" Padding="10. and search for Standard AppBarButton Styles Th s s fo owed by a ot of commented out entr es wh ch define sty es for var ous buttons 2. you can add the app bar 1. 0"> <StackPanel Orientation="Horizontal" HorizontalAlignment="Left"> <Button x:Name="btnAppBarDec" Style="{StaticResource DecAppBarButtonStyle}" Click="BaseButtons_Click"/> <Button x:Name="btnAppBarHex" Style="{StaticResource HexAppBarButtonStyle}" Click="BaseButtons_Click"/> <Button x:Name="btnAppBarBin" Style="{StaticResource BinAppBarButtonStyle}" Click="BaseButtons_Click"/> </StackPanel> </AppBar> </Page. Save the StandardSty es xam fi e Adding an app bar Now that you have set up the sty es for the three buttons. Repeat the prev ous step to create sty es for the dec ma and b nary buttons <Style x:Key="DecAppBarButtonStyle" TargetType="ButtonBase" BasedOn="{StaticResource AppBarButtonStyle}"> <Setter Property="AutomationProperties. mmed ate y after the end of the Grid <Page. 0 10.AutomationId" Value="DecAppBarButton"/> <Setter Property="AutomationProperties.

n th s case arranged hor zonta y and eft-a gned L ke menus. t’s a s mp e matter to ed t the base buttons hand er so that t reacts proper y to the app bar buttons 1. and by us ng the W ndows operat ng system as an ntermed ary. Bu d and run the app You can now change the base by us ng the app bar Adding sharing For the fina task n th s chapter. choos ng the Share charm wh e n an app w d sp ay a app cat ons that have regstered themse ves as targets for shar ng Th s means that you can send data from your app to any of the shar ng targets w thout the two part es hav ng pr or know edge of one another W ndows 8 defines the fo ow ng s x contracts ■ Search  The app s search enab ed 428  Microsoft Visual C++/CLI Step by Step . r ght-c ck w th the mouse or sw pe upward from the bottom of the screen You shou d see the app bar appear C ck or touch anywhere e se on the screen (or sw pe downward). but t doesn’t do anyth ng Fortunate y. but t ustrates an mportant feature of W ndows Store apps Contracts and charms App cat ons can commun cate and share data by us ng contracts W ndows Store apps use contracts to dec are the nteract ons that they support w th other app cat ons These contracts are defined by W ndows RT. apps can commun cate w thout know ng anyth ng about one another For examp e.The BottomAppBar e ement conta ns an AppBar. because you’re on y go ng to be ab e to share the va ue n the d sp ay. you’re go ng to add another feature to the ca cu ator the ab ty to share data w th other app cat ons Th s sn’t go ng to be very soph st cated. and any buttons for he p shou d be r ght-a gned on the other s de of AppBar Each button has the appropr ate sty e set and s nked to the base buttons c ck hand er 2. and t w s de away Hooking it up You now have an app bar that you can d sp ay and h de. Ed t the code n the BaseButtons Click funct on so that t accepts both the button on the screen and the app bar buttons if (btn == btnHexBase || btn == btnAppBarHex) 2. t s a convent on that commands on a bottom app bar shou d be eft-a gned. wh ch n turn conta ns a StackPanel A StackPanel s a conta ner that conta ns a stack of tems. Bu d and run the app When the UI appears.

■ Share  The app can share content w th other app cat ons or s ready to accept spec fic types of data from other app cat ons ■ Settings  Imp ements a standard way of defin ng app sett ngs ■ Play To  The app can stream aud o. and mages to enab ed dev ces ■ File Picker  The app s used as a ocat on for sav ng and oad ng fi es ■ Cached File Updater  The app can track fi e updates and de ver the atest vers on to the user Charms are a spec fic and cons stent set of buttons that you can access n every app The charms are Search. and search your app’s content from another app ■ Share content from your app w th peop e or serv ces ■ Go d rect y to the Start screen ■ Connect to dev ces and send content. Sett ngs. stream med a. nc ud ng the fo ow ng ■ P a n text ■ Formatted text ■ HTML ■ URIs ■ B tmaps ■ F es ■ Deve oper-defined data Chapter 21  More about W ndows Store apps   429 . v deo. or press W ndows key+C These buttons prov de the fo ow ng set of core act ons that users frequent y need ■ Search for content ocated n your app or n another app. ett ng them share data w th other apps n a var ety of formats. and pr nt ■ Configure the app As you can apprec ate. move the mouse po nter to the upper-r ght or owereft of the screen. Connect. mp ement ng contracts and us ng the charms makes your app a fu member of the W ndows Store commun ty Implementing sharing Shar ng s one of the common contracts supported by apps. Share. and Start They appear on the r ght s de of the screen when you sw pe nward from the r ght edge of the screen.

.

.

and then prov de the funct on that the de egate w ca n th s case. because you on y need t when mp ement ng a mu t page app In that case. wh ch uses gener cs to create a de egate that w ca a hand er funct on You use the ang e brackets to spec fy the two argument types that the hand er w use. Set up the DataTransferManager so that shar ng s act ve for the app Start by add ng a new pr vate member to the MainPage c ass. you shou d see the t t e and descr pt on you prov ded. as shown here Windows::Foundation::EventRegistrationToken dataRequestedToken. DataRequestedEventArgs^>(this. and you’d use the token to te the Data TransferManager that you no onger want th s page to rece ve share events There s. wh ch s the second from the top After a few seconds n t a zat on. as demonstrated n th s screen shot 432  Microsoft Visual C++/CLI Step by Step . p ac ng t before the ca to Reset DataTransferManager ^dataTransferManager = DataTransferManager::GetForCurrentView(). Not ce the rather compressed form of the second statement You create a new TypedEvent Handler. Bu d and run the app and put a number n the d sp ay Then. together w th a st of the app cat ons that can accept the data. Add the fo ow ng code to the OnNavigatedTo funct on to reg ster for share events. no harm n nc ud ng t. however. se ect the Share charm. Th s object s returned to you when you reg ster your event hand er w th the DataTransfer Manager It sn’t str ct y necessary to nc ude t here. and t w serve to rem nd you of what to do when you move on to mu t page app cat ons 6. &MainPage::ShareTextHandler). and th s returns the token that you can use to unreg ster when nav gat ng away from the page 7. dataRequestedToken = dataTransferManager->DataRequested += ref new TypedEventHandler<DataTransferManager^.5. wh ch s ca ed when you move to another page. you w mp ement the OnNavigatedFrom funct on. t s the ShareTextHandler funct on on “th s” object The de egate s hooked to the DataRequested event on the DataTransferManager.

mp ement the shar ng contract. Then. XOR. and nk the r click events to a su tab e hand er. on y the Ma app s ab e to accept shared text data Where next? I’ve run out of space n th s chapter. use the DataTransferManager to make shar ng ava ab e for that page.You can see that the t t e for the data. OR. and put the stored va ue nto the d sp ay (MR) Add a change s gn button (+/–) that changes the s gn of the va ue n the d sp ay Imp ement some more programmer funct ona ty. such as b tw se operat ons (AND. Add a hand er for a DataRequestedEvent and put the data nto a DataPackage. Then. subtract the current y d sp ayed va ue from t (M–). and NOT) and eft and r ght sh ft Add a h story mechan sm so that you can see what you’ve done up to now Quick reference To Do This Add an app bar to ho d command buttons F rst create sty es for the buttons n StandardSty es. s shown so that users can dec de what they want to do w th the data On the system I’m us ng. there are severa ways n wh ch you cou d enhance the ca cu ator. xam . Chapter 21  More about W ndows Store apps   433 . Add a BottomAppBar to the XAML. bu d ng on what you’ve earned Here are some suggest ons ■ ■ ■ ■ Add the typ ca ca cu ator “memory” funct ona ty The ca cu ator keeps a memory var ab e. a ong w th a descr pt on f you supp ed one. and four buttons et you set t to zero (MC). add a StackPanel conta n ng the buttons. but now that you have seen how to bu d a more comp ex W ndows Store app. add the current y d sp ayed va ue to t (M+).

.

PAR T IV Advanced topics CHAPTER 22 Work ng w th unmanaged code 437 CHAPTER 23 Attr butes and reflect on 453 CHAPTER 24 L v ng w th COM 475 435 .

.

” cons ders cons ders nteroperat ng between the Component Object Mode (COM) and NET Managed vs.. I’ ntroduce one feature of the namespace—the P atform Invoke mechan sm for ca ng unmanaged funct ons w th n DLLs We a so nvest gate some of the other ssues that surround nteract ng w th unmanaged code Chapter 24. . unmanaged code Code and data that ve n the NET wor d are ca ed managed because ocat ons and fet mes are managed by the Common Language Runt me (CLR) Code and data that ex st outs de of NET are ca ed unmanaged. you w be ab e to ■ Exp a n the ssues that affect managed and unmanaged code ■ Use managed objects n unmanaged code ■ Use the P atform Invoke mechan sm to ca unmanaged funct ons n DLLs A though the pr mary focus of th s book s us ng C++/CLI w th the M crosoft NET Framework. because there s no centra mechan sm for manag ng the r fet mes Somet mes you have to m x the two.. “L v ng w th COM. ca ng ex st ng unmanaged code from w th n NET Th s sect on ntroduces some of the ssues and techn ques that you’ need to cons der n th s s tuat on Mixed classes A though managed c asses are norma y composed of other managed types. at t mes you’ have to ca funct ons outs de the NET env ronment T he System::Runtime::InteropServices namespace conta ns c asses and structures to he p w th nteroperat on between NET and the outs de wor d In th s chapter.CHAPTER 22 Working with unmanaged code After comp et ng th s chapter. }. as n th s examp e ref class ManagedClass { UnmanagedClass *puc. 437 . t s poss b e to m x managed and unmanaged types as members of c asses under some c rcumstances It s a so poss b e to have a po nter to an unmanaged object as a member of a managed c ass.

Not ce the use of the aster sk (*) rather than the caret (^) th s s a po nter to an unmanaged type.. or when delete s ca ed on a po nter Managed objects don’t work n th s way.. Create a GCHandle to refer to your object GCHandles can be converted to and from ntegers for ease of pass ng them between funct ons 438  Microsoft Visual C++/CLI Step by Step . at the end of the process for a g oba var ab e. . }. so t’s poss b e to arrange for correct object dea ocat on n most c rcumstances You can’t have an unmanaged object as a member of a managed c ass. Because the unmanaged object doesn’t ex st n the NET wor d. you can dec are destructors for managed c asses and use delete on objects of managed types. ustrated n the // C4368: mixed types are not supported An unmanaged object w on y work as a c ass member f the host object s exp c t y de eted at some po nt at the end of the enc os ng b ock for an automat c var ab e. the garbage co ector doesn’t know who has a reference to the object or when t can be co ected The GCHandle type There s a way to use a managed type as part of an unmanaged c ass by us ng the GCHandle type prov ded n the System::Runtime::InteropServices namespace GCHandle asks the runt me to g ve you a “hand e” to refer to a managed object from unmanaged code You use the GCHandle::Alloc stat c method to create the hand e.. t’s up to you to manage the fet me of the object at the other end of the po nter You shou d hand e th s carefu y unmanaged objects somet mes need exp c t de et on at a part cu ar po nt n the code. and the garbage co ector can’t co ect an unmanaged object It’s mposs b e to have a hand e to a managed type as part of an unmanaged c ass. the hand e to the conta ned object s nv s b e to the garbage co ector Thus.. // C3265: cannot declare a managed 'obj' // in an unmanaged 'UnmanagedClass' . and th s m ght not fit we w th the NET garbage co ect on mode However. such as s fo ow ng ref class ManagedClass { UnmanagedClass obj. }. not a hand e Because the member s unmanaged. and the hand e’s Free method to re ease t aga n Here’s how you’d use GCHandle f you wanted to pass a po nter to a managed object to unmanaged code 1. as shown here class UnmanagedClass { ManagedClass ^obj.

Pass the GCHandle to the unmanaged code As ong as the hand e hasn’t been freed.2. M crosoft prov des a he per temp ate c ass ca ed gcroot The fo ow ng exerc se shows you how to use gcroot to nc ude a po nter to a managed type as part of an unmanaged c ass 1. Ca Free on the hand e when the unmanaged code no onger needs t At th s po nt. Add the defin t on of an unmanaged c ass class UClass { public: gcroot<MClass^> mc. Add a using d rect ve to the top of the code to make t eas er to use the System::Runtime::Interop Services namespace using namespace System::Runtime::InteropServices.h> Th s system header fi e defines the gcroot he per c ass 3. Add the defin t on of a s mp e managed c ass to the code ref class MClass { public: int val. Th s c ass s mp y wraps an nteger. Start M crosoft V sua Stud o 2012 and create a new CLR Conso e App cat on project named Manage 2. UClass(gcroot<MClass^> pmc) : mc(pmc) { } int getValue() { return mc->val. Chapter 22  Work ng w th unmanaged code   439 . the runt me won’t co ect the object 3. 4. } }. MClass(int n) : val(n) { } }. whose va ue s set n the constructor 5. the run- t me s free to co ect the object f no one e se s us ng t To he p you use GCHandles w th n unmanaged code w thout your hav ng to get nto the deta s of us ng Alloc and Free. Add an #include d rect ve for the gcroot h system header fi e just be ow the stdafx h include d rect ve #include <gcroot.

getValue()). Mod fy the main funct on to use the c asses int main(array<String^>^ args) { Console::WriteLine("Testing. and shows you how they’re used n code 440  Microsoft Visual C++/CLI Step by Step . so you can ver fy that the code rea y ets you access a managed object from an unmanaged context 6. pinning and boxing. } The code first creates a managed object and n t a zes t w th an nteger The po nter to th s object s then used to n t a ze an unmanaged object. the gcroot s destroyed. and the getValue funct on s used to extract the va ue from the managed object before pr nt ng t out When the UClass object goes out of scope. 7. and t s freed when the gcroot object s destroyed A UClass object s passed a hand e to a managed MClass object when t s created. n turn. wh ch frees the GCHandle and.h>) will call the destructor on the object when the gcroot goes out of scope. Console::WriteLine("Value is {0}". frees up the managed object Tip  If the managed type that you want to use with gcroot has a destructor. return 0.. and th s hand e s stored away n the gcroot object The getValue funct on s mp y returns the pub c val member from the MClass object by va ue."). Bu d and run the app cat on Pinning and boxing Th s sect on d scusses two C++/CLI concepts. // Create an unmanaged object UClass uc(pm). uc. // Create a managed object MClass ^pm = gcnew MClass(3).. using the auto gcroot type (declared in <auto gcroot.The defin t on of the mc var ab e s an examp e of us ng a temp ate c ass The defin t on effect ve y creates a gcroot var ab e that wraps a GCHandle to an MClass po nter The GCHandle s created when the gcroot object s created.

and p nn ng a member of a managed object resu ts n the ent re object be ng p nned For examp e. et’s br efly d scuss interior pointers We w do th s by ook ng at a scenar o n wh ch you have a managed object. } Chapter 22  Work ng w th unmanaged code   441 . but the va ue of the po nter cannot be changed.Interior pointers Before gett ng to p nn ng. p nn ng the first e ement of an array w resu t n the ent re array be ng p nned The object w rema n p nned unt there are no references eft to the p nn ng po nter The code fragment that fo ows shows the creat on and use of a p nn ng po nter F rst. you don’t want the CLR to move the object around n memory wh e the object s be ng used by the unmanaged code A pinning pointer s a po nter to a managed object. the comp er w g ve you an error f you try to use an ord nary po nter w th a managed object An interior pointer s a po nter whose address w be updated f the object to wh ch t refers s moved They are ca ed “ nter or” po nters because you use them to po nt to a member w th n a managed object Note  You can’t use an interior pointer to point to a “whole” managed object. because the address he d n the po nter cou d end up po nt ng to the wrong p ace f the garbage co ector moves the object In fact. Pinning pointers The CLR assumes that t can move objects around n the managed heap whenever t wants At t mes. creat ng a p nn ng po nter to an object g ves you a po nter that can safe y be passed out to unmanaged code because you can be sure that the address s go ng to rema n va d You can use p nn ng on a or part of a managed object. f you want to pass a po nter to a managed object to an unmanaged funct on. you can only point to a field within an object. assume that we have an unmanaged funct on that takes a po nter to an nteger void someFunc(int *p) { // Do something with the integer value… int n = *p. and you want to pass t to an unmanaged funct on that requ res a po nter You probab y know that the garbage co ector can (and does) move objects around on the managed heap to max m ze free space Th s means that you can’t use an unmanaged po nter to refer to a managed object. however. you m ght need to te the CLR to eave objects where they are For examp e. wh ch means that the garbage co ector cannot move t around n memory Thus.

ass gnng nullptr to the p nn ng po nter frees the array object so that t can be moved Boxing and unboxing Boxing and unboxing. 442  Microsoft Visual C++/CLI Step by Step . foo).Here s how we cou d use th s w th a managed array // Create a managed array of int array<int> ^arr = gcnew array<int>(5). un ke references. and that s ess than about 16 bytes n s ze s a good cand date for mak ng a va ue type Because va ue types aren’t accessed v a references. “Va ue types.” covers va ue types n deta and teaches that they are fundamenta y d fferent from reference types To recap. and that '&' is used to take the address of the object pin_ptr<MyClass> pin = &arr[0]. cons der the over oad of the Console::WriteLine funct on that performs formatted output. wh ch are stored on the run-t me heap Instances of va ue types are a ways accessed d rect y. make t poss b e for va ue types to be treated as objects Chapter 9. whose prototype s shown here static void WriteLine(String^. confident that the int won’t be moved around n memory Observe how there s an mp c t convers on between pin ptr<int> and int*. even though “12” s not an nstance of a reference type int foo = 12. you can’t d rect y spec fy a va ue type But. and the second s a hand e to any NET reference type Because va ue types aren’t accessed by references. such as a Boo ean or an nteger. The first String^ parameter s the format str ng. // Create a pinning pointer to the first element // Note there is no '^'. After the array e ement has been p nned. va ue types have three part cu ar propert es ■ ■ ■ Va ue types are stored on the stack. Console::WriteLine("foo is {0}". // Pass the integer member to an unmanaged function someFunc(pin). you can pass ts address to the unmanaged funct on. you w find that the fo ow ng works. un ke reference types. they can be far more effic ent than the equ va ent reference types but can’t be regarded as objects n the same way that reference types can Th s becomes a prob em when you want to use a va ue type n a context where an object reference s needed For examp e. so you don’t need to convert t yourse f When you’re fin shed. wh ch are accessed through references Th s means that you don’t use the new operator when creat ng nstances It a so means that va ue types are not garbage-co ected Copy ng va ue types cop es the va ue rather than the reference Anyth ng that wraps a s mp e va ue. Object^). wh ch w be d scussed n a moment. // Zero out the pinning pointer // The array is not pinned any more pin = nullptr.

} Chapter 22  Work ng w th unmanaged code   443 . obj). and the second ne stores t (stloc) nto a oca var ab e After the str ng tera s pushed onto the stack.1 box [mscorlib]System.i4.Console::WriteLine(string.Boxing Box ng wraps a va ue type n an object “box” so that t can be used where an object reference s needed In C++/CLI. Ed t the main funct on to create an nteger and box t int main(array<String^>^ args) { Console::WriteLine("Boxing Example"). b t by b t. return 0. object) The first ne pushes a tera 12 onto the stack. nto the managed object ■ The address of the managed object s returned Be aware that the managed object conta ns a copy of the va ue type Th s means that any mod ficat ons you m ght make to the managed wrapper don’t propagate back to the or g na va ue You can see th s happen ng f you ook at the generated code the IL d sassemb er too (ISDASM) The IL generated for the preced ng two nes of C++/CLI code ook someth ng ke th s IL_0002: IL_0004: IL_0005: IL_000a: IL_000b: IL_0010: ldc. wh ch generates an object to ho d the nteger before ca ng WriteLine Unboxing What f you want to retr eve the va ue from a boxed object? The fo ow ng br ef exerc se shows you how to get the va ue back out of a boxed object by us ng a cast 1. Create a new CLR Conso e App cat on project named Boxing 2.Int32 call void [mscorlib]System. // Use the boxed object Console::WriteLine("Value of foo is {0}".s 12 stloc.1 ldstr "Value is {0}" ldloc. // It will get boxed automatically Object ^obj = foo. // Create an int int foo = 12. th s wrapp ng s done automat ca y The fo ow ng three th ngs happen when an object s boxed ■ A managed object s created on the CLR heap ■ The va ue of the va ue type s cop ed. the ldloc nstruct on takes the oca var ab e and pushes t back onto the stack You can see that the next ne s a box nstruct on.

and what the funct on returns A mechan sm such as P/Invoke s necessary to fac tate commun cat on between managed and unmanaged code Take str ngs as an examp e A str ng n C++/CLI s a hand e to a String object. at t mes you’ need to use code that wasn’t wr tten for NET to accommodate s tuat ons such as the fo ow ng ■ ■ ■ You need to ca a M crosoft W ndows API funct on that doesn’t have a NET equ va ent You have some code n a Dynam c-L nk L brary (DLL) that or g nated outs de NET and can’t be rewr tten You have code that needs to be wr tten n a anguage that’s not yet supported by the NET Framework Whatever the reason. safe cast will throw an exception. you need to spec fy the name of the DLL conta nng the funct on. the name of the funct on. Console::WriteLine("fooTwo is {0}". a str ng sn’t represented by an object Instead. The safe cast checks to see whether a boxed int s on the other end of the obj po nter.3. fooTwo). Add the fo ow ng code to get the va ue back out of the box // Unbox the value int fooTwo = safe_cast<int>(obj). Like dynamic cast. If it is. Unlike dynamic cast. t returns an int Note The safe cast is explored in Chapter 3. the cast is performed and the value returned. a str ng s a po nter to a ser es of memory ocat ons that conta n characters and s term nated by a nu If you’re go ng to pass a str ng 444  Microsoft Visual C++/CLI Step by Step . but n standard C++.nvoke”) It s prov ded to et you ca funct ons n DLLs Us ng P/Invoke nvo ves add ng a prototype to your code that uses attr butes to nform NET about the funct on you’re propos ng to ca In part cu ar. what arguments the funct on takes. 4. pronounced “p. f t s. a safe cast is performed at run time. “Variables and operators.” but let’s take a moment to consider it here. Bu d and run the app cat on Using P/Invoke to call functions in the Win32 API A though t’s poss b e to do a great dea by us ng the funct ona ty prov ded n the NET Framework. so you need a way to pass funct on ca s nto and out of NET The mechan sm to do th s s ca ed P/Invoke (for P atform Invoke. It checks whether the type on the other end of the handle is of the right type. the code you’re ca ng ex sts outs de the NET-managed env ronment. which returns a null if the types don’t match.

you can dent fy a DLL funct on to P/Invoke by us ng th s ord na number When you ca W ndows API funct ons. t mers. menus. someth ng has to convert between the correspond ng managed and unmanaged data types Th s convers on process s ca ed marsha ng. standard M crosoft W ndows XP supports both the ASCII (one byte per character) and Un code (two bytes per character) character encod ngs Th s means that both ASCII and Un code vers ons of each funct on must ex st. respect ve y. dent fied by an “A” or a “W”. wh ch conta ns the GDI graph cs subsystem code How do you know wh ch DLL ho ds a part cu ar system funct on? If you ook the funct on up n the P atform SDK. t’s a standa one funct on and doesn’t requ re any sett ng up. the ASCII vers on w used be The fo ow ng exerc se shows you how to ca an unmanaged funct on n one of the W ndows system DLLs The obv ous cand date for th s exerc se s MessageBox for two reasons first. added to the end of the funct on name (for examp e. you can spec fy wh ch vers on of a funct on you want to use w th P/Invoke If you don’t exp c t y p ck one. the C++ comp er maps a ca to MessageBox onto the correct funct on depend ng on whether you’re us ng ASCII or Un code n your app cat on As you’ d scover n the exerc se ater n th s sect on. and commun cat ons Kerne 32 d . wh ch conta ns ow. second. you can a so have two or more vers ons of funct ons that take characters or str ngs as arguments because W ndows can support more than one character encod ng For examp e.data between managed and unmanaged code. wh ch conta ns funct ons for message hand ng. you can a so ass gn a funct on n a DLL a number that can be used to execute the funct on at run t me If you need to. you’ usua y find a c ue n the “Requ rements” sect on at the end of the top c For examp e.eve operat ng system funct ona ty for memory management and resource hand ng GDI32 d . t’s obv ous whether the ca has worked The MessageBox funct on—that s. MessageBoxW) A though you can ca the d fferent vers ons d rect y. the MessageBoxA and MessageBoxW funct ons—res de n the User32 d system DLL Three system DLLs conta n the unmanaged W ndows API code ■ ■ ■ User32 d . and t s one of the tasks that P/Invoke performs for you Identifying functions There are two po nts that you need to be aware of when dent fy ng funct ons to ca us ng P/Invoke A though you usua y dent fy a funct on n a DLL by name. the He p top c for MessageBox has the fo ow ng nes L brary User32 b DLL User32 d Chapter 22  Work ng w th unmanaged code   445 .

and (because th s s a funct on that uses characters or str ngs) an nd cat on of wh ch vers on to use CharSet::Auto eaves t up to the target p atform to dec de wh ch vers on to ca and how to convert the str ng arguments The first argument to MessageBox s a “hand e to the own ng w ndow ” Th s s a hand e n the or g na W n32 sense. and we’re not concerned about t here The rather strange cho ce of argument name (hwnd) comes from the or g na type. String ^caption. where the or g na funct on wou d requ re a W ndows LPTSTR type The P/Invoke marsha ng automat ca y converts the data when mak ng the ca The fina argument s the sty e of MessageBox. Start a new CLR Conso e App cat on project named Message 2. Most of the nterop features are part of the System::Run­time::InteropServices namespace. so it will be 32 bits on 32-bit Windows and 64 bits on 64-bit systems. CharSet=CharSet::Auto)] int MessageBox(IntPtr hwnd. and t’s much eas er to use f you dec are the namespace 3. Add the P/Invoke prototype for the MessageBox funct on before the main rout ne // Set up the import [DllImport("User32. wh ch just d sp ays an OK button 446  Microsoft Visual C++/CLI Step by Step .dll". HWND Note An IntPtr is an integer type large enough to hold a native pointer. It is commonly used in interop to pass pointers to and from unmanaged code. String ^text. Add a using d rect ve to the top of the project using namespace System::Runtime::InteropServices. you’ have to  nk w th a brary named User32 b.The first ne nd cates that f you want to use MessageBox n trad t ona C++ code. wh ch governs wh ch con and buttons t w d sp ay The defau t va ue s zero. There s qu te a ot to exp a n about these few nes of code The prototype for the Message Box funct on s dec ared by us ng the DllImport attr bute The two parameters passed to the attr bute are the name of the DLL n wh ch the funct on res des. and the second denotes that the code actua y res des n User32 d Now that you know where you can find the MessageBox funct on. unsigned int type). here’s the exerc se 1. Not ce how String hand es are used to pass str ng nformat on. and t s bas ca y a po nter Th s s used to estab sh the MessageBox as a ch d of another w ndow.

.

.

wh ch reports on the AC and battery status of the system The W ndows API defines a structure SYSTEM POWER STATUS. and hands back the fi ed structure. fi s t n. } SYSTEM_POWER_STATUS. BYTE Reserved1. pass ng over a structure. and then d sp ay the resu ts 1. Add the fo ow ng using d rect ve using namespace System::Runtime::InteropServices. BYTE BatteryLifePercent. DWORD BatteryLifeTime. DWORD BatteryFullLifeTime. // status The funct on takes a po nter to a SYSTEM POWER STATUS structure. BYTE BatteryFlag. wh ch conta ns the status nformat on The defin t on of th s unmanaged structure s shown here typedef struct _SYSTEM_POWER_STATUS { BYTE ACLineStatus. n wh ch members appear n unmanaged memory n the same order they appear n the managed defin t on The fo ow ng exerc se shows how to ca an unmanaged W ndows API funct on that needs to be passed a structure The funct on s GetSystemPowerStatus. and you must do th s carefu y In part cu ar. Create a new CLR Conso e App cat on project named PowerMonitor 2. The prototype for the GetSystemPowerStatus funct on n the API documentat on s th s BOOL GetSystemPowerStatus( LPSYSTEM_POWER_STATUS lpSystemPowerStatus ). you need to spec fy the way structures are a d out n memory to be sure that they are passed around correct y You spec fy the ayout of structures and c asses by us ng the StructLayoutAttribute and FieldOffsetAttribute c asses You add StructLayoutAttribute to managed types to define a formatted type w th a part cu ar ayout There are three poss b e ayout types that you can spec fy for a formatted type ■ ■ ■ Automat c ayout (LayoutKind::Auto). return ng a Boo ean va ue to et you know whether t worked Your task s to ca th s funct on. Th s makes t eas er to refer to the attr butes we’ be us ng ater Chapter 22  Work ng w th unmanaged code   449 . *LPSYSTEM_POWER_STATUS.Passing structures You’ often need to pass structured data to arguments to unmanaged funct ons. n wh ch the runt me m ght reorder the members f t s more effic ent You never use automat c ayout for types that are go ng to be used w th P/Invoke because you need to be sure that everyth ng stays n the same order Exp c t ayout (LayoutKind::Explicit). n wh ch members are ordered accord ng to byte offsets spec fied by FieldOffset attr butes on each fie d Sequent a ayout (LayoutKind::Sequential).

as ustrated n the fo ow ng int main(array<String^>^ args) { Console::WriteLine("Power Status Test. as shown here // Define the BOOL type typedef int BOOL. Console::WriteLine("Got status. return was {0}". System::UInt32 BatteryFullLifeTime. and DWORD. and LayoutKind::Sequential s spec fied so that the ayout of the members w rema n the same as the data s passed through P/Invoke 4. Add code to report on the members of the c ass 450  Microsoft Visual C++/CLI Step by Step . and so s represented by System::UInt32 The StructLayoutAttribute s attached to the c ass. System::Byte BatteryFlag. return 0.dll". and the s ng e argument s g ven as a hand e to our managed type 5. Define the prototype for the GetSystemPowerStatus funct on. PStat ^ps = gcnew PStat(). System::UInt32 BatteryLifeTime. }. Define a managed equ va ent for the structure [StructLayoutAttribute(LayoutKind::Sequential)] ref class PStat { public: System::Byte ACLineStatus. wh ch s a 32-b t uns gned nteger. b). BOOL s a W ndows type represent ng a Boo ean va ue and s actua y a typedef for an nteger It has been w de y used n the W ndows API because C acks a true Boo ean type The prototype uses the rea name of the funct on as t occurs n Kerne 32 d . wh ch represents a one-byte nteger. System::Byte Reserved1. System::Byte BatteryLifePercent. and so can be represented by the System::Byte type.. the return va ue shou d be nonzero."). Bu d and run the app cat on at th s po nt..3. } If the ca worked. // Prototype for the function [DllImport("Kernel32. correct ng any errors and check ng the output 7. wh ch represents a Boo ean true va ue 6. Our equ va ent of SYSTEM POWER STATUS s a managed c ass named PStat The or g na defin t on conta ns two W ndows data types BYTE. BOOL b = GetSystemPowerStatus(ps). CharSet=CharSet::Auto)] BOOL GetSystemPowerStatus(PStat ^ps). Wr te the code to ca the funct on Ed t the main funct on to create a PStat object and use t to ca the funct on.

or 255 (unknown) The second check s on the status of the battery. 1 (off). // How many seconds battery life is left? if (ps->BatteryLifeTime == -1) Console::WriteLine("Battery life in seconds: Unknown"). if (ps->BatteryFlag & 8) Console::Write(" 'charging'"). and the b tw se OR operator (&) s used to check wh ch b ts are set The fina two checks pr nt out the percentage of fet me eft n the battery and the number of seconds If the funct on can’t determ ne the number of seconds. if (ps->BatteryFlag & 4) Console::Write(" 'critical'"). and th s va ue can be made up of one or more of the va ues 1 (h gh charge). break. ps->BatteryLifePercent). and 128 (no battery present) Each of these represents a part cu ar b t pos t on w th n the resu t. The first check s on the ACLineStatus fie d. else Console::WriteLine("Battery seconds remaining: {0} secs". ps->BatteryFlag). else Console::WriteLine("Battery life is {0}%". wh ch w have the va ue 0 (on). Bu d and run the app cat on You w obv ous y ach eve the best resu ts f you run t on a aptop Chapter 22  Work ng w th unmanaged code   451 . break. case 255: Console::WriteLine("'unknown'"). 8 (chargng).// Report on the AC line status Console::Write("AC line power status is "). t w return –1 n th s fie d 8. if (ps->BatteryFlag & 1) Console::Write(" 'high'"). // What's the percentage charge left in the battery? // A value of 255 means unknown if (ps->BatteryLifePercent == 255) Console::WriteLine("Battery life unknown"). if (ps->BatteryFlag & 2) Console::Write(" 'low'"). Console::WriteLine(). 4 (cr t ca y ow charge). break. } // Report on the battery status Console::Write("Battery charge status is ({0})". if (ps->BatteryFlag & 128) Console::Write(" 'no system battery'"). ps->BatteryLifeTime). switch(ps->ACLineStatus) { case 0: Console::WriteLine("'off'"). case 1: Console::WriteLine("'on'"). 2 ( ow charge).

452  Microsoft Visual C++/CLI Step by Step Use the P/ nvoke mechan sm by dec ar ng a prototype for the un managed funct on that uses the DllImport attr bute to spec fy the DLL n wh ch the funct on res des and other opt ona parameters. Retr eve the va ue from a boxed object. Use the System::Runtime::InteropServices::GCHandle::Alloc func t on to wrap a po nter to a managed object n a GCHandle. F x a or part of a managed object n memory so that t can be used safe y by unmanaged code.Quick reference To Do this Obta n a safe hand e to a managed object so that t won t be garbage co ected wh e be ng used. The managed Foo object won t be moved n memory or garbage co ected unt the p nn ng po nter goes out of context or has nu ass gned to t. gcroot<Foo^> pf = ff. For examp e: pin_ptr<Foo> p = gcnew Foo(). Use pin ptr<> to create a p nn ng po nter. and hand es c eanup when the gcroot s destroyed. For examp e: int myVal = safe_cast<int>(po). Th s code wraps the po nter to the Foo object w th a GCHandle. and then dereference the po nter. Use safe cast to cast the box ng object to the correct type. Note that the va ue n the box s a copy of the or g na . For examp e: Foo ^ff = gcnew Foo(). Convert a va ue type to an object so that t can be used where an object s requ red. . The eas est way to do th s s to use the gcroot he per c ass. Th s w happen automat ca y. Ca an unmanaged funct on n a DLL.

you w T be ab e to ■ Descr be what attr butes are ■ Use attr butes to add metadata to managed types ■ Create your own attr bute types ■ Access attr bute metadata from code h s chapter ntroduces metadata and attr butes and shows you how to start defin ng and man puat ng metadata for your own NET types Metadata and attributes The concept of metadata s centra to the way the M crosoft NET Framework works. t s data that descr bes data) A ot of metadata conta ns nformat on that can’t be spec fied n the programm ng anguage. n W ndows a extra data has to be stored n the W ndows reg stry One of the ma n prob ems w th th s s ensur ng that the data n the reg stry doesn’t become corrupt or out of step w th the code Another major advantage of metadata s that t prov des a way to add vers on nformat on to the code so that you know wh ch vers on of a component you’re us ng Th s so ves a ot of prob ems that have p agued programmers s nce the ear y days of W ndows. and t offers a usefu —many peop e wou d say essent a —way to prov de a the extra nformat on needed by the NET runt me One of the major advantages of metadata s that t s stored a ong w th the code. so to be an effect ve NET programmer. t s a huge step forward 453 .CHAPTER 23 Attributes and reflection After comp et ng th s chapter. you need to know what t s and how to work w th t Metadata s data attached to NET data types that carr es nformat on about those types ( n a broader sense. so extra data doesn’t need to be stored separate y Trad t ona y.

t s s mp y here so that you can d sassemb e t to ook at the metadata 3. c ck Open. on the Too s menu. } }. world"). wh ch are spec a syntax e ements that can be attached to c asses and c ass members You’ see how to use attr butes ater n th s chapter You can see some of the metadata that the comp er attaches to your code f you use the IL d sassemb er too (ILDASM). and then type ildasm on the command ne 5. Bu d the app cat on to generate the executab e 4. Run ILDASM To do so. c ck V sua Stud o Command Prompt.The comp er a ways attaches metadata to the output code to descr be t. nav gate to the He o exe executab e. and the Common Language Runt me (CLR) uses the metadata to contro the oad ng and execut on of the code You can a so attach metadata to code by us ng attr butes. On the ILDASM F e menu. wh ch s nc uded w th the NET Framework SDK (You can find th s too n the \Program F es\M crosoft SDKs\W ndows\v8 0a\b n\NETFX4 0 Too s fo der ) Using ILDASM The fo ow ng examp e shows you how to use ILDASM to exam ne a s mp e app cat on 1. and then open t 454  Microsoft Visual C++/CLI Step by Step . The c ass doesn’t rea y have to do anyth ng part cu ar. Add a new managed c ass to the app cat on ref class Hello { public: static void SayHello() { Console::WriteLine("Hello. Start M crosoft V sua Stud o 2012 and create a new CLR Conso e App cat on project named Hello 2.

A w ndow opens that shou d ook s m ar to the fo ow ng 6. as dep cted n the fo ow ng screen shot Chapter 23  Attr butes and reflect on   455 . wh ch s nd cated by the b ue component sym- bo C ck the p us s gn (+) to expand the tree for Hello and d sp ay the deta s of the c ass. We’re nterested n the managed type Hello.

The type has three entr es the deta s of the c ass. and the entr es for two methods. Doub e-c ck the red tr ang e to br ng up the c ass nformat on A w ndow s m ar to the fo ow ng appears The defin t on of the managed c ass—wh ch extends System::Object— s marked as private auto ansi These keywords represent tems of metadata that have been added by the comp er to descr be the c ass You can open the other methods n th s c ass to see what metadata s attached to them 456  Microsoft Visual C++/CLI Step by Step . wh ch are the SayHello method you added and the defau t constructor prov ded by the comp er 7.

You can nqu re about attr butes at run t me by us ng reflect on. such as n the fo ow- ng examp e [assembly:AssemblyVersionAttribute("1. Many of these have empty str ngs as arguments 3. you’ see how to create custom attr butes and how to use code to ook at the attr butes attached to c asses Using predefined attributes In th s sect on. wh ch w be used to set the metadata n the assemb y at bu d t me The fo ow ng exerc se shows you how to mod fy assemb y attr butes 1. and what metadata s attached to them Us ng attr butes n code s very powerfu because t g ves you a way to extend the programm ng anguage. you can see the vers on n two p aces F rst. wh ch s a feature by wh ch programmers can obta n nformat on about the objects they are us ng. F nd the vers on number attr bute and ed t t to produce a new vers on. Th s number wou d correspond to vers on 1 1. and by attach ng attr butes to managed e ements n your code The AssemblyInfo. Open the Assemb yInfo cpp fi e and exam ne ts contents Observe that the fi e conta ns a number of entr es of the fo ow ng form [assembly:AssemblyTitleAttribute("AssemblyAttributes")]. t w w ndow. bu d 105. such as what c ass the objects beong to. Create a new CLR Conso e App cat on project named AssemblyAttributes 2. as demonstrated here show n the pane at the bottom of the ILDASM ma n Chapter 23  Attr butes and reflect on   457 . Comp e and bu d the app cat on If you now ook at the assemb y by us ng ILDASM.3")].105.cpp file Every C++/CLI project nc udes an Assemb yInfo cpp fi e that conta ns code affect ng the attr butes app ed to the assemb y You can ed t th s fi e to custom ze the assemb y attr butes. ntroducng new propert es for your c asses that don’t ex st n the base anguage Later n the chapter. rev s on 3 4. you’ earn how to use the attr butes that are predefined by the NET Framework You can use these attr butes n two ways by ed t ng the Assemb yInfo cpp fi e that comes as part of a C++/ CLI project. what methods the objects support.1.

.

t s bu t as an executab e w th an exe extens on and can be executed from the command ne If the assemb y doesn’t conta n an entry po nt. t ooks a ong the path for a fi e w th the r ght name and then oads the first one t finds So. DLLs prov de one way to package up assemb es If an assemb y conta ns a standard entry po nt such as main or WinMain. Create a new CLR Conso e app cat on named UseAttributes You’ add code to th s project ater on n the exerc se Chapter 23  Attr butes and reflect on   459 . mak ng t hard to d agnose and fix However. so app cat ons can contro the r memory use They can be shared by more than one process.DLLs in Windows W ndows executab e code can be packaged n two forms as an executab e. had an o d-fash oned exp c t getter funct on You dec de to add propert es and want to nform deve opers that they shou d not be us ng the o d getter funct on 1. nstead. because assemb es—the fundamenta bu d ng b ocks of NET app cat ons—have vers on nformat on bu t n. f a user has changed the order of d rector es on the r path—or f the path has been changed by nsta ng or remov ng an app cat on—the app cat on m ght find another vers on of the DLL fi e before the correct one Th s means that ocat ng the r ght DLL s dependent on the nd v dua computer setup. the resu t w be a prec se and repeatab e error message rather than odd behav or In the NET wor d. t s bu t as a brary assemb y w th a d extens on A brary assemb y has no entry po nt to beg n execut on but conta ns types that can be referenced from other assemb es Th s exerc se shows you how to use a standard attr bute as we as how to create and use a DLL Imag ne that you have a c ass that d dn’t use propert es but. and t s poss b e to spec fy n the code exact y what vers ons of an assemb y are acceptab e If code does end up runn ng on a computer w th the wrong vers on of an assemb y. us ng the wrong vers on of a DLL sn’t a prob em for NET programmers. so they are a good way to prov de shared funct ona ty such as pr nter dr vers Us ng DLLs means that t s poss b e to upgrade or fix part of an app cat on w thout havng to red str bute or re nsta everyth ng There s a so one major drawback to DLLs n the trad t ona W ndows wor d an app cat on m ght use the wrong vers on of a DLL When an app cat on wants to oad a DLL. or as a DLL DLLs conta n executab e code but can’t run on the r own A DLL conta ns funct ons or c asses used by other code n a process It s oaded at run t me There are both advantages and d sadvantages to us ng DLLs Here are some advantages ■ ■ ■ DLLs can be oaded and un oaded on demand.

n the pane on the eft. } You can see that n add t on to the c ass hav ng a getter funct on. You create DLLs by us ng a C ass L brary project In So ut on Exp orer. so you mark t as obso ete by us ng the Obsolete attr bute [Obsolete("Use the Val property instead". on the shortcut menu. and then c ck New Project 3. When the Add New Project d a og box appears. c ck Propert es In the d a og box. You don’t want to remove the getter funct on because that m ght break ex st ng c ent code. Bu d the app cat on to ensure that you have no cod ng errors 7. and the message shou d be used to nform deve opers why and what to do nstead The second argument d rects the comp er as to whether to treat use of th s funct on as an error or to on y ssue a warn ng 6. } } }. } property int Val { int get() { return val. ca the project MyDll. public: TestClass(int n) : val(n) { } int getVal() { return val. you must add a reference to the conso e project Open the project propert es d a og box for the UseAttr butes project by r ght-c ck ng the project name (not the so ut on name!) and then. c ck Framework And References 460  Microsoft Visual C++/CLI Step by Step . po nt to Add. and then.2. r ght-c ck the so ut on name On the shortcut menu that appears. } The Obsolete attr bute a erts the comp er that th s funct on shou dn’t be used. To use the DLL from the conso e app cat on. false)] int getVal() { return val. t now a so has a property that does the same job 5. and then c ck OK The MyD h fi e opens n the ed tor 4. se ect C ass L brary. c ck Common Propert es. Ed t the c ass defin t on so that t ooks ke th s namespace MyDll { public ref class TestClass { int val.

Bu d the app cat on You shou d see the fo ow ng warn ng from the comp er UseAttributes. you can eas y define custom attr butes and use them n your projects Custom attr butes are qu te s mp e to wr te because an attr bute’s parameters are s mp y represented by a c ass w th propert es and methods For examp e. int n = tc->getVal(). rebu d the ent re so ut on by se ect ng Rebu d So ut on from the Bu d menu. Visual Studio only recompiles those files that have changed since the last build.cpp(12): warning C4947: 'MyDll::TestClass::getVal' : marked as obsolete Message: 'Use the Val property instead' You cou d a so try chang ng the second argument to the Obsolete attr bute to true. C ck the Add New Reference button to open the Add Reference d a og box In the pane on the eft.. Defining your own attributes As you’ see n th s sect on. 10. c ck the So ut on entry Do ng so shows a the projects n the current so ut on You shou d see MyD sted n the center pane se ect the check box adjacent to t. This can be useful when you’ve made significant changes.8.. type=LogAttribute::AllMethods)] ref class MyClass. Chapter 23  Attr butes and reflect on   461 . return 0. suppose you had the fo ow ng attr bute attached to a c ass des gned to contro the generat on of ogg ng nformat on at run t me [LogAttribute("myfile. Ed t the main funct on to create an object and ca ts obso ete get method. and check that use of the obso ete funct on s now treated as an error Note  When you use the Build command. as shown here int main(array<System::String ^> ^args) { TestClass ^tc = gcnew TestClass(4). and then c ck OK tw ce to d sm ss the d a og boxes If you expand the Externa Dependenc es entry under the UseAttr butes project. Open the UseAttr butes cpp source fi e and add a using d rect ve for the MyDll namespace using namespace MyDll.log". you shou d see that t now d sp ays an entry for MyD 9. } 11. Using Rebuild causes Visual Studio to rebuild the entire project.

.

wh ch are spec fied as a name/va ue pa r Cons der the custom attr bute we used as an examp e [LogAttribute("myfile.log". and are passed to the c ass constructor Named parameters are mp emented as propert es n the attr bute c ass Design criteria for attribute classes Before mov ng on to the exerc se. most w nto two groups spec fy at east one Attr bute parameters fa ■ Positional parameters. Create a new CLR C ass L brary project named CustomAttributes The custom attr bute needs to be created as a DLL so that t can be used n other projects Chapter 23  Attr butes and reflect on   463 . as you’ see n the next exerc se As you m ght expect. type=LogAttribute::AllMethods)] Th s attr bute has one pos t ona parameter and one named parameter ca ed type Pos t ona parameters a ways appear before named parameters. you can comb ne two or more members together w th the b tw se OR operator ( ). for an argument ca ed type. are spec fied n a fixed order. ca a c ass DocumentationAttribute rather than Documentation) ■ Use pos t ona arguments for requ red parameters ■ Use named arguments for opt ona parameters ■ Prov de a read-on y property for each pos t ona argument ■ Prov de a read/wr te property for each named argument Be sure the name of the property d ffers n case from that of the argument (for examp e. you’ see how to wr te code that makes use of th s attr bute 1. an attr bute w thout AttributeUsage can be app ed to any code e ement Attribute class properties A though some attr butes have no parameters. prov de a property ca ed Type) Writing a custom attribute Th s exerc se shows you how to create a custom attr bute that can be used to document methods and propert es In the next sect on.If you want to spec fy more than one target. here are a few des gn cr ter a that you shou d keep n m nd when you wr te a custom attr bute c ass ■ A ways add “Attr bute” to the c ass name for an attr bute (for examp e. wh ch are dent fied s mp y by the r pos t on n the parameter st ■ Named parameters.

2. and author and date str ngs (wh ch w be opt ona —and thus mp emented as named parameters) Add the dec arat ons for the three members to the c ass namespace CustomAttributes { [AttributeUsageAttribute(AttributeTargets::Method | AttributeTargets::Property)] public ref class DocumentationAttribute : Attribute { String ^text. // documentation text String ^author. } } 464  Microsoft Visual C++/CLI Step by Step . } Our c ass s ca ed DocumentationAttribute and nher ts from System::Attribute The name fo ows the convent on of hav ng the c ass name for an attr bute end w th “Attr bute ” The c ass s tagged w th an AttributeUsage attr bute that m ts ts use to c ass methods and propert es Note how you can use more than one member of the AttributeTargets enumerat on by comb n ng them w th the b tw se OR operator 3. Open the CustomAttr butes h header fi e and ed t the ske eton c ass as fo ows namespace CustomAttributes { [AttributeUsageAttribute(AttributeTargets::Method | AttributeTargets::Property)] public ref class DocumentationAttribute : Attribute { }. Add a read-on y property so that users can retr eve the text at run t me // Read-only property to return the text property String^ Text { String^ get() { return text. Add the constructor public: DocumentationAttribute(String ^txt) : text(txt) { } The constructor takes a str ng as ts on y argument. saved away as the documentat on text 5. } 4. // optional author field String ^date. // optional date field }. The attr bute w nc ude three p eces of data the documentat on text (wh ch w be a pos t ona parameter).

as demonstrated here // A class to test the attribute ref class TestAtts { int val. } void set(String ^dt) { date = dt. } } property String^ Date { String^ get() { return date. Define a managed c ass that uses the new custom attr bute. } void set(String ^au) { author = au. Open the TestAtts cpp fi e and add a using namespace ne to the top of the fi e using namespace CustomAttributes. just as you d d n steps 7 and 8 of the prev ous exerc se 10. Date="10/10/01")] TestAtts(int v) { val = v. Add read/wr te propert es to a ow access to the two named parameters // Properties for the positional parameters property String^ Author { String^ get() { return author. 11. r ght-c ck the so ut on name On the shortcut menu that appears. } } }. public: [DocumentationAttribute( "The TestAtts class constructor takes an integer". Chapter 23  Attr butes and reflect on   465 . and then se ect New Project Ensure that the project type s set to CLR Conso e App cat on and ca the project TestAtts 9. po nt to Add. } } Choose the names for the propert es carefu y because these are go ng to be used n c ent code when us ng the attr bute 7. } [DocumentationAttribute( "The read-only Value property returns the value of" " the int class member". Bu d the app cat on to check that you haven’t made any errors 8. Author="julian".6. Add an externa reference to the CustomAttr butes DLL. Author="julian")] property int Value { int get() { return val. Add some code that w use the new attr bute In So ut on Exp orer.

and open the TestAtts exe fi e 14. wh ch then forms part of the TestAtts object You can access th s attr bute object from code (You’ see how to do th s n the next sect on ) 15. whereas the property uses on y the text and the Author named parameter Note  Remember that you can split a string literal over two lines.. try add ng the Documentation attr bute to the c ass. ke th s [DocumentationAttribute("The TestAtts class". Before eav ng th s exerc se..ctor entry Th s opens the d sassemb y for the constructor. Run ILDASM. as shown here You can see how the code creates a DocumentationAttribute object. C ck the p us s gn (+) next to the b ue component symbo abe ed TestAtts and then doub e- c ck the . } 466  Microsoft Visual C++/CLI Step by Step . and as long as there is nothing between the closing and opening double quotation marks except white space characters. as descr bed ear er. Author="julian")] ref class TestAtts { .The Documentation attr bute has been attached to the two members of th s c ass The constructor uses a three poss b e parameters. 12. Bu d the app cat on to ensure that t comp es c ean y You can now use ILDASM to see how the attr bute data s he d n the c ass 13. the preprocessor will concatenate them for you.

and enumerat ons It s the pr mary way to access metadata and the way n wh ch you use reflect on A though the Type c ass s used ma n y by deve opers wr t ng anguage too s.When you comp e th s code. C#. nterfaces. you can find out what members a type has. 'property' Using reflection to obtain attribute data The fina sect on of th s chapter shows you how to use attr butes at run t me by nqu r ng about what attr bute data an object conta ns Reflection Query ng attr bute data s on y one aspect of reflection. you need to know someth ng about the Type c ass System::Type s a c ass that represents type dec arat ons Th s means that you can get a Type object to represent any object or type to wh ch you have a reference. you cou d mag ne a p ug.cpp(8): error C3115: 'CustomAttribute::DocumentationAttribute': this attribute is not allowed on 'TestAtts' c:\users\julian\documents\sbs\customattribute\debug\customattribute. and what nterfaces t mp ements You w see th s n act on short y. uses ntrospect on to see what types the DLL defines. and then ets the user choose what to create The th rd use s dynam c nvocat on.n mechan sm that oads a DLL at runt me. wh ch means execut ng funct ons and access ng propert es on an object dynam ca y at run t me You’d typ ca y do th s on an object you’ve created dynam ca y The Type class Before I ta k about reflect on and how t re ates to attr butes. and you can then use that object to find out many deta s about the type You can obta n Type objects to represent va ue types. such as C++/CLI. s to find nformat on about a type For examp e. you m ght find t usefu at t mes. what ts base c ass s. when you use t to find out the attr butes attached to an object The second use of reflect on s to create objects dynam ca y Th s can be usefu when you don’t know the exact type you want unt run t me For examp e. the comp er w attr bute cannot be app ed to c asses throw the fo ow ng error message because the TestAtts. c asses. arrays. such as when you want to access c ass attr butes Chapter 23  Attr butes and reflect on   467 . a powerfu feature supported by many anguages that have a runt me. a so ca ed introspection.dll : see declaration of 'CustomAttribute::DocumentationAttribute' attribute can only be applied to: 'member function'. and Java Reflect on s ma n y used for three th ngs The first.

.

.

r ght-c ck the project name. We know that the c ass doesn’t have any custom attr butes. on the shortcut menu. so add th s code to the start of the main funct on int main(array<String^>^ args) { Console::WriteLine("Testing Attributes"). Cont nue w th the project from the prev ous exerc se 2. Console::WriteLine("Custom attributes on the class: {0}". c ck Set As Startup Project The project name shou d now be d sp ayed n bo d Th s w be the project that s started when you nstruct V sua Stud o to run the projects n the so ut on 470  Microsoft Visual C++/CLI Step by Step . and then. Type ^tt = ta->GetType().Accessing custom attribute data Custom attr bute data s accessed by us ng the stat c GetCustomAttribute and GetCustomAttributes members of the Attribute c ass As you’d expect. You can check whether there are any custom attr butes on a c ass by us ng the GetCustom Attributes method on the Type object. A c asses dea ng w th reflect on res de n the System::Reflection namespace. so you’d expect a count of 0 Note the second Boo ean argument. return 0. Bu d and run the app cat on and check the output 6. // Create an object and get its type TestAtts ^ta = gcnew TestAtts(3). whereas GetCustomAttributes returns you an array conta n ng deta s of a the custom attr butes for a type Th s exerc se shows you how to use the Type c ass and the GetCustomAttributes method to retr eve the attr bute sett ngs from the c ass you created n the prev ous exerc se 1. so add the fo - ow ng using dec arat on to the others at the top of the source using namespace System::Reflection. You need to create a Type object to use reflect on to find out about custom attr butes. To run the conso e app cat on. } You obta n a Type object by us ng the GetType method that every NET type nher ts from System::Object 4. you w need to set t as the startup project In So ut on Exp orer. wh ch spec fies that we want to nc ude any attr butes nher ted from base c asses 5. atts->Length). 3. GetCustomAttribute retr eves nformat on about one attr bute. ke th s // See if there are any custom attributes on the class array<Object^> ^atts = tt->GetCustomAttributes(true).

att->ToString()). mi->Length). the private data value. and ToString). Ca ng GetMembers on the Type object returns an array of MemberInfo objects that descr be the members Runn ng th s code on the TestAtts c ass nforms you that there are seven members Note  The seven members are the constructor. m->Name). } } Chapter 23  Attr butes and reflect on   471 . GetType. 8. for each(Object ^att in atts) { Console::WriteLine(" attribute is {0}". so get a st of the c ass members and query them.7. DocumentationAttribute ^da = dynamic_cast<DocumentationAttribute^>(att). and the fo ow ng code shows one of them Mod fy the code for the nner oop n the prev ous step so that t ooks ke th s for each (Object ^att in atts) { Console::WriteLine(" attribute is {0}". } } } The outer oop cons ders each member n turn and ca s GetCustomAttributes on the Member Info object to get a st of attr bute objects If there are any attr bute objects for th s member. Loop over the st of c ass members and get the custom attr butes for each one for each (MemberInfo ^m in mi) { array<Object^> ^atts = m->GetCustomAttributes(true). the property get method. att->ToString()). There are severa ways to figure out whether a member has the Documentation custom at- tr bute. Console::WriteLine("Class members: {0}". The attr butes are actua y on the c ass members. we pr nt them out 9. GetHashCode. if (da != nullptr) { Console::WriteLine("Doc attribute: {0}". not on the c ass tse f. and four methods inherited from the Object base class (Equals. da->Text). as shown n the fo ow ng // Get info on the class members array<MemberInfo^> ^mi = tt->GetMembers(). if (atts->Length > 0) { Console::WriteLine("Attributes for member {0}:".

Add arguments to the c ass constructor or constructors p us read on y propert es to g ve access to the va ues. For examp e: if ((t->Attributes & TypeAttributes::Public) == TypeAttributes::Public) Create a custom attr bute. }.The oop first uses dynamic cast to cast the current attr bute as a DocumentationAttribute hand e If that returns a non-nu va ue. Represent opt ona parameters for a custom attr bute. Use the Attributes property on a Type object that repre sents the type.. Represent mandatory parameters for a custom attr bute. and so you can retr eve the Text 10. and use the AttributeUsage attr bute to contro where your attr bute can be app ed. you know that the cast worked.cpp fi e that s gener ated for a C++/CL projects n V sua Stud o 2012. w th a stng of the attr butes present on c ass members and a show ng of documentat on text va ues Quick reference To Do this Mod fy the assemb y eve attr butes n a c ass. Add a property to represent each opt ona parameter. 472  Microsoft Visual C++/CLI Step by Step . For examp e: [AttributeUsage(AttributeTargets::Method)] public ref class MyAttribute { .. and use the b tw se AND operator (&) to compare the va ue w th members of the TypeAttributes enumerat on. Create a c ass to represent an attr bute. Ed t the entr es n the Assemb y nfo. Bu d and run the app cat on You shou d see conso e output s m ar to that shown n the screen shot that fo ows. F nd out about the standard attr butes of a type.

.

.

there are st some features of W ndows that aren’t wrapped by NET for wh ch you need to use COM to access The second. t s st worth know ng about COM for two ma n reasons F rst.CHAPTER 24 Living with COM After comp et ng th s chapter. part cu ar y COM components and Act veX contro s Th s chapter shows you how the wor ds of NET and COM can nteroperate. though. you w be ab e to ■ Descr be how you can use Component Object Mode (COM) objects from NET projects ■ Use COM objects through ear y and ate b nd ng ■ Use Act veX contro s n W ndows Forms projects ■ Expose NET objects as COM objects A though the types prov ded n the M crosoft NET Framework are suffic ent for the vast majorty of app cat ons. n the form of Act veX contro s and ower. wh ch s not go ng to go away In fact. mak ng t poss b e for you to take advantage of the best use of new and ex st ng techno og es Many peop e assumed that COM was dead when NET arr ved on the scene. HRESULT. you should learn more about COM before proceeding with this chapter. If terms such as GUID. IDispatch. and type library don’t mean anything to you. IUnknown.eve components. somet mes you’ need to nteract w th ex st ng components. s that the W ndows RT APIs are COM based If you want to get the max mum performance out of W ndows RT code (for examp e. f you’re wr t ng games n C++). 475 .NET world. and perhaps more nterest ng reason. and t s unden ab e that NET prov des a better so ut on for creat ng a ot of component-based so ut ons If you program n C++. there s a ot of COM code out there. you’ want to use COM Note  This chapter assumes that you know what COM objects are and something about how to use them outside the .

t s easy to use a COM object from NET code. n some cases. wh ch are summar zed n the fo ow ng tab e COM . and manag ng ts fet me The pr mary goa of the RCW s to h de the comp ex ty of COM objects from NET programmers.COM components and the COM Interop The des gners of the NET Framework recogn zed that even though the framework s eas er to use and more flex b e than COM for many app cat ons. Wrapper c asses are needed to br dge these d fferences so a COM object can appear as a NET object.NET objects are accessed through references and can be moved around by the CLR for performance reasons. C ents use QueryInterface or browse the object s type nformat on to find out whether a part cu ar nterface s supported. t doesn’t tota y rep ace COM For th s reason.NET C ents must manage the fet mes of the COM objects they create. The Common Language Runt me (CLR) manages the fe t me of . NET programmers m ght not even know they are us ng a COM object 476  Microsoft Visual C++/CLI Step by Step . so you can use COM objects just as f they were NET objects You can see how th s works n the d agram that fo ows The RCW does a the housekeep ng by nteract ng w th the W ndows Regstry.NET code To use a COM object from NET code. and th s g ves NET deve opers access to hundreds of ex st ng COM objects It s a so poss b e to use a NET object from COM code. they deve oped the COM Interop fac ty so that NET and COM objects can nteract As you’ see short y. .NET objects. and v ce versa How do RCWs work? The wrapper takes the form of a proxy c ass that does a the work of creat ng and ta k ng to the COM object. creat ng the object. forward ng ca s to the object. C ents can use reflect on to query an object. a though I’d expect th s to be a ess common occurrence Using COM components from . COM objects are accessed through raw po nters and are therefore fixed n memory. you first create a Runtime Callable Wrapper (RCW) You need the RCW because of severa major d fferences between COM and NET.

.

1. You’ll find the source and executable for the TempConverter project. c ck ComWrapper Propert es to open the Project Propert es d a og box Se ect Common Propert es. choose the COM entry It m ght take a few seconds to popu ate the st box w th deta s of the COM components reg stered on your system 4. You w see that a new entry for TempConverterLib has been added to the project’s st of references 478  Microsoft Visual C++/CLI Step by Step . c ck Frameworks And References. n the pane on the eft. It implements simple temperature conversion functionality between Fahrenheit and Celsius.txt file with directions for installing it. in this book’s sample files. In the Add Reference d a og box that opens. Be sure TempConverter is installed before starting this exercise. On the Project menu. and then c ck the Add New Reference button 3.Note  I’ve created a simple COM object for use in this exercise called TempConverter. Browse the st to find the entry for the TempConverterLib component C ck to the eft of th s entry to add a check mark and then c ck OK 5. plus a ReadMe. n the pane on the eft. Start V sua Stud o 2012 and create a new CLR Conso e App cat on project named ComWrapper 2. and then.

you take the name of the COM co-c ass and append C ass Chapter 24  L v ng w th COM   479 . so the namespace you need to mport s TempConverterLib You can see that the assemb y conta ns three types Converter and IConverter represent the or g na COM co-c ass and nterface defin t ons. so ts symbo doesn’t conta n the I The RCW s produced by the t b mp too 8.6. where XXX and YYY are the name and vers on of the COM component to wh ch the RCW refers 7. Open the IL d sassemb er too (ISDASM) and use t to exam ne Interop TempConverter 1 0 d The sh e d. the r symbo s marked w th an I (a cap ta “ ”) to show that they are nterfaces ConverterClass s a rea type. Open W ndows Exp orer and ook n the project’s Interop d rectory You w see that t conta ns a fi e ca ed Interop TempConverterL b 1 0 d . wh ch conta ns the RCW assemb y These fi es are a ways named Interop XXX YYY d . To deduce the name of the wrapper c ass w thout us ng ILDASM. respect ve y.ke symbo w th the red top represents a namespace.

d).. you need to catch them to prevent your app cat on from term nat ng Here’s what you’ see on the conso e f you pass an nva d temperature 480  Microsoft Visual C++/CLI Step by Step . } Th s code m ght return two error HRESULTs The first. as shown n the fo ow ng int main(array<String^>^ args) { Console::WriteLine("COM Interop Sample").. and methods are ca ed on t n exact y the same way as norma There’s no way to determ ne from th s code that you’re us ng a COM object. return S_OK. wh ch won’t happen when ca ed by the RCW The second. Bu d and run the app cat on. Console::WriteLine("27C is {0}F". Add a using d rect ve to your code to make t eas er to reference the RCW using namespace TempConverterLib. // Create a COM object ConverterClass ^conv = gcnew ConverterClass(). return 0. if (dCelsius < -273. double* dFahr) { if (dFahr == 0) return E_POINTER. } Observe how the wrapper s created just ke any other managed object. E POINTER. check ng that the output s what you expect Handling COM errors You know that COM methods return status and error nformat on by us ng 32-b t HRESULTs The RCW converts a error HRESULTs nto except ons that you can catch n your code The test Converter project returns an error f the convers on methods are passed any va ues ess than –273C or –459˚F because temperatures ess than abso ute zero have no mean ng Here’s the COM code STDMETHODIMP CConverter::ConvertC2F(double dCelsius. Add code to create a wrapper object.0) return E_INVALIDARG. occurs f the po nter to the resu t var ab e s nu . and the wrapper performs a the fet me management for you 11. // Call a conversion method and print the result double d = conv->ConvertC2F(27. 10. and use t to ca methods on the COM object. *dFahr = (9/5.0 * dCelsius) + 32. // Temperatures below -273C are meaningless.0). and as usua . E INVALIDARG. occurs f an nva d temperature s passed These are converted to except ons by the RCW.9.

bu d and run the app cat on and check that the output s correct Late binding to COM objects RCWs mp ement ear y b nd ng connect ons to COM objects. but the process s a tt e more comp ex The exerc se that fo ows shows how to use the TempConverter object w th ate b nd ng Th s COM object was created w th a dua nterface. Type ^t = Type::GetTypeFromCLSID(g). so t can be accessed v a both ear y b nd ng and ate b nd ng 1. Add code to main to get a Type object that represents the COM component (Consu t Chap- ter 23.0). because when you have a type brary. d). Console::WriteLine("-280C is {0}F". you have a the deta s of what the COM object can do ava ab e to you at comp e t me If you want to use a COM object that mp ements IDispatch. if (t == nullptr) { Console::WriteLine("Error getting type for TConverter"). The GetTypeFromCLSID stat c method takes a COM c ass ID (CLSID) as a Guid object and creates a Type object to represent the co-c ass If there s a prob em creat ng the Type object because the CLSID can’t be found or because of some other reg stry-re ated prob em. Create a new CLR Conso e App cat on project named LateBind 2. f that su ts your code better Chapter 24  L v ng w th COM   481 . } Console::WriteLine("Got type for TConverter"). } catch(Exception ^ex) { Console::WriteLine("Exception from COM object: {0}". return -1. ex->Message). you can a so ca t at run t me.You can hand e th s by add ng a try/catch b ock to the code n the main funct on try { double d = conv->ConvertC2F(-280. } Aga n.” for more deta s on the Type c ass and ts uses ) // Get a type representing the COM object Guid g = Guid("75F3EDC5-AA71-437A-ACB6-F885C29E50F7"). a nu s returned Over oads of th s funct on et you spec fy that an except on be thrown nstead of return ng a nu . “Attr butes and reflect on.

the array conta ns on y one va ue the temperature to be converted 5. and check that you get the r ght answer (wh ch s 80 6F) 482  Microsoft Visual C++/CLI Step by Step . } InvokeMember. a hand e to a Binder object (wh ch you’re not us ng). The Activator c ass creates nstances of oca or remote objects for you The reference returned s a genera object reference. as demonstrated here // Use System::Activator to create an instance Object ^obj = Activator::CreateInstance(t). Here. us ng the InvokeMember method of the Type c ass // Invoke the method try { Object ^result = t->InvokeMember("ConvertC2F". Ca the convers on method dynam ca y. Console::WriteLine("27C is {0}F". nullptr. argarray). you don’t need to cast t to any spec fic type because th s w be taken care of for you ater 4. you’ be passed back an Object reference represent ng the resu t.You can find the CLSID of a component by exam n ng the d fi e that was used when creatng  t 3. Use the System::Activator c ass to create the COM object for you. wh ch s then converted to the appropr ate type by us ng one of the stat c methods of the Convert c ass 6. obj. you’re nvok ng a method rather than access ng a property or fie d). d). Bu d and run the app cat on. as shown here // Make up the argument list array<Object^> ^argarray = { 27. Bu d the parameter st before you ca a convers on method on the object Th s takes the form of an array of Objects. double d = Convert::ToDouble(result). Reflection::BindingFlags::InvokeMethod. a hand e to the object on wh ch the operat on s to be nvoked. dynam ca y nvokes a member of an object The arguments supp ed to the funct on are the name of the member to be nvoked. the type of operat on ( n th s case. as ts name mp es. } catch(Exception ^ex) { Console::WriteLine("Exception from Invoke: ". ex->Message).0 }. and a hand e to the argument array If the ca works.

NET components as COM components In add t on to us ng COM objects from NET c ents. th s sect on ntroduces the top c but eaves the pract ca mp ementat on of NET-to-COM code for more advanced texts Aga n. and NET types need to fo ow some ru es f they’re to be exposed as COM objects us ng COM Interop Here’s a summary of what the NET type must to do ■ ■ ■ ■ It must supp y a defau t constructor—one that doesn’t take arguments—because COM objects are a ways created un n t a zed. and t ets the c ent code manage ts fet me n the norma COM manner What must . a CCW puts a COM ayer onto a NET object so that the NET object behaves n exact y the way a COM object s expected to behave The process s shown here The CCW exposes a the nterfaces expected by c ents us ng COM. on y th s t me they are ca ed COM Ca ab e Wrappers (CCWs) In effect.NET types implement to be used as COM objects? COM objects have a part cu ar set of character st cs.Using . you can use NET objects n the COM wor d The process for expos ng NET c asses as COM objects s comp ex because nteract ng w th COM at the C++ eve s d fficu t For th s reason. and there’s no standard way to pass over n t a zat on data For th s reason. t must be poss b e to create NET objects un n t a zed f they’re to be used as COM objects The type’s assemb y must be s gned w th a strong name See the upcom ng s debar “Names and s gn ng” for deta s on strong names and how to use them The type’s assemb y must be p aced where the CLR can find t See the upcom ng s debar “Insta ng assemb es” for more deta s The correct COM-re ated reg stry entr es must be made for the NET object Th s s done for you automat ca y f you’re us ng V sua Stud o Chapter 24  L v ng w th COM   483 . wrapper c asses are used. such as IUnknown and IDispatch.

you use the too s prov ded by the NET Framework for manag ng the cache (such as gacut exe) Assemb es must res de n one of these two ocat ons because they are where the CLR ooks for them when t needs to oad them at run t me 484  Microsoft Visual C++/CLI Step by Step . wh ch cons sts of the text name. and they a so prov de nformat on about the component’s or g nator. and a way to ver fy the assemb y owner or creator COM requ res that components be un que y dent fied. they shou d be g ven a strong name. and poss b y oca e nformat on Th s s adequate for pr vate assemb es that w be used on y w th n a s ng e app cat on However. resu t ng n ots of potent a for confus on To make assemb es un que. vers on. vers on number. p us a pub c key and a d g ta s gnature Every key generated by us ng Pub c Key Encrypt on s un que. can be p aced n the d rectory where the executab e res des or any d rectory d rect y underneath Shared assemb es are nsta ed nto the G oba Assemb y Cache (GAC). t sn’t good enough for those that w be used more w de y because two peop e cou d use the same name for the r assemb es. wh ch are ntended for use by a s ng e app cat on. so us ng keys and d g ta s gnatures serves both to prov de a un que dent fier for an assemb y. wh ch GUIDs do not Installing assemblies Assemb es are typ ca y nsta ed n one of two p aces Pr vate assemb es. wh ch s a per-computer repos tory for assemb es that need to be shared You don’t manua y copy assemb y fi es nto the GAC. and oca e nformat on. and t uses GUIDs to accomp sh th s NET strong names fu fi the requ rement for un que component dent ficat on.Names and signing Assemb es are norma y dent fied by the r name.

NET c ass. Then.NET component n a COM project. Chapter 24  L v ng w th COM   485 .NET code. Use the stat c GetTypeFromProgID or GetTypeFromCLSID methods of the Type c ass to generate a Type object rep resent ng the COM object. Create a CCW. f you re us ng V sua Stud o 2012. exe too to generate an RCW for the COM object. F na y.Quick reference To Do this Use a COM object from . Use a COM object v a ate b nd ng. use InvokeMember on the Type object to nvoke your chosen member. f you re comp ng from the command ne. use the t b mp. Use a . and then reference the wrapper n your code as you wou d any other . use the Propert es d a og box to add a reference to the COM component. use the CreateInstance stat c method on the System::Activator c ass to create an nstance of the object.

.

  107 nt8 type.  175 & (AND operator).  199 % (modu us operator).  31 = operator. 254 > (po nter operator).  335 487 . creat ng connect ng to database.  469 abstract c asses and sea ed c asses.  336 connected app cat on.  391 ~ (comp ement operator).  30 Add method n bank examp e.  26 * (aster sk) symbo .  24 nt64 type.  345 350 namespaces.  31 = (ass gnment operator). creat ng.  24 << ( eft sh ft operator).  30 <> syntax.  342 343 overv ew.  125 #pragma once ne.  337 341 creat ng and execut ng command.  83 + operator.  14 n bank examp e.  256 addresses.  28 #pragma once d rect ve. 254 > operator.  240 241 Add New tem d a og box.  236.  30 .  20 :: (doub e co on syntax).NET assemb es.  269 [ ] (square brackets).  334 335 d sconnected app cat on.  79 = (equa s gn).  364 AddServ ceEndpo nt.Index Symbols + (add t on operator).  240 Add funct on.  438 ^ (caret) symbo .  336 337 data prov ders.  238 240 AddAccount method.  137 overv ew.  344 345 d sconnected operat on us ng DataSet.  422 / (d v s on operator).  240 >> (r ght sh ft operator).  341 342 execut ng quer es and process ng resu ts.  30 ! (NOT operator).  32 :: (scope reso ut on operator). (dot operator).  251.  252. WCF.  130 131 Account c ass.  30 * (mu t p cat on operator).  363 ADO.  24 nt16 type.  439 # nc ude statements.  24 nt32 type.  221 add t on operator (+).  340 341 execut ng command that mod fies data.  422 A Abs funct on.  267 (subtract on operator).  207 %x descr ptor.  169 Abstract attr bute.  296 && (AND operator).  461 add OnF rstEvent method.  252 += operator. 254 # nc ude d rect ve.  30 & (ampersand character).  32 %d descr ptor.  32 <= ( ess than or equa to) cond t on.  107 Add New Reference button.  355 Add Serv ce d a og box.

  438 attached propert es. 315 Attr bute node type.  212 search ng.NET. 464 Attr buteUsageAttr bute c ass.  6 assemb y man fest.Age property overv ew.  427 app bars AppBar contro .  350.  469 auto gcroot type.  212 assemb es ADO. W ndows.  458. 239 Ar thmet cButtons C ck method.  265 AppBarButton sty e.  208 210 n t a z ng.cpp fi e.  461 463 propert es for. 468 Attr buteTargets enumerat on.  469 overv ew. 406 Ar thmet cExcept on.  208 mu t d mens ona .  217 arrays managed arrays and reference types.  202 a gor thms.  26.  213 215 488  Index copy ng e ements. 326 AppendText method.  324.  378 ampersand character (&).  26 27 ass gnment convers ons.  334 336 qu ck reference.  217 218 us ng enumerators w th.  207 Array::Reverse method. 232.  207 208 us ng for each oop w th.  30 31 over oad ng.  292.  216 217 sort ng.  200 202 overv ew.  203 205 n t a z ng.  202 mu t d mens ona .  336 .  454 457 defin ng custom creat ng.  379 ass gn ng var ab es.h.  266 Assemb yCompanyAttr bute. 368 Age property.  161 162 ar ty.  425 428 AppendA L nes method. 323.  267.  197 199 pass ng to funct ons.  210 211 nat ve dynam c a ocat on of.  468 Assemb yQua fiedName property.  380 app cat on programm ng nterface (AP ).  453 454 us ng LDASM.  26 ass gnment operator (=).g.  184 ar thmet c operators.  265 App cat on U tab.  469 AP (app cat on programm ng nterface).  28 System::Array c ass bas c operat ons us ng.  386 387 Attr buteCount property.  16 Ans C ass attr bute. 268 Assemb y nfo.  215 overv ew.  211 overv ew.  175 AND operator (&).  218 219 Array::Sort method.  463 464 overv ew.  464 Attr buteUsage attr bute.  226 A Apps charm.  292 AppendCh d method.  380 App.cpp fi e predefined attr butes. 326.  457 458 c asses for.  307.  309 attr butes and metadata overv ew.  462. W ndows.NET.  457 us ng reflect on to obta n access ng custom attr bute data. 462 AutoC ass attr bute.  292 AppendA Text method.  31 An ma c ass.  161 array keyword.g.  467 469 Attr butes property.  412 ArgumentExcept on.  233 .  232 aggregate n t a zer.  468 Assets fo der. 293 App.  404.  457 458 assemb y nker.  383 n ca cu ator examp e.  458 461 overv ew.  291.  463 467 des gn cr ter a for attr bute c asses.cpp.  222.  463 464 predefined attr butes Assemb y nfo.  266 Assemb y property.  470 472 access ng standard attr butes.  467 468 Type c ass.  296 AND operator (&&).  202 203 overv ew.  217 AsReadOn y method.  440 auto mp emented propert es. 30 aster sk (*) symbo .

  410 412 Ca endar Ass stant app cat on.  4 dent fiers n.  236 238 overv ew.  403 404 gett ng number from button. 282.  391 cast ng process.  417 418 chang ng base.  283 Boo ean type. 132.  4 5 CCWs (COM Ca ab e Wrappers).  421 425 hand ng number nput. 302.  355 b tw se operators.  240 243 mp ement ng.  468 base var ab e.  398 401 overv ew.  425 428 ar thmet c buttons.  449 Average funct on.  3 He o Wor d examp e. 133.  33 34 catch b ock.  180 182. 448 ca ng funct ons.  430 hand ng requests.  261 CanDeb t method.  212 B naryWr ter c ass.  123.  355.  241 BankAccount c ass.  355 BaseButtons C ck method.  233 Ba ance property. overv ew.  428 test ng.  418 421 convert ng str ng n d sp ay.  298. 136 bank examp e add ng Account c ass. 299 303 B narySearch method. 124. WCF. W ndows 8.  429 430 overv ew.  144 C Cached F e Updater contract.  376 Byte type.  299 304 B naryWr ter c ass. 298 b nd ng. 282.  162 B naryReader c ass.  347 hand ng except ons us ng.  282 buffer overrun.  61 Ca ngConvent on fie d. 318 BaseType property.  404 405.  406 shar ng n contracts and charms.  397 398 perform ng ca cu at ons. 134 Canvas contro .  483 Index  489 .  73 breakpo nts.  383 BorderTh ckness property.  408 409 remember ng operat ons.  32 33 b ock ng.  298 overv ew. 407 408 hand ng d fferent number bases add ng buttons for.  5 6 keywords n.  388 Capac ty property.  171 break keyword.  274.  24 Border contro .  358 359 Berke ey Sockets protoco .  238 239 Bank c ass add ng accounts to.  271 Boo ean va ue type.  220 caret (^) symbo .  401 402 ay ng out number buttons.  419 Bas cHttpB nd ng.  126 129 BaseStream property.  412 415 app bars. 358 behav or of W ndows Store apps.  431 432 mp ement ng.  274.  429 ca cu ator examp e add ng t e.  271 Byte va ue type.  236 base addresses.  383 Button e ement.  373 behav ors.  123.  53 B back ng var ab e.  45 47 Ca Me method. overv ew. 189 C++/CL defined.  447 b nary /O B naryReader c ass.  399 BottomAppBar e ement.CCWs (COM Callable Wrappers) automat c ayout.  418 base c asses.  145 boo type.  428 429 DataPackage c ass.  275 BestF tMapp ng fie d.  298 b nary operator. overv ew.  47 BufferedStream c ass. WCF. overv ew.  428 box ng  443 unbox ng.  200 Button contro .  443 444 box ng process. 130.  26 cast operator.  5 6 ma n funct on n.  447.

  79 80 n source fi es.  20 c ass brary. 437.  475 476 us ng from .  309 .  476 us ng .  428 429 n W ndows Store apps.  106 n header fi es.  126 129 c ass w de members data members.  93 94 nstance constants.  92 93 concrete c asses.  483 COM (Component Object Mode ).  145 CheckBox contro .  272 273 Co umnDefin t on e ement.  476 477 creat ng RCWs.  77 c ass w de constants.  86 87 creat ng objects.  93 constructors defin ng.  96 97 overv ew.  374 CharSet fie d.  273 274 Co ect ons namespaces. overv ew.  481 482 overv ew.  222 223 Co ect ons nterfaces. 287.  90 91 overv ew.  458 CLS comp ant operators.  384 CheckCharacters property.  84 86 member n t a zat on sts.  283.  219 SortedL st<K.  323. 326 C ose method. and nher tance.  387 Comb ne method. 448 Char type. 326 C oneNode method.  402 C ear method.  166 167 code beh nd fi es.  212.  130 131 constants n c ass w de constants.  88 89 member funct ons.  236 C ass attr bute.  340 Comment node type. 326 C rc e c ass.  379.  131 136 for predefined attr butes.  95 96 test ng examp e app cat on.  92 93 C earButton C ck method.  137 overv ew.  88 89 member funct ons.  129 130 and fina zers.  95 96 creat ng Loya tyScheme objects.  24. 454 CLS (Common Language Spec ficat on). 299.NET code and RCWs. 382 code reuse.CDATA node type CDATA node type.  100 organ z ng.  81 82 n object or ented programm ng.  90 91 overv ew.  149 150 n W ndows RT.  310 Check ngAccount c ass.  219 221 overv ew. 263 264.  463 464 der ved c asses.  265 c ass members.  469 c asses abstract c asses.  160.  97 100 mp ement ng Loya tyScheme c ass.  20.  136 137 sea ed c asses and abstract c asses. .  447.NET components as COM components.  483 485 CommandText property.  87 88 stat c constructors. over oad ng.  309 charms n ca cu ator examp e.  386 Co umn property. 308. overv ew. 271 Char va ue type.  250 ComboBox contro . 298 CLSComp antAttr bute c ass.  87 88 stat c constructors. 324.  83 84 for custom attr butes.  15 Ch dNodes property.  212 c earOnNextKey var ab e.  324.  458 461 protected access. 336. 298.V> c ass.  122 co ect ons L st<T> c ass.  137 490  Index vs.  94 95 overv ew.  93 94 c ass w de members data members.  16 object re at onsh ps creat ng Loya tyScheme c ass.  276 overv ew.  78 79 overr d ng member funct ons.  130 131 base c asses.  477 480 hand ng errors.  391 392 c ass keyword.NET. 265. structures.  480 481 ate b nd ng to COM objects.  409 C one method.  384 COM Ca ab e Wrappers (CCWs). 318 CLR (Common Language Runt me).

437.  28 29 const cast<> operator.  123.  382 383 Contro temp ates.  463 467 des gn cr ter a for attr bute c asses.NET connect ng to database.  344 DataContract c ass.  222 CompareTo method.  428 429 WCF.  44 Conso e::Wr te funct on.  458 Configurat onManager c ass.  212.  338 connect v ty.  339 connect onStr ngs sect on. 293 Count property. 129 130 CurrentAccount. 218 custom attr butes creat ng.  33 constructors defin ng.  324 Creat onT me property.  249 CurrentAccount c ass. overv ew. n XAML.  292.  129 Current property. 263 264.  264 Cube funct on.  44 copy constructors.  150 Conta nsKey method.data contracts Common Language Runt me (CLR).  289 CreateAttr bute method.  324 CreateWh tespace method.  128 CurrentAccount header fi e.  339 ConformanceLeve property.  78 CTS (Common Type System).  130 131 Cond t ona Attr bute c ass. 454 Common Language Spec ficat on (CLS).  324 Create method.  241 Conta nsVa ue method.  324 CreateProcess ng nstruct on method.  470 472 overv ew.  310 connected app cat on.  113 116 Copy method. WCF.  342 343 overv ew.  324 CreateEnt tyReference method.  337 341 creat ng and execut ng command.  164 ConverterC ass. 298 Compare method.  93 overv ew.  291 CreateText method.  291.  291 293.  223 Content attr bute.  44 constants n c asses c ass w de constants.  324 CreateComment method.  324 CreateE ement method.  93 94 nstance constants. 222 comp ng source fi es.  376 content contro s. 292 CopyTo method.  479 convert ng constructors.  4 Conso e::ReadL ne funct on.  218.  461 463 propert es for.  382 cont nue keyword.  353 Conso e ne.  220 count var ab e.  See COM concrete c asses. 421 Convert::To nt32 funct on.  356 358 n W ndows Store apps. ADO.  94 95 overv ew.  423 ConvertTextTo nt funct on. 126 127.  341 342 execut ng quer es and process ng resu ts.  276.  86 87 for structures.  223 Conta ns method.  164 ConvertOutputStr ng funct on.  381 convers on operator. 308 CreateNav gator method.  20. 306.  324.  463 464 obta n ng data us ng reflect on. 293 Cred tCardAccount c ass.cpp project.  324 CreateSubd rectory method.  463 464 D data adapter.  324 CreateDefau tAttr bute method.  9 10 comp ement operator (~). 215.  160.  210.  184 185 member n t a zat on sts.  84 86 hand ng except ons for.  340 341 execut ng command that mod fies data.  374 contro s.  340 Connect onStr ngSett ngs object.  32 Component Object Mode (COM).  324 CreateD rectory method.  324 CreateXm Dec arat on method.  407.  212.  73 contracts n ca cu ator examp e.  336 337 Connect on property. 293 CreateTextNode method. 326 CreateNode method.  290 CreateDocumentType method.  357 data contracts.  344 DataCo umn c ass.  324 CreateCDataSect on method. 336.  356 Index  491 .

  246 247 De eteCommand. 365 368.  346 DCOM (D str buted Component Object Mode ).  309 Document Object Mode (DOM).  352 d str buted systems.  105 106 us ng.V> c ass. 444 D mport attr bute. n ca cu ator examp e.  430 data prov ders.  458 DebuggerStepThroughAttr bute c ass.  323 DocumentFragment node type.  30 DLL (Dynam c L nk L brary).  458 DebuggerH ddenAttr bute c ass. ADO.  226 der ved c asses.  310 dup ex operat on. overv ew.  59 D spose method.  248 249 de egates that return resu t.  49 dec arat ve U ayout.).  274.  352 D v deByZeroExcept on. gett ng nformat on about.  447 448 DOB member.  129 130 492  Index destructors overv ew.  88 89 Data namespaces. c ass w de.  170.  293 D sp ayDate funct on.  344 DbProv derFactory c ass.  109 De ete method.  219 d rector es.  309 DocumentType property.  431 data types.  307 deque type.  24. 308 D str buted Component Object Mode (DCOM).  464.  204 overv ew.  20 doub e co on syntax (::).  336 DbDataAdapter c ass. 292. 282.  210 211 EarnPo ntsOnAmount funct on.  247 mp ement ng ca ng non stat c member funct ons by us ng de egates.  458 debugg ng.  97 . 282 D rectory nfo c ass.  33 dynam c nvocat on. 250 de egates defin ng.  109 110 D agnost cs namespace.  466 Documentat onAttr bute c ass. over oad ng. d sconnected operat on us ng.  323 do keyword. 152 DateT me c ass.  334 335 DataRow c ass.  247.  234 DbConnect on c ass.  66 defau t va ues.  293 D rectory property.  14 data members. for var ab es. stepp ng through app cat on.  26 overv ew. 271 Doub e va ue type.  265 D ct onary<K.  23 24 Date structure.  309 Document node type.  40 de egate keyword.  247 us ng mu t cast de egates.NET.  358 dynam c a ocat on.  47 51 Debug too bar.  252 253 overv ew. WCF. 298 299. for funct on prototypes. STL/CLR.  446 D mportAttr bute c ass.  71 73 DtdProcess ng property.  276 277 DataPackage c ass.  274.  307 DocumentType node type.  395 defau t branch.  467 Dynam c L nk L brary (DLL. 444 E for each oop us ng w th arrays.  307 dot operator (.  290.  192.  25 decrement operators.  245 246 purpose of.  290 297 D rectory c ass.  151 152 Documentat on attr bute. of arrays.  144 do wh e oops.  249 ca ng stat c member funct ons by us ng de egates.  344 350 DataTransferManager.  72 DOM (Document Object Mode ). 290 291 D rectoryName property.  192.  249 252 overv ew. 293 Depth property.  352 Debuggab eAttr bute c ass. 287. 472 DocumentE ement property.  79 Doub e type.  345 de ete method for arrays. 444 dynam c cast<> operator.  150. 291.  203 205 dynam c cast.  183 d v s on operator (/).  283.  344 DataSet c ass.  171 172 Defau tAttr bute.  274 D a og c ass.data hiding data h d ng.  381 dec ar ng var ab es mu t p e.

  259 261 EvtRcv c ass. us ng w th arrays. n object or ented programm ng.  185 188 overv ew.  480 E ement node type.  9 ExecuteNonQuery method.  276 Extens on property.  449 F FO (first n.  337.  153 154 memory usage.  309 EntryPo nt fie d.  178 executab e programs comp ng source fi es.  291 F fa through.  274.  215 Enab eB naryButtons method. over oad ng. first out).  286 F e P cker contract.  303 304 Index  493 .  175 178 rethrow ng. 340 Ex sts method.  286 F eAttr butes c ass.  337.  362 endpo nts.  190 error hand ng.  309 EndPo ntAddress c ass.  255 events event rece ver.  189 191 Except on c ass propert es. 288.  212.  420 Enab eDec ma Buttons method.  306 Extens b e Sty esheet Language (XSL).  448 except ons and safe cast keyword.  276 Ent ty node type. 342 ExecuteSca ar method.  356 F e dOffsetAttr bute c ass.  260 event hand ng. 11 source fi es for.  337.  420 Enab eHexButtons method.files EF (Ent ty Framework). 341 ExecuteReader method.  191 192 creat ng.  262 standard. 282. 288 F e nfo c ass.  274. 425 Equa s funct on.  353 354 Ent tyC ent data prov der. us ng n sw tch statement. copy ng.  420 encapsu at on. us ng COM components from .  447 448 EnumerateD rector es method. 282 F eMode enumerat on.  182 183 hand ng catch b ock.  184 185 n m xed anguage programm ng.  226 F eAccess enumerat on.  449 eXtens b e Markup Language. 293 exp c t ayout.  276 E NVAL DARG error.  192 195 nest ng.  254 256 overv ew.  185 188 throw ng.  259 261 System::EventHand er de egate and.  67 68 fau t contracts.  255 ExactSpe ng fie d.  253 254 qu ck reference.  307 E PO NTER eror.NET.  429 fi es.  6.  156 enumerators.  8 9 runn ng program.  256 258 event source c ass.  7. 290. 471 errNo fie d.  407. 9 10 creat ng project. See also text /O gett ng nformat on about.  290 297 qu ck reference.  178 180 types of.  309 Ent tyReference node type.  257 EvtSrc c ass.  14 15 Encod ng property.  182 183 except on h erarchy.  169 171 equa s gn (=).  180 182 w th constructors.  10 errors.  309 EndEnt ty node type.  188 try/catch b ocks.  218 219 EOF property. WCF.  291.  309 e ements n arrays.  480 481 Error L st w ndow.  290 291 EnumerateF es method.  74.  296 F e c ass. n propert es.  See also b nary /O.  189 Except on c ass propert es. 292 Ex sts property.  232 EventArgs object. n XAML.  156 us ng n programs.  See XML Extens b e Sty esheet Language Transformat ons (XSLT).  307 EndE ement node type.  290 291 enumerat ons creat ng.  184 fina y b ock. W ndows 8.  389 event keyword.  480 Equa sButton C ck method.  290 291 EnumerateF eSystemEntr es method.  334 Ent ty Framework (EF).  236 Equa s method.

  131 136 pass ng arrays to. 298.  40 defined.  27. 392 gener cs. 296 .FileShare enumeration F eShare enumerat on. 110.  484 garbage co ector.  41 parameters n.  272 float ng po nt va ues.  42 43 return type.  200 202 stat c member funct ons. 282. 318 FontS ze property.  65 67 us ng fa through n.  73 74 wh e oops.  283.  103 104 GCHand e::A oc method.  206.  71 73 for oops. 282 F eSystemWatcher c ass.  62 64 nested tests.cpp fi e.  61 62 oop statements do wh e oops. 286 287 fi e structure.  399 for each oop.  188 F ndA method.  205 206 Geometry.  249 over oad ng.  169 float type.  117 GetAccountNumber funct on.d .  274.  224 STL/CLR brary.  299 fina Amount var ab e.  403 for oops.  154 Formatt ng property. 208 gcroot var ab e.  51 53 oca scope.  67 68 F ushAsync method. 326 F rstEventHand er de egate. 28.  24 flow contro statements f statement mu t way tests.  379 380 F eSystem nfo c ass.  68 70 sw tch statement overv ew. 293. ca ng by us ng de egates.  445 generat ons. 320 forms.  212 Foreground property. ca ng by us ng de egates. and unmanaged code.  291.  212 F ndLast method.  180 funct on header.  440 GD 32.  104 gener c keyword.  70 71 Format member.  106 us ng.  458 F pV ew contro .  323.  224 227 overv ew.  39 40 g oba scope.  395 F agsAttr bute c ass. for W ndows Store apps.  39 return type.  384 float ng po nt types.  347 hand ng except ons us ng.  43 45 funct on prototypes dec ar ng. 468 fu y qua fied name. 147.  370 494  Index FromB nary funct on.  274.  38 parameters n.  41 42 overv ew.  51 53 non stat c member funct ons. first out (F FO).  392 gener c types and temp ates overv ew.  212 F rstCh d property. overv ew.  53 55 overr d ng.  438 GCHand e type.  274.  38 funct ons ca ng. n W ndows RT.  70 71 overv ew.  45 47 funct on bod es defin ng.  82 GetAttr bute method.  212 F nd method.  108 109 fina y b ock.  226 F agsAttr bute.  68 ForEach method.  308 GetAttr butes method.  283 F ush method.  255 first n.  64 65 one way tests.  50 fina zers overv ew.  422 Fu Name property.  269 func funct on.  38 39 defau t va ues for.  286 F eStream c ass.  438 441 gcnew operator. 143.  292. 282 F Buffer method.  41 Funct on keyword.  248 249 G GAC (G oba Assemb y Cache).  57 two way tests.  57 61 overv ew.  68 uncond t ona jumps n.  318.

  374 HasAttr butes property.  212. and W ndows Store apps.  234 GetMethod method.  58 G oba Assemb y Cache (GAC).  290.  184 for nher tance.  354 I Channe hand e. 214 GetMember method.  290 GetLowerBound method.  468 GetMonth funct on.  118 119 overv ew.  364 HttpRequest c ass. 470. 326 hashcode.  277 HttpResponse c ass.  326 GetPropert es method.  212. 450 getter. 273 HasSecur ty attr bute. 164 getVa ue funct on.  213 GetYear funct on.  182 183 except on h erarchy. overv ew. 291 GetD rectoryRoot method.  297 GetD rector es method. 471 get date funct on. c asses n.  468 GetMethods method.  290.  184 fina y b ock.  468 GetMembers method.  307 HasCh dNodes property. 218.  470.  324 GetE ementsByTagName method.  291 get funct on.  87 Get nterfaceMap method.  290 GetE ementBy d method.  171.  470 GetCustomAttr butes method.  123 124 HttpGetEnab ed property.  218 Comparer<T> nterface. 291 GetF eSystemEntr es method.  11 Index  495 .  180 182 hardware.  27 28 hand ng except ons catch b ock.  219.  213.  189 w th constructors.  384 H hand es to objects.  468 GetF e d method.  477 DE ( ntegrated deve opment env ronment).  307 header fi es. 471 Get nterestRate funct on.  59 GetD rector es funct on.  229 GetDay funct on.  481 GetType method. 326 GetEvent method.  59 GetNamespaceOfPrefix method. 214 getVa funct on. 324.  161 GetHashCode method.  469 GetProperty method.  469.  468 Get nterface method.  324 GetEnumerator method.  231 GetTypeFromCLS D method.  79 80 He o Wor d examp e.  184 185 Except on c ass propert es.  484 g oba scope.  375 376 Gr dV ew contro .  468 GetCreat onT me method.  277 HTTP transport.  468 GetF es method.  290 GetCustomAttr bute method. 214 GetLog ca Dr ves method.  253 GetLastAccessT me method.  449. 471 GetUpperBound method.  188 try/catch b ocks.  290 GetF eSystem nfos method.IDE (integrated development environment) GetConstructor method.  52 green and b ue stacks.  372 373 Gr d contro .  468 get method.  290.  326 GetNumberOfAccounts funct on.  273 Connect onPo ntConta ner nterface.  468 Get nvocat onL st funct on.  440 GetVa ue method.  468 GetConstructors method.  468 GetEvents method.  212.  468 GetF e ds method.  290 GetPrefixOfNamespace method.  51 53 g oba var ab es.  162.  468 Get nterfaces method. 292 GetCurrentD rectory method.  323.  90 GetParent method.  362 Co ect on<T> nterface.  477 Connect onPo nt nterface.  290.  273 Comparab e nterface.  171 HashSet<T> c ass. 292 GetLength method.  290.  4 h erarchy for except ons.  469 GetSystemPowerStatus funct on.  469 HasVa ue property. 292 GetLastWr teT me method.

  144 nt32 type.  136 137 sea ed c asses and abstract c asses.  235 nter or po nters.  213 n ne funct ons.  144 ntegrated deve opment env ronment ( DE).identifiers.  439 nc ude guard. over oad ng. 326 nnerXm property.  44 nsertAfter method.  223 nher tance abstract c asses.  250 nvokeMember method. 163 nva dCastExcept on.  5 6 D ct onary<K.  318 ndexed propert es bank examp e creat ng Account c ass propert es.  406 n t a ze method.  469.  271 nt64 type.  273 D spatchEx nterface.  57 61 overv ew.  123 124 term no ogy.  323.  477 Enumerab e<T> nterface.  441 ntermed ate Language ( L).  273 EnumVAR ANT nterface.  122 n t a zeComponent method.  77 nt16 type.  467 nt type.  223 ndexOf method.  318 ndentChar property.  360 # nc ude statements.  221 nstance constants.  130 131 der ved c asses.  137 overv ew.  79.  375 nter process commun cat on ( PC).  469 nterfaces.  129 130 496  Index des gn ng h erarchy for.  363 mport attr bute.  213.  61 62 gnoreComments property.  271 nt16 va ue type. 216 ndexOfVa ue method.  273 MathServ ce contract.  323. 326 nput/output.  264 L D sassemb er too .  324.  210 Enumerator<T> nterface.  310 LDASM.  219 nvocat on st.  271 nt64 va ue type.  345 nsert funct on.  57 two way tests. 24 ntVa c ass.  324 # nc ude d rect ve.  130 131 and code reuse.  64 65 one way tests.  230 overv ew.  See  /O nput var ab e.  207 ndexOfKey method.  62 64 nested tests.  171 172 ndentat on property.  310 gnoreWh tespace property.  375 L st<T> nterface.  15 overr d ng member funct ons.  122 base c asses.  11 nterface attr bute.  18.  19 nnerText property.  477 Error nfo nterface.  121 122 propert es and. 482 nvoke method.  264 L ( ntermed ate Language). 326 nsertBefore method.  191 nva dOperat onExcept on.  271 ntPtr va ue type. 96 ncrement operators.  235 protected access.  274.  477 D spatch nterface. overv ew.  241 244 defined.  138 139 n object or ented programm ng.  137 subst tutab ty.  353 ntPtr type.  454 457 LDASM too . overview dent fiers. propert es n.  161.V> nterface.  273 Enumerator nterface.  123 124 nterfaces.  94 95 nstance members.  361 MetadataExchange contract.  310 gnoreProcess ng nstruct ons property.  145 ntPtr::Zero argument.  236 ndex ng.  477 f statement mu t way tests.  126 129 concrete c asses.  248 OExcept on c ass. 326 nsertCommand. 282 .  324.  131 136 overv ew.  239 240 mp ement ng to retr eve accounts.  469 mportNode method.  447 ntrospect on.

  384 tera constant.  468 sArray property.  286 287 overv ew.  298 B naryReader c ass.  240.  260 L neNumberOffset property.  226 L stV ew contro .  299 303 B naryWr ter c ass.  28 tera keyword.  71 73 for oops.  212 ong ong type.  213.  283 285 O namespace.  274 PC ( nter process commun cat on).  468 sByRef property. 241 L st<T> c ass.  462 og ca operators over oad ng.  415 Load method.  318 oop statements do wh e oops.  382 terator.  325 LoadXm method.  273 sAbstract property.  264 K Kerne 32.  323.  381 L st c ass.  331 LogAttr bute c ass.  384 L stBox tems contro .  308 LookupPrefix method.  219 221 st type.  468 sNotPub c property.  95 96 creat ng objects. 273 L nq c ass.  73 74 wh e oops. 326 LoyaltyScheme class example Last ndexOf method. overv ew. 326 tems contro s.  477 J J T (Just n T me) comp er.  308 sSynchron zed property. 323. 323.  468 sEmptyE ement property.  24 LookupNamespace method. STL/CLR.  307 Set<T> nterface. 226 Unknown nterface.  481 482 ayout n ca cu ator examp e.  212 s nterface property. 293 LastCh d property.  31 32 LongLength property.  287 290 TextWr ter. /O ( nput/output) b nary /O.  307.  24 ong type.  389 KeyVa uePa r c ass. first out (L FO).  291.  283 TextReader. 323.  468 sPub c property. 216 ast n.  226 LastWr teT me property.  70 71 overv ew. 293 ess than or equa to (<=) cond t on. to COM objects.  468 sC ass property.  325 Loca Name property.  310 L nePos t onOffset property.  264 Just n T me (J T) comp er. first out).  32 Length property.  212.  384 388 eft sh ft operator (<<).  354 Prov deC ass nfo nterface.  103 105 L FO ( ast n. 326 oca scope. 213.  445 KeyRoutedEventArgs.  68 uncond t ona jumps n.  212 sVa ueType property.d .  5 6 L LastAccessT me property. overv ew.  51 53 ocat on e ement.  273 overv ew.  225.  477 ReadOn yCo ect on<T> nterface.  223 keywords.  167 169 overv ew.  307.  93 L ve t es.  468 sReadOn y property. of objects.  68 70 Loya tyScheme c ass examp e creat ng.  310 L nkedL st<T> c ass.  276 L stBox contro .  353 PC transport.  219.  291.  298 text /O F eStream c ass.  468 tem property. 293 ate b nd ng.  226 L m tReached event.  199 fet mes. 326 sStartE ement method.  212.  97 100 Index  497 .  398 401 n XAML.  273 sF xedS ze property.

  468 namespaces ADO.  335 .  4 5 ma n method.  376 markup extens ons.  387 MBCS (Mu t Byte Character Set).  272 273 Data namespaces.  382 Marsha AsAttr bute c ass.cpp.  226 mu t p cat on operator (*).  308 MoveToE ement method.  208 209 n t a z ng.  454 457 498  Index .g.  308.  210 MoveToAttr bute method.  355 MFC (M crosoft Foundat on C asses).  81 M crosoft spec fic data types. 323.  445.  24 m xed c asses. 307.  310 Max mumRowsOrCo ums attr bute.  390 MEX (Metadata Exchange) addresses.  438 441 m xed c asses.  353 Name property.  363 365 and attr butes overv ew.  370.  192 195 mm c ass. Except on c ass. unmanaged code GCHand e type.  368 MaxCharacters nDocument property.  276 277 D agnost cs namespace.  405 MC ass object.  211 overv ew. 375 M crosoft ntermed ate Language (MS L) fi e.  308 MoveToContentAsync method.  291. 292 MoveNext method.NET Co ect ons nterfaces.  30 Move method.  308 MoveTo method. 326 Namespace property. STL/CLR.  273 274 Co ect ons namespaces.  90 91 member n t a zat on sts.  380 MakePurchase funct on.  182 metadata add ng to WCF serv ces. 264.  30 mu t set type.h.  274 Net namespaces.  468 modu us operator (%).  229.  356 Math::Abs funct on.  249 252 mu t d mens ona arrays managed arrays.  394 Marg n property.  290.  86 87 MemoryStream c ass. and unmanaged code.  357 358 MessageBox funct on.  96 97 test ng app cat on.  108 Ma nPage c ass.  354 Mu t Byte Character Set (MBCS).  437 Map type.  406 Ma nPage.  274. 282 memory usage.  453 454 us ng LDASM.  291.NET.  440 mc var ab e.  80.  210 211 managed code vs. n constructors.  100 101 M ma n funct on.g. 405 M crosoft ntermed ate Language (MS L). for enumerat ons.  169 MathServ ceC ent c ass.  275 .  437 438 overv ew. 293 MoveToNextAttr bute method.  211 nat ve arrays.  463 named p pes.  156 MEPs (message exchange patterns).  405 mu t cast de egates.  308.  208 mu t d mens ona .  437 438 m xed anguage programm ng. 375 MS L (M crosoft ntermed ate Language) fi e.  458 marsha ng. STL/CLR.main function mp ement ng c ass.  394 map type. 293. 315 MoveToF rstAttr bute method.  80 managed arrays and reference types. 446 Message property.  229. 248 overv ew.  81 MSMQ transport.  207 us ng for each oop w th.  308 MoveToContent method.  226 N named parameters.NET. except ons n.  115 Modu e property.  380 Ma nPage.  41. STL/CLR.  202 203 mu t map type. 98 MakeRepayment funct on. c ass w de.  226 MapV ew type.  440 member funct ons.  274 O namespace.  266 268 n W ndows RT. 315 MS L (M crosoft ntermed ate Language).

  246 not a number (NaN).  275 System namespace.NET Framework assemb es.object-oriented programming overv ew.  308 309.  270 273 us ng n C++ app cat ons.  277 278 W ndows namespaces.  355.  13 14 Index  499 .  16 17 c asses n.  481 482 overv ew.  307.  268 269 Serv ceMode namespaces.  25 26 NaN (not a number).  247 O Object L nk ng and Embedd ng (OLE).  276 Namespaces property.  273 274 Co ect ons namespaces.  263 264 CLS (Common Language Spec ficat on).  306 307 NetMsmqB nd ng.  266 268 MS L (M crosoft ntermed ate Language).  272 nest ng except ons. 326 None node type.  272 Notat on node type.  265 CLR (Common Language Runt me).  250 NOT operator (!).  249 Norma ze method.  275 System namespace.  476 us ng .  16 defined.  325 NodeRemov ng event.  305 306 XML process ng c asses.  31 NotPub c attr bute.  418 421 convert ng str ng n d sp ay.  275 overv ew.  270 271 Web namespaces.  274 Net namespaces. 326 NodeChanged event. 358 new operator.  265 CTS (Common Type System). ca ng by us ng de egates.  417 418 chang ng base.  272 nat ve arrays dynam c a ocat on of.  274 O namespace.  264 namespaces Co ect ons nterfaces.  278 XML and NET XML namespaces.  477 480 hand ng errors.  325 Node nserted event.  197 199 pass ng to funct ons.  270 271 Web namespaces.  270 273 us ng n C++ app cat ons.  277 278 W ndows namespaces.NET components as COM components.  184 nu ptr va ue.  202 203 overv ew.  355.  355.  325 NodeType property.  264 metadata.  325 node st.  469 nu ptr keyword.  370 object or ented programm ng advantages of.  306 overv ew.  326 norma po nters.  323.  325 NodeChang ng event.  263 qu ck reference.  275 Xm namespaces.  309 Not fyDe egate.  272 273 Data namespaces. 358 NetNamedP peB nd ng.  185 188 f statements.  276 overv ew.  421 425 Numer cOp funct on.  476 477 creat ng RCWs.  203 NextS b ng property.NET us ng COM components from and RCWs.  309 NonSer a zedAttr bute c ass.  98 number bases n ca cu ator examp e add ng buttons for.  325 Node nsert ng event.  275 NetTcpB nd ng.  276 277 D agnost cs namespace.  329 NodeRemoved event. 358 Net namespaces.  480 481 ate b nd ng to COM objects.  200 202 negat ve nfin ty.  318 NamespaceUR property.  203 205 n t a z ng.  202 mu t d mens ona . of var ab es.  64 65 .  458 non stat c member funct ons.  268 269 Serv ceMode namespaces. 324.  483 485 .  275 Xm namespaces.  266 c ass brary. 323 nam ng.

  97 100 mp ement ng Loya tyScheme c ass.  166 Orac eC ent data prov der.  166 op Log ca Or operator.  173 174 CLS comp ant operators.  458 ODBC data prov der.  118 119 fet mes of.  171 172 og ca operators Equa s funct on.  109 110 fina zers overv ew.  160 operators ar thmet c operators.  166 op GreaterThan operator.  358 OnNav gatedFrom funct on.  16 po ymorph sm n.  30 og ca operators.  32 33 cast operator.  370 one way messag ng.  167 op UnaryNegat on operator. 432 op Add t on operator.  159 restr ct ons on.  30 31 ass gnment operators.  444 Observer c ass.  163 166 types need ng.  31 32 ternary operator.  167 169 overv ew.  167 op ncrement operator.  261 Obso ete attr bute.  167 op nequa ty operator.  166 Open method.  167 op Log ca Not operator.  167 op Mu t p y operator.  356 operator over oad ng and reference types.  161 162 best pract ces.  34 re at ona operators.  172 173 ar thmet c operators.  96 97 overv ew.  113 116 creat ng.  110 111 obj po nter.  31 32 precedence of.  166 op B tw seOr operator.  83 84 destructors overv ew.  166 op R ghtSh ft operator.  166 op AddressOf operator.  161 stat c operator over oads.  105 106 us ng.  166 op Comma operator.  15 objects n.  292 293 OpenText method.  167 op Subtract on operator.  17 22 nher tance n.  14 15 examp e of.  106 us ng.  167 op LeftSh ft operator.  103 105 n object or ented programm ng. 326 over oaded [ ] operator.  33 34 defined.  167 op OnesComp ement operator.  166 op UnaryP us operator.  30 b tw se operators.  167 op Log ca And operator.  95 96 test ng examp e app cat on.objects encapsu at on n.  384 OR operator.  169 170 overv ew.  171 172 ncrement operators.  167 op Modu us operator.  160 ru es for.  167 op GreaterThanOrEqua operator.  32 33 op Exc us veOr operator.  230 .  292 293 OpenWr te method.  167 op LessThanOrEqua operator.  166 op B tw seAnd operator.  16 re at onsh ps for creat ng Loya tyScheme c ass.  95 96 creat ng Loya tyScheme objects.  421.  31 32 OuterXm property.  324.  334 O eDb data prov der.  334 Or entat on property.  334 OLE (Object L nk ng and Embedd ng).  166 op Po nterDereference operator.  100 101 trad t ona C++ creat on and destruct on.  460 Obso eteAttr bute c ass.  292 293 op Equa ty operator.  432 OnNav gatedTo funct on.  166 167 decrement operators.  167 op LessThan operator.  166 op Decrement operator.  116 118 copy constructors.  292 293 OpenRead method.  108 109 hand es to.  15 16 objects and stack semant cs creat ng objects w th.  166 500  Index operat on contracts.  111 113 overv ew.  166 op D v s on operator.

  394 P atform nvoke (P/ nvoke).  145 Propert es property.  402 property keyword.  379.  274.  See P/ nvoke P atform::Metadata namespace.  379 pre decrement.  171 #pragma once d rect ve.  377 Page e ement.  463 464 for Except on c ass.  236 overv ew.  8 9 propert es for custom attr butes. n W ndows RT.  39 names for. 412 Page c ass.  447 448 overv ew.  379.  171 PrependCh d method. Xm ReaderSett ngs c ass.  449 452 P atform::Co ect ons namespace.  42 43 n funct on prototypes.  229 230 qu ck reference.  236 244 overv ew.  15 16 pop back funct on.  456 pr vate c ass.cpp fi e.  330 processF e funct on.  390 Project Propert es d a og box. 414 po nter operator ( >).  469 overv ew.  391 part a keyword.  272 post decrement.  449 452 Path c ass. 326 Parent property.  379. of operators.  326 PreserveS g fie d. 326 pr ntArea funct on.  232 nher tance and.  236 Pr ntStatement funct on.  31 Prefix property.  457 458 c asses for.  458 parameters n funct on bod es.  444 447 pass ng structured data.  287 pf funct on po nter.  324.  233 errors n propert es. 282 PeekChar method.  171 ProviderName property postfix ncrement operator express on.  136 pr vate keyword.  299 Peek method.  39 ParentNode property.  27 28 p nn ng po nters. over oad ng funct ons.  375 ParamArrayAttr bute c ass.  310 314 part a c asses. 324.  339 Index  501 .  244 sca ar propert es auto mp emented propert es.  235 236 overv ew.  441 442 P/ nvoke (P atform nvoke) ca ng funct ons n W n32 AP D mportAttr bute c ass.  53 55 overr d ng member funct ons.  338 projects.  308. creat ng.  235 n nterfaces.  458 461 obta n ng attr bute data us ng.  28 po nters nter or po nters.  131 136 OwnerDocument property.  233 235 of va ue types.  246 p nn ng po nters.  392 pass ng structured data.  324.  430 Propert es tab.  291 pars ng XML us ng.  19 ProcessCh dNodes funct on. 326 pre ncrement.  309 project ons.  441 overv ew. 326 P Package.  225 Portab e Network Graph cs (PNG) fi es.  457 prefix ncrement operator express on.  136 137 Prov derName property.  323.  394 P ay To contract.  324 Prev ousS b ng property.  448 PreserveWh tespace property.  34 precomp ed headers. W ndows 8.  171 predefined attr butes Assemb y nfo.  78 pr vate auto ans .  231 protected access.  441 442 po ymorph sm n object or ented programm ng.  182 183 ndexed bank examp e.  429 PNG (Portab e Network Graph cs) fi es.  125 precedence. 414 pos t ona parameters.appxman fest fi e.  394 P atform namespaces.  297 Process ng nstruct on node type.  31 post ncrement.  463 pos t ve nfin ty.  231 232 read on y and wr te on y propert es.

  308 ReadContentAs method.  287.  31 32 re at onsh ps.  193 reference types.  212.  97 100 mp ement ng c ass.  318 R Ra seOne funct on.  20 and managed arrays.  470 472 access ng standard attr butes.  325. overv ew.  352 remot ng. 273 queue type.  476 477 Read7B tEncoded nt method. STL/CLR.  299 RedeemPo nts funct on.  259 ra se OnF rstEvent method.  95 96 Re ease Cand date (RC) vers on. 213 rateFract on var ab e.  391 Reference Manager d a og box.  469 overv ew.  308 ReadContentAs nt method. access ng WCF serv ces us ng.  299 ReadByte method.  309 ReadState property.  299 Read nt32 method.  172 173 ref keyword. 309 ReadToDescendant method.  477 480 overv ew.  308 ReadE ementStr ng method. 326 RemoveBy ndex method.  208 209 and operator over oad ng.  299 ReadL ne method.  391 Refresh method.  287.  287 ReadB ock method.  299 ReadContentAsAsync method.  287 ReadToFo ow ng method.  287.  467 469 ref new keyword. 239 ReadOuterXm method.  308 ReadB ockAsync method.  325 read on y propert es.  225 Q Queue<T> c ass.  256 Ra seTwo funct on.  299 ReadChar method.  100 101 overv ew. 289 502  Index Read method.  308 Read nt16 method.  309 ReadToEndAsync method.  7 RCWs (Runt me Ca ab e Wrappers) creat ng.  469 pub c c ass.  97 refactor ng. n ca cu ator examp e.  18 push back funct on. object Loya tyScheme c ass examp e creat ng.  299 Read nt64 method. 308 ReadAttr buteVa ue method. accessing WCF services using proxy.  299 ReadAsync method.  34 re at ona operators.  325 326 .  287 ReadToEnd method.  184 reflect on obta n ng attr bute data us ng access ng custom attr bute data.  299.  365 368 Pub c attr bute.  241 RemoveA method.  308 ReadDec ma method.  219.  299 ReadS ng e method.  299 ReadBytes method.  299 ReadStartE ement method.  313 Read nnerXm method.  299 ReadU nt64 method.  50 RC (Re ease Cand date) vers on.  223 RemoveCh d method.  299 ReadChars method. 308 ReadNode method.  308 ReadSByte method.proxy.  406 Remote Method nvocat on (RM ).  309 Read funct on.  7 remember ng operat ons.  264 RemoveAccount funct on.  287 ReadBoo ean method.  309 ReadToNextS b ng method.  309 ReadU nt16 method.  293 re nterpret cast<> operator.  299 ReadU nt32 method.  233 234.  308 ReadStr ng method.  259 Rank property. 299.  308 ReadContentAsStr ng method.  95 96 creat ng objects.  407 reference counted objects.  308 ReadEndE ement method.  299 ReadE ementContentAs nt method.  308 ReadE ementContentAs method.  299 ReadDoub e method.  226 QuoteChar property.  136 pub c keyword.  96 97 test ng app cat on.  467 468 Type c ass.

327 Rep ace method.  232 nher tance and.  32 RM (Remote Method nvocat on).  221 RemoveHand er funct on.  430 set date funct on. and except ons.  456 SByte type.  290.  308 Schemas property.  276 Schema nfo property.  233 234 Schema c ass.  347 Se ected Components pane.  302 SEH (Structured Except on Hand ng). Remove funct on. arrays.  235 SetHtmlFormat method n nterfaces. 302 SeekOr g n enumerat on.  384 Sea ed attr bute.  345 Se ectCommand property.  325.  221 Rep aceCh d method.  137 Search contract.  39 40 Reverse method.  389 RowDefin t on e ement.  213 r ghtOperand var ab e.  216 217 SecondEventHand er de egate.  428 search ng.  310.  5 Reset funct on.  210 Res ze method.  193 Se ectNodes method.  275 serv ces WCF.  See RCWs Runt meWrappedExcept on.  230 errors n.  352 Root property.  408 r ght sh ft operator (>>).  430 Index  503 .  409 Reset method.  33 Save method. 123.  269 Scro V ewer contro . 41 return type for funct on bod es.  449 Ser a zab e attr bute.  271 SByte va ue type.  178 Se ectCommand. 327 sequent a ayout.  250 remove OnF rstEvent method.  144 sca ar propert es auto mp emented. 293 reserved words.  43 45 for funct on prototypes.  352 access ng by us ng proxy.  112 SetData method.  213 resource d ct onar es.  257 secur ty perm ss ons.  235 read on y and wr te on y. 11 Runt me Ca ab e Wrappers (RCWs).  444 safe cast keyword.  276 Serv ceContract attr bute.  80 SetCurrentD rectory method.  356 serv ce contracts.cpp project.  361 362 SetAttr butes method. on operator over oad ng.  292.  229 SetHtm Format method.  292 SetB tmap method.  469 sea ed c asses and abstract c asses.  266 Seek method.  365 368 add ng metadata to.  4.  298.  307 SayHe o method.  240 241 man pu at ng nvocat on sts us ng.  325 Sav ngsAccount c ass. W ndows 8.  129 SAX (S mp e AP for XML) AP .  7.  51 53 scope reso ut on operator (::).  51 53 oca scope.  469 Ser a zab eAttr bute c ass.  137 overv ew.  15.  381 restr ct ons.  302 seek po nter.  291 RoutedEventArgs c ass.  356 Serv ceMode namespaces. 327 Se ectS ng eNode method. 130 Sav ngsAccount.  259 Remove method n bank examp e.  430 SetDataProv der method.  160 rethrow ng except ons.  363 365 overv ew.  233 defined.  256 RemoveRange funct on.  192 S safe cast.  291 SetCursorToArrow ne.  386 runn ng programs.  325.  191 192 safe cast<> operator.  430 SetCreat onT me method. 324 scope g oba scope. 292 SetCred tL m t funct on.  359 362 wr t ng serv ce c ent.  129 Sav ngsAccount header fi e. 126 127.  185 188 return keyword.  325.  458 Ser a zat on c ass.

  248 StackPane contro .V> c ass.  277. W ndows 8.  274.  334 Sq ServerCe data prov der.  271 S ng e va ue type.  291 292 SetName funct on.  273 overv ew.  231 SetText method. 282 streams. 282.  313 overv ew.  442 Str ngReader c ass. n W ndows RT. and objects creat ng objects w th.  392 393 Str ngWr ter c ass.  277. c ass w de.  248 249 stat c operator over oads.  225 227 overv ew.  302 StreamWr ter c ass. Except on c ass. 306 s mp ex messag ng.  219.  309 SMTP (S mp e Ma Transfer Protoco ).  226 SetUr method.  107 stepp ng through app cat on. STL/CLR.  47.  327 sw tch statement.  163 166 stdafx.  87 SetLastAccessT me method.  449.  226 StandardSty es.  144 s zeof operator. over oad ng.h fi e.SetInterestRate function Set nterestRate funct on.  431 SetVa ue method.  65 67 us ng fa through n.  32.  29 30 Str ng^ parameter. 302 StreamReader c ass.  308.  291 292 SetLastError fie d.  429 Sett ngs property.  267 square funct on. 60 short type. 401 stat c cast<doub e> operator. Except on c ass. 458 structured data.  224 225 Stop Debugg ng opt on.  380.  309 Sk p method. 426 Start W thout Debugg ng opt on.  152 153 creat ng.  430 SetStorage tems method.  201 Sk pAsync method.  358 s ng e byte str ng type.  431 setter.  146 StructLayoutAttr bute c ass.  274.  274.  431 432 mp ement ng.  274.  47 51 STL/CLR brary concepts beh nd.  24 S gn ficantWh tespace node type. 306 SortedL st<K.  405 S ng e type.  90 stat c member funct ons.  449 452 Structured Except on Hand ng (SEH).  429 430 overv ew.  334 square brackets [ ].  38 subst tutab ty.  430 hand ng requests.  307 S mp e Ma Transfer Protoco (SMTP). 284.  219.  429 shar ng n ca cu ator examp e contracts and charms. STL/CLR.  277 SOAP (S mp e Object Access Protoco ).  448 SetLastWr teT me method.  150 152 vs.  431 Sett ngs contract. 282 struct keyword. 318 set type.  428 short c rcu t eva uat on.xam fi e.  428 429 DataPackage c ass. pass ng.  178 structures constructors for.  213.  165 Stream c ass. 214 Shape c ass.  213 Source property.  384 504  Index stack semant cs. ca ng by us ng de egates.  146 148 overv ew. Debug menu.  150 copy ng.  235 Share contract.  146 us ng w th n another.  18.  33 stat c cast<> operator.  381 Sub keyword.  273 sort ng.  30 Supports method.  123 124 subtract on operator ( ).  111 113 overv ew. arrays.  182 stack type.  149 150 sty es. 282 str ngs. 283 Str ng c ass.  20 SetRtf method.  217 218 Sort method. c asses. 44 overv ew.  67 68 .  92 93 stat c keyword.  309 S mp e AP for XML (SAX) AP .  274. W ndows 8.  116 118 Stack<T> c ass. 282. 273 StackTrace property.  33 stat c constructors.  182 Sq C ent data prov der.  277 S mp e Object Access Protoco (SOAP). 222 223 SortedSet<T> c ass.

287 290 TextWr ter c ass.  361 System::Serv ceMode assemb y.  215 overv ew.  247 System::D agnost cs namespace.  277 System::Web::Secur ty namespace.  212 search ng. 283 285 throw ng except ons.  179 System:: O namespace.  272 overv ew.  335 System::Data::Sq C ent namespace.  218 System::Co ect ons::Gener c namespace.  306 System::Xm ::Xs namespace. 335 System::Data::L nq namespace.  178 180 throw keyword.  335 System::Data::Odbc namespace.  306.  277 System::Xm ::L nq namespace.  448 Index  505 .  278 System::Web::U namespace.  277 System::Web namespace.  404.  287 290 TextWr ter.  169 System::OutOfMemoryExcept on c ass.  277 System::Web::U ::Htm Contro s namespace.  470 System::Runt me:: nteropServ ces namespace.  219 System::Configurat on assemb y.  306 System::Xm ::XPath namespace.  213 214 copy ng e ements. 316 System::Xm ::Ser a zat on namespace.  177 System::Enum c ass.  276.  335 System::Data::Ent tyC ent namespace.  309 TextReader c ass.  274.  179 System::ArgumentExcept on c ass.ThrowOnUnmappableCharacter field swscanf s funct on.  437 System::Runt me::Ser a zat on namespace.  276.  281 282 System::MemberAccessExcept on c ass. for XAML. 282.  303 System::Serv ceMode ::AddressAccessDen ed Except on.  276.  259 261 System::Except on c ass. 471 test ng.  212 syntax. and gener c types overv ew.  179 System::Ar thmet cExcept on c ass.  28 Synchron zed method. 335 System::Data::O eDb namespace. 171 System::Web::Ma namespace.  145.  224 STL/CLR brary concepts beh nd. 409 symbo c constant.Serv ceMode > e ement.  335 System::Data namespace.  283. 335 System::Data::Orac eC ent namespace.  32 33 TestAtts c ass.  270 271 System::NotSupportedExcept on c ass.  283 TextReader.  276.  177 ThrowOnUnmappab eCharacter fie d.  277 System::Web::Serv ces namespace.  306 System::Xm ::Schema namespace.  179 System::Nu ReferenceExcept on c ass. overv ew. 335 System::Data::Serv ces namespace.  179 System::Object c ass.  362 <system.  271 float ng po nt types.  367 System::Str ng c ass.  335 System::De egate c ass.  345 System::Data::Common namespace.  306 System::Xm namespace.  247.  283 286 Text node type.  274. events and.  216 217 sort ng.  354 TempConverterL b component.  209 System::SystemExcept on c ass.  466.  286 287 overv ew. 249 System namespace bas c types.  335 System::Data::Spat a namespace.  478 TempConverter project.  217 218 us ng enumerators w th.  449 System::Reflect on namespace. 335 System::Data::Sq Types namespace.  458 System::D v deByZeroExcept on error.  218 219 System::Co ect on namespace.  306 T TCP/ P transport. 287 SyncRoot property.  193 text /O F eStream c ass.  105 System:: ndexOutOfRangeExcept on c ass.  179 System::Mu t castDe egate c ass. 179 System::GC::Co ect stat c method.  179 System::TypeLoadExcept on c ass.  153 System::EventHand er de egate.  478 temp ates.  177.  224 225 ternary operator.  276.  225 227 overv ew.  381 382 System::App cat onExcept on c ass.  179 System:: nva dCastExcept on c ass.  410 412 Test method. ca cu ator examp e.  179 SYSTEM POWER STATUS structure.  179 System::Va ueType c ass.  179 System::Array c ass bas c operat ons us ng.

471 track ng hand es. hand ng except ons us ng.  275 U nPtr va ue type.  443 nter or po nters.  449 452 vs.  317 Va date method.  180 182 TryGetVa ue method.  29 .  145 UML (Un fied Mode ng Language).  121 U UC ass object.  271 U nt64 va ue type.  149 150 var ab es arrays.  275 #us ng d rect ve.  27 28 Str ng c ass.  143 144 enumerat ons creat ng.  381 Tr mToS ze funct on.  73 74 Under y ngSystemType property.  468 Un codeC ass attr bute.  423 Too t p contro .  114 tr ggers.  271 U (user nterface) brar es for W ndows app cat ons.  347 try/catch b ocks.  152 153 creat ng.  145 purpose of. c asses. ca cu ator examp e.  144 145 structures constructors for.  223 type cast ng.  146 us ng w th n another.  372 mode for W ndows Store apps.  213 try b ock.  29 30 typedefs.  412 415 ToB nary funct on.  444 447 506  Index pass ng structured data.  440 U nt16 type.  308 va ue types and reference types overv ew.d .  443 444 uncond t ona jumps.  28 29 data types for.  271 U nt32 va ue type.  441 442 unbox ng.  345 User32.  325 Va dat onF ags property.  271 U nt16 va ue type. 146. obta n ng attr bute data us ng.  23 hand es.  374 U (user nterface) framework.  384 ToStr ng funct on.  441 p nn ng po nters.  29 TypedEventHand er.  26 27 constants. Start Page.  443 444 us ng P/ nvoke to ca funct ons n W n32 AP D mportAttr bute c ass.  27 28 nam ng of.  150 copy ng.  153 154 memory usage.  146 148 overv ew.  20.  432 type safe.  25 26 po nters.  26 overv ew.  291.  33 34 Type c ass.  23 24 dec ar ng mu t p e. 324.  28 ass gn ng va ues to.  469 Un fied Mode ng Language (UML).  447 448 overv ew.  123 unmanaged code.  310 va ue keyword.  308.  156 propert es of.  437 UpdateCommand. managed code GCHand e type.  27 track ng reference.  438 440 m xed c asses.  221 TrueForA method.  270 V Va Hand er c ass.  264 box ng. 161 Va ue property.  437 438 overv ew.  144 U nt32 type. operator for. Start Page.  445 user nterface (U ) framework.tiles.  150 152 vs.  222 Tr mToS ze method.  467 469 typedefs. overv ew.  144 U ntPtr type. 293. calculator example t es. 469.  134 ToStr ng method.  156 us ng n programs.  144 U nt64 type. n oop statements. 326 Va ueType property.  25 defined.  123 unbox ng.  310 Va dat onType property.

  355 behav ors.  397 398 perform ng ca cu at ons.  371 W ndows Presentat on Foundat on (WPF).  371 ca cu ator examp e add ng t e.  430 W ndows::App cat onMode namespaces.  447 448 overv ew.  405 wchar t type.  306 WeekDay c ass.  393 W ndows::Foundat on namespaces.  370 371 W ndows Presentat on Foundat on. overv ew.  406 shar ng n.  393 W ndows::Dev ces namespaces.  401 402 ay ng out number buttons.  425 428 ar thmet c buttons.  408 409 remember ng operat ons.  369 370 W ndows Forms.  24 wcsto (W de Character Str ng To Long) funct on.  277 278 web serv ce.  309 W de Character Str ng To Long (wcsto ) funct on.  370 371 W ndows Presentat on Foundat on.  122 vers on ng.  398 401 overv ew.  352 access ng by us ng proxy.  351 serv ces.  275 d str buted systems. STL/CLR.  353 354 MEPs (message exchange patterns).  375 379 fi e structure for.  277 Web Serv ce Defin t on Language (WSDL).  448 W ndows namespaces.  68 70 wh te space.  266 V rtua z ngStackPane contro .  390 W ndows::Secur ty namespaces. Var ab eS zedWrapGr d contro .  416 425 hand ng number nput.  422 w de str ng type.  394 vector type.  275 W ndows::Data namespaces.  393 W ndows::Management namespaces.  5 Wh tespace node type.  322 WCF (W ndows Commun cat on Foundat on) addresses.  393 W ndows Presentat on Foundat on.  393 W ndows app cat ons M crosoft Foundat on C asses.  394 Veh c e c ass.  353 contracts.  393 W ndows Forms.  403 404 gett ng number from button.  363 365 overv ew.  355 Web Serv ce Descr pt on Language (WSDL).  359 362 wr t ng serv ce c ent.  See W nRT W ndows Runt me L brary (WRL).  371 W ndows Commun cat on Foundat on (WCF).  393 W ndows Store apps and W ndows app cat ons M crosoft Foundat on C asses.  361 362 wchar t* po nter.  393 W ndows::Med a namespaces.  365 368 add ng metadata to.  38 W W3C DOM.  357 358 overv ew.  226 VectorV ew terator c ass. 407 408 hand ng d fferent number bases.  370 371 W ndows::Foundat on::Co ect ons namespaces.  369 370 W ndows Forms.DataTransfer namespace.  393 W ndowsMessageBox funct on.  372 creat ng.  412 415 app bars.  358 359 b nd ng.  410 412 choos ng U brary.  352 endpo nts.  405 W n32 AP .  449 452 Windows Store apps W ndows::App cat onMode .  355 connect v ty.  154 wh e oops.  275 W ndows RT (W nRT).  370 W n32 AP .  394 Vector type.  422 Web namespaces.  275 W ndows::Network ng namespaces.  379 380 Index  507 .  444 447 pass ng structured data.  404 405.  356 358 defined.  394 VectorV ew type.  393 W ndows::G oba zat on namespaces.  369 370 ca ng funct ons us ng P/ nvoke D mportAttr bute c ass.  393 W ndows::Storage namespaces.  370 W n32 AP .  393 W ndows::Graph cs namespaces.  387 Vector terator c ass.  428 432 test ng.  385 vo d keyword.

  392 393 W ndows namespaces.  355 WSDL (Web Serv ce Descr pt on Language).  283 Wr teL ne method.  392 metadata.  319 Wr teStartAttr bute method.  355.  325. 360.  319 Wr teEndE ement method.  374 W nRT AP s.  380 Xm c ass.  319 Wr teEndAttr bute method. 162 Wr te method.  306 307 .  276 Xm Dec arat on node type.  319 508  Index Wr teE ementStr ng method.  394 str ngs.  374 overv ew.  319 Wr teComment method.  283.  390 overv ew. 298 Wr teName method. 327 Wr teVa ue method. 111.  374 overv ew.  325.  394 W ndows::U ::XAML namespaces.  394 W ndows::Web namespaces.  319 Wr teEndDocument method.  319 Wr teNode method.  379 syntax.  322 XML (eXtens b e Markup Language) NET and NET XML namespaces.  389 ayout contro s.  393 WPF (W ndows Presentat on Foundat on).  389 390 P atform namespaces.  389 ayout contro s.  384 388 syntax.  373 U mode .  392 metadata.  318 Wr teBase64 method.  373 contracts and charms.  393 XAML contro s.  382 383 defined.  319 Wr teCharEnt ty method. 362 X XAML (Extens b e App cat on Markup Language) contro s.  283 Wr teAttr butes method.  319 Wr teTo method.  374 hardware usage.  391 392 gener cs.  319 Wr teContentTo method.  390 WSDL (Web Serv ce Defin t on Language).  355.  348 WRL (W ndows Runt me L brary). 358 WSHttpB nd ng.  382 383 defined.  318 Wr teB nHex method. 327 Wr teDocType method.  309 Xm Document c ass.  292 Wr teA Text method.  292 Wr teAsync method.  318 Wr teStr ng method.g.  389 390 P atform namespaces.  319 Wr teEnt tyRef method.  319 Wr te statement.  319 Wr teQua fiedName method.  319 Wr teStartDocument method.  108 Wr teState property.  319 Wr teWh tespace method.  392 393 W ndows namespaces.  381 382 Xam Type nfo.  374 c asses.  306 overv ew.  283 Wr teL ne statement.  394 W nRT (W ndows RT) AP s. 358.  319 Wr teFu EndE ement method.Windows::System namespaces ma n features app behav or.  390 overv ew.  306 WSDua HttpB nd ng.  319 Wr teChars method.  372 373 W ndows RT c asses.  384 388 project fi es.  319 Wr teL neAsync method.h.  319 Wr teRaw method.  275 Wr te7B tEncoded nt method.  319 Wr teStartE ement method.  394 W ndows::U namespaces.  319 wr te on y propert es.  318 Wr teAttr buteStr ng method.  319 Wr teXm method.  380 381 event hand ng.  381 382 W ndows::System namespaces.  108.  233 234 Wr teProcess ng nstruct on method.  394 395 str ngs.  391 392 gener cs.  318 Wr teCData method.  305 306 XML process ng c asses.  380 381 event hand ng.  298 Wr teA L nes method.

  276 Xm Node c ass.  138 x:Name attr bute.  314 w th va dat on.  306 Z Z ndex property.  309 Xm Reader c ass pars ng XML us ng creat ng Xm Readers.  318 322 Xm Va dat ngReader c ass.  318 322 Xm Document c ass overv ew. 318 Xm namespaces.  325 332 Xm NodeType enumerat on.  310 314 qu ck reference.  314 315 overv ew.  276 XSLT (Extens b e Sty esheet Language Transformat ons).  315 317 Xm ReaderSett ngs c ass.  325 332 Xm Lang property.  307 309 ver fy ng we formed XML.  348 wr t ng XML us ng.  310 Xm Space property.  314 315 overv ew.  318 Xm TextReader c ass.  388 Index  509 .  308.  276 XSL (Extens b e Sty esheet Language) processor.  276 Xs c ass.  314 w th va dat on.  310 314 Xm Reso ver property. ZIndex property pars ng us ng Xm Reader creat ng Xm Readers.  307 Xm TextWr ter c ass creat ng object.  309 310 hand ng attr butes.  381 XPath c ass.  322 Xm Node c ass.  322 W3C DOM and.  307 309 ver fy ng we formed XML.  332 wr t ng us ng Xm TextWr ter.  309 310 hand ng attr butes.  315 317 Xm ReaderSett ngs c ass.  307 Xm Wr ter c ass.