diff --git a/2554.pdf b/2554.pdf new file mode 100644 index 0000000..66020dd Binary files /dev/null and b/2554.pdf differ diff --git a/2555.pdf b/2555.pdf new file mode 100644 index 0000000..774201e Binary files /dev/null and b/2555.pdf differ diff --git a/2744.html b/2744.html new file mode 100644 index 0000000..301eff9 --- /dev/null +++ b/2744.html @@ -0,0 +1 @@ +
Page xxvii, So What Did You Say About C++/CLI?, Paragraph 2 read:
Of
course, the C++/CLI programmer can also choose to program with the .NET
managed types only, and in this way provide verifiable code, using the
\clr:safe Visual C++ compiler switch. It should read (changes highlighted):
Of
course, the C++/CLI programmer can also choose to program with the .NET
managed types only, and in this way provide verifiable code, using the /clr:safe Visual C++
compiler switch. |
Page xxviii C++\CLI should read:
C++/CLI (occurs 5 times on the page) |
Page 5, Figure 1-1 [2nd
label] Application Development Technologies should
read: .NET
Framework Base Classes [3rd label] Application Development
Technologies should read: Common Language Runtime |
Page 6, 3rd bullet, 1st line reads: Managed code is used to create objects that can be
garbage collection. It should read (change highlighted): Managed code is used to
create objects that can be garbage collected. |
Page 8, 6th bullet, 1st line reads: A list of all reference assemblies It should read (change
highlighted): A list of all referenced assemblies |
Page 17, Just-In-Time Compilation, Paragraph 2 reads: The JIT compiling process is, in concept, very
easy. When an application is started, the JIT compiler is called to convert
the MSIL code and metadata into machine code. To avoid the potentially slow
start-up time caused by compiling the entire application, the JIT compiler
only compiles the portions of code that it calls, when they are called (hence
the name, just-in-time compiler). It should read (changes highlighted): The JIT compiling process is, in concept, very
easy. When an application is started, the JIT compiler is called to convert
the MSIL code and metadata into machine code. To avoid the potentially slow
start-up time caused by compiling the entire application, the JIT compiler
only compiles the portions of code that the application calls, when they are called
(hence the name, just-in-time compiler). |
Page 19, 6th bullet, 1st line reads: Handler types: A reference to a type It should read (changes highlighted): Handle types: A reference to a type |
Page 19, Paragraph 1 reads: A point worth mentioning is that the CLS defines
all .NET-compatible language data types, but a .NET-compatible language does
not need to support all CLS-defined data types. It should read (changes highlighted): A point worth mentioning is that the CTS defines all
.NET-compatible language data types, but a .NET-compatible language does not
need to support all CTS-defined
data types. |
Page 21, .NET Application Development Realms, Paragraph 1 reads: .NET application development falls primarily into
one of five realms: Web applications, Web services, Windows applications,
Windows services, and console applications. Using languages such as C#,
Visual Basic .NET, and Visual Studio .NET provides a simple, powerful, and
consistent environment to develop all five. Unfortunately, for C++/CLI, only
four are supported: console applications, Windows applications, Windows
services, and Web services. It should read (changes highlighted): .NET application development falls primarily into
one of five realms: Web applications, Web services, Windows applications,
Windows services, and console applications. Using languages such as C#,
Visual Basic .NET and
C++/CLI, in conjunction with Visual Studio .NET provides a simple,
powerful, and consistent environment to develop all five. Unfortunately, for
C++/CLI, only four are supported: console applications, Windows applications,
Windows services, and Web services. |
Page 30, Paragraph 4 reads: The preceding line actually declares one handle and
one pointer to an int and two variables of type int. It should read (changes highlighted): The preceding lines actually declare one handle and one pointer to an int and
two variables of type int. |
Page 31, top of page reads: int x =
y = z = 200; It should read (changes highlighted): int y,
z; int x =
y = z = 200; |
Page 32, Table 2-3 reads: Abstract delegate event finally Generic in
initonly literal Override property sealed where It should read (changes highlighted): abstract delegate event finally generic in initonly literal override
property sealed where |
Page 34, in Caution reads: A char is an 8-bit
unsigned integer It should read (changes highlighted): A char is an 8-bit signed integer |
Page 32, in Listing 2-1 reads: // Initialize using
charater literal It should read (changes highlighted): // Initialize using character literal |
Page 43, paragraph 2 reads: Like the fundamental types already discussed, enums
default to being placed on the stack but can beused automatically as objects
when required. It should read (changes highlighted): Like the fundamental types already discussed, enums
default to being placed on the stack but can be used automatically as objects when required. |
Page 43, paragraph 5 reads: It should read (changes highlighted): CLI enums are different from native enums in that the names of the CLI enums values, better known as enumerators, can only be found through the scope of the enums name, and the declaring of the enumÕs base data type has no meaning with a CLI enum. |
Page 45, paragraph 2 reads: Listing 2-8 is a simple example of a value class
called Coord3D. It is made up of three doubles, a constructor, and a Write()
method. I cover constructors and overriding in Chapter 3. It should read (text to be removed highlighted): Listing 2-8 is a simple example of a value class
called Coord3D. It is made up of three doubles, a constructor, and a Write()
method. I cover constructors |
Page 46, last paragraph reads: There are no stack base declarations of C++/CLI
arrays using subscripts, as in traditional C++. All C++/CLI arrays are
references and created on the managed heap. It should read (changes highlighted): There are no stack based declarations of C++/CLI arrays using
subscripts, as in traditional C++. All C++/CLI arrays are references and
created on the managed heap. |
Page 47 reads: Unlike what you have seen so far when
declaring data types, arrays are declared with syntax very similar to a
C++/CLI templates or .NET 2.0 generic classes. Also, to declare an array
requires the namespace stdcli::language: using namespace stdcli::language; For those coders who had to struggle with
the declaration syntax of an array in the previous version of .NET (1.0 and
prior), the new syntax should seem like a breath of fresh air, as I believe
is a little easier to work with do to three aspects of the declaration: É To create an instance of the array, use
the constructor initialization format. Also, because you are allocating the array
to the managed heap, the gcnew
operator is required.
Therefore, to create an array of five ints and an array of seven Strings would require the following statements: using namespace stdcli::language; array<int>^ fiveInts =
gcnew array<int>(5); array<String^>^
sevenStrings = gcnew array<String^>(7); It should read (changes highlighted): Unlike what you have seen so far when
declaring data types, arrays are declared with syntax very similar to a
C++/CLI templates or .NET 2.0 generic classes.
For those coders who had to struggle with
the declaration syntax of an array in the previous version of .NET (1.1 and prior), the new
syntax should seem like a breath of fresh air, and I believe is a little easier to work with do
to three aspects of the declaration: É To create an instance of the array, use
the constructor initialization format. Also, because you are allocating the
array to the managed heap, the gcnew
operator is required.
Therefore, to create an array of five ints and an array of seven Strings would require the following statements:
array<int>^ fiveInts =
gcnew array<int>(5); array<String^>^
sevenStrings = gcnew array<String^>(7); |
Page 47, Code snippet after the second Unsafe code block read: class CLASS {}; array<CLASS*>^ pClass =
gcnew array<CLASS*>(5); for (int i = 0; i <
pClass->Length; i++) pClass[i] = new CLASS(); ... for (int i = 0; i <
pClass->Length; i++) delete pClass[i]; It should read (changes highlighted): class CLASS {}; array<CLASS*>^ hClass = gcnew
array<CLASS*>(5); for (int i = 0; i < hClass->Length; i++) hClass[i] = new CLASS(); ... for (int i = 0; i < hClass->Length; i++) delete hClass[i]; |
Page 48, first code snippet reads: using namespace stdcli::language; array<int, 1>^ Ints_5 =
gcnew array<int>(5); array<int, 2>^ Ints_5x3 =
gcnew array<int>(5, 3); array<int, 3>^ Ints_5x3x2 =
gcnew array<int>(5, 3, 2); It should read (text to be removed highlighted):
array<int, 1>^ Ints_5 =
gcnew array<int>(5); array<int, 2>^ Ints_5x3 =
gcnew array<int>(5, 3); array<int, 3>^ Ints_5x3x2 =
gcnew array<int>(5, 3, 2); |
Page 48, middle code snippet reads: array< array<int>^ >^
jagged = gcnew array< array<int>^ >(4); for (int i = 0; i <
jagged->Length; i++) { e[i] = gcnew array<int>((i+1) * 5); //
each row 5 bigger } It should read (changes highlighted): array< array<int>^ >^
jagged = gcnew array< array<int>^ >(4); for (int i = 0; i <
jagged->Length; i++) { jagged[i] = gcnew array<int>((i+1) * 5); // each row 5
bigger } |
Pages 52, 61, 75, 80,
Assorted instances Change
all references of ÔInt32Õ on these pages to int |
Page 59 second last line on listing 2-12 reads: Console::WriteLine ( e ); //
displays the letter 'e' It should read (changes highlighted): Console::WriteLine ( e ); //
displays the letter 'E' |
Pages 63 and continues on 64 reads: (Careful with this one. This
error is from the first book) The bitwise AND operator compares the bit
pattern of its two operands. If both the bits at the same offset in the bit
pattern are 1s, then the resulting bit pattern will become a 1; otherwise, it
will become a 0. For example: 0101 & 0011 becomes 0001 The bitwise OR operator compares the bit
pattern of its two operands. If either or both the bits at the same offset in
the bit pattern are 1s, then the resulting bit pattern will become a 1;
otherwise, it will become a 0. For example: 0101 & 0011 becomes 0111 The bitwise XOR operator compares the bit
pattern of its two operands. If either, but not both, of the bits at the same
offset in the bit pattern is a 1, then the resulting bit pattern will become
a 1; otherwise, it will become a 0. For example: 0101 & 0011 becomes 0110 The ones complement operator simply flips
the bits. If it was a 1, then it becomes a 0, and vice versa: 0101 becomes 1010 It should read (changes highlighted): The bitwise AND operator compares the bit
pattern of its two operands. If both the bits at the same offset in the bit
pattern are 1s, then the resulting bit pattern will become a 1; otherwise, it
will become a 0. For example: 0101 & 0011 becomes 0001 The bitwise OR operator compares the bit
pattern of its two operands. If either or both the bits at the same offset in
the bit pattern are 1s, then the resulting bit pattern will become a 1;
otherwise, it will become a 0. For example: 0101 | 0011 becomes 0111 The bitwise XOR operator compares the bit
pattern of its two operands. If either, but not both, of the bits at the same
offset in the bit pattern is a 1, then the resulting bit pattern will become
a 1; otherwise, it will become a 0. For example: 0101 ^ 0011 becomes 0110 The ones complement operator simply flips
the bits. If it was a 1, then it becomes a 0, and vice versa: ~0101
becomes 1010 |
Page 75, paragraph one reads: It means you canÕt add or remove elements
to or from the collection. This is not an issue for arrays, given that this
is not allowed anyway, but for many other collection types it may be a
problem. The worst thing is if the compiler doesn't catch it. It is the CLR
that lets you know about it by throwing an exception. It should read (changes highlighted): It means you canÕt add or remove elements
to or from the collection. This is not an issue for arrays, given that this
is not allowed anyway, but for many other collection types it may be a
problem. The worst thing is that the compiler doesn't catch it. It is the CLR that lets
you know about it by throwing an exception. |
Page 76, paragraph 4 reads: The parameter-list
is a comma-separated list of
variable declarations that define the variable, which will be passed to the
function when it starts executing. Parameter variables can be any value
types, references, handles, or pointers, even ones that are user defined. It should read (changes highlighted): The parameter-list
is a comma-separated list of
variable declarations that define the variables, which will be passed to the function when it
starts executing. Parameter variables can be any value types, references,
handles, or pointers, even ones that are user defined. |
Page 77, middle of page reads: int a = 5; int b = example(a); the value of a will be 10. There is a pro and a con to using
references. The pro is that it is faster to pass arguments by reference, as
there is no copy step involved. The con is that, unlike using handlers, other
than %, there is no difference between passing
by value or reference. There is a very real possibility that changes can
happen to argument variables within a function without the programmer
knowing. It should read (text to be removed highlighted): int a = 5;
the value of a will be 10. There is a pro and a con to using references.
The pro is that it is faster to pass arguments by reference, as there is no
copy step involved. The con is that, unlike using handle |
Page 90, Private Public and Protected..., end of paragraph 1 reads: Most people who code C++ use the keywords
ref class when they create objects, and ref struct is very seldom if ever
used. It should read
(changes highlighted): Most people who code C++/CLI use the keywords
ref class when they create objects, and ref struct is very seldom if ever
used. |
Page 92, last paragraph reads: If you have come from the traditional C++
world, you may have noticed the new keyword ref in front of the classÕs
definition. This is one of the biggest and most important changes between
traditional C++ and C++/CLI. (It is also a big change from C++/CLI and
Managed Extensions for C++, as the keyword was __gc.) It should read (text to be removed highlighted): If you have come from the traditional C++
world, you may have noticed the new keyword ref in front of the classÕs
definition. This is one of the biggest and most important changes between
traditional C++ and C++/CLI. (It is also a big change for |
Page 97, last paragraph reads: This fancy name is simply C++/CLIÕs way of
reminding programmers that ref
classes are objects. Member
variables are simply variables defined within the definition of a ref class. It should read
(changes highlighted): This fancy name is simply C++/CLIÕs way of
reminding programmers that ref
classes are object definitions. Member
variables are simply variables defined within the definition of a ref class. |
Page 98, 1st paragraph after Unsafe Code block reads: Member variables can be public, protected,
or private. With C++/CLI and ref
classes, public member
variables should be handled with care, especially if invalid values in these
variables will cause problems in the programÕs execution. It should read
(changes highlighted): Member variables can be public, protected,
or private. With C++/CLI,
a ref classÕs public member variables should be handled with care,
especially if invalid values in these variables will cause problems in the
programÕs execution. |
Page 119, Scalar Properties, Paragraph 3 reads: You can make a property write-only by excluding the set method in the propertyÕs declaration: property type PropertyName { type get() {}; } Conversely, you can make the property read-only by excluding the get method: property type PropertyName { void set (type value) {}; } The get() method gives you full access to the property to do as you please. The most common thing you will do is validate the parameter and then assign it to a private member variable. The only real catch you might encounter is that the property name cannot be the same as a member variable. A conversion I use, which is by no means a standard, is to use a lowercase letter as the first letter of the member variable and an uppercase as the first letter of the property name. With the addition of a set method, you are now free to put any calculation you want within the method, but it must return the type specified. For this type of property, the most common body of the method is a simple return of the member variable storage of the property. It should read (changes highlighted): You can make a property write-only by excluding the get() method in the propertyÕs declaration: property type PropertyName { void set(type value) {}; } Conversely, you can make the property read-only by excluding the set() method: property type PropertyName { type get() {}; } The set() method gives you full access to the property to do as you please. The most common thing you will do is validate the parameter and then assign it to a private member variable. The only real catch you might encounter is that the property name cannot be the same as a member variable. A convention I use, which is by no means a standard, is to use a lowercase letter as the first letter of the member variable and an uppercase as the first letter of the property name. With the addition of a get() method, you are now free to put any calculation you want within the method, but it must return the type specified. For this type of property, the most common body of the method is a simple return of the member variable storage of the property. |
Page 127, listing 3-13 reads:
property String^ default [int]
{
String^ get(int index)
{
if (index < 0)
index = 0;
else if (index > defaultArray->Length)
index = defaultArray->Length - 1;
return defaultArray[index];
}
} private:
array<String^>^ defaultArray; }; void
main() {
Numbers numbers;
Console::WriteLine(numbers[-1]);
Console::WriteLine(numbers[3]);
Console::WriteLine(numbers[10]); } It should read (changes highlighted):
property String^ default [int]
{
String^ get(int index)
{
if (index < 0)
index = 0;
else if (index > defaultArray->Length - 1)
index = defaultArray->Length - 1;
return defaultArray[index];
}
} private:
array<String^>^ defaultArray; }; void
main() {
Numbers numbers;
Console::WriteLine(numbers[-1]);
Console::WriteLine(numbers[3]);
Console::WriteLine(numbers[6]); } |
Page 128, listing 3-14 reads: public: ref class NestedClass //
Declaration of the nested class { public:
int publicMember; protected:
int protectedMember; private:
int privateMember; }; NestedClass^ protectedNC; // protected variable
reference to NestedClass private: NestedClass^ privateNC;
// private variable reference to NestedClass It should read (changes highlighted): public: ref class NestedClass //
Declaration of the nested class { public:
int publicMember; protected:
int protectedMember; private:
int privateMember; }; protected: NestedClass^ protectedNC;
// protected variable reference to NestedClass private: NestedClass^ privateNC;
// private variable reference to NestedClass |
Page 167, paragraph before Listing 4-10 reads: Listing 4-10 shows a simple example of an
exception. I noted in Chapter 3 that the safe_cast operator
throws a System::InvalidCastException
when it is unable to convert
from one try to another. It should read (changes highlighted): Listing 4-10 shows a simple example of an
exception. I noted in Chapter 3 that the safe_cast operator
throws a System::InvalidCastException
when it is unable to convert
from one type to
another. |
Page 170, 1st code snippet reads: try { // Methods that throw OutOfMemoryException } catch (OutOfMemoryException
*oome) // If a method throws an exception {
// Execution will continue here // Process exception } It should read (changes highlighted): try { // Methods that throw OutOfMemoryException } catch (OutOfMemoryException ^oome) // If a method
throws an exception {
// Execution will continue here // Process exception } |
+ /// Visual Basic .NET code example
+ ///
+ ///
+ /// C# code example
+ ///
+ ///
+ /// C++ code example
+ ///
+ ///
+ /// A code statement;
+ /// Another code statement;
+ ///
+ ///