⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch03.htm

📁 好书《C++ Builder高级编程技术》
💻 HTM
📖 第 1 页 / 共 5 页
字号:
the central
constructs that drives BCB. This is the heart of delegation programming model. As
I have said several times, BCB is primarily about components, properties, and the
delegation model. Take events away, and you have some other product 
altogether. Events
radically change the way C++ programs are written. The key effect of events on C++
seems to me to be the following: "In addition to using inheritance and virtual
methods to change the behavior of an object, BCB allows you to 
customize object by
delegating events. In particular, VCL objects often delegate events to the form on
which they reside.&quot;</P>
<P>Like all properties, events work with both standard C++ classes and with VCL classes.
<H3><FONT 
COLOR="#000077">declspec(delphiclass | delphireturn | pascalimplementation)</FONT></H3>
<P>All the additions to C++ discussed so far are primarily about finding ways to
support the VCL. In particular, the new VCL object model has certain benefits 
associated
with it, and so Borland has extended C++ in order to accommodate this new model.
The property and event syntax, however, appears to have at least some other implications
beyond its simple utilitarian capability to support the VCL. I think 
you will find
the next three changes are very small potatoes compared to properties and events.
All they really do is make it possible for BCB to use the VCL, and they don't really
have much effect at all on the way we write code.</P>
<P>As you have 
no doubt gleaned by this time, VCL classes behave in specific ways.
For instance, a VCL class can only by instantiated on the heap, and you can only
use the <TT>__published</TT> or <TT>__automated</TT> keywords with VCL classes.</P>
<P>The majority of 
the time your own classes can inherit this behavior directly,
simply by descending from a VCL class. For instance, here is part of the declaration
for <TT>TControl</TT></P>
<PRE><FONT COLOR="#0066FF">class __declspec(pascalimplementation) TControl : 
public Classes::TComponent

{

  typedef Classes::TComponent inherited;

private:

  TWinControl* FParent;

  ... // etc

}

</FONT></PRE>
<P>As you can see, these classes are declared with the <TT>delphiclass</TT> or <TT>pascalimplementation</TT>

attribute. This means they are implemented in Pascal, and the headers are the only
part that appear in C++ code. If you have an Object Pascal unit that you want to
use in a BCB application, the other declarations in the unit will automatically be

translated and placed in a C++ header file. The class declarations in that header
file will be similar to the one shown here.</P>
<P>However, if you create a descendant of <TT>TControl</TT>, you don't have to bother
with any of this, because the 
attributes will be inherited:</P>
<PRE><FONT COLOR="#0066FF">class MyControl : public TControl

{

  // My stuff here

}

</FONT></PRE>
<P>Class <TT>MyControl</TT> is automatically a VCL class that can support __<TT>published</TT>
properties and must 
be created on the heap. It inherits this capability from <TT>TControl</TT>.
As a result, it is implicitly declared <TT>pascalimpementation</TT>, even though
you don't explicitly use the syntax. I don't like to clutter up class declarations
with 
<TT>__declspec(pascalimplementation)</TT>, but it may appeal to some programmers
because it makes it clear that the class is a VCL class and has to be treated in
a particular manner.</P>
<P>If you want to create a forward declaration for a class with 
the <TT>pascalimplementation</TT>
attribute, it must have the <TT>delphiclass</TT> attribute:</P>
<PRE><FONT COLOR="#0066FF">class __declspec(delphiclass) TControl;

</FONT></PRE>
<P>This is a forward declaration for the <TT>TControl</TT> class found 
in <TT>CONTROLS.HPP</TT>.
You do not inherit <TT>delphiclass</TT> in the same sense that you do <TT>pascalimplementation</TT>,
and so you must use it explicitly in forward declarations!</P>
<P><TT>delphireturn</TT> is used to tell the compiler to 
generate a particular kind
of code compatible with the VCL when it returns objects or structures from a function.
The only place in BCB where this is done is in <TT>SYSDEFS.H</TT> and <TT>DSTRINGS.H</TT>,
which is where classes like <TT>Currency</TT>, 
<TT>AnsiString</TT>, and <TT>Variant</TT>
are declared. If you need to return objects or structures to the VCL, you may need
to declare your class with this directive. However, there are very few occasions
when this is necessary, and most programmers 
can forget about <TT>delphireturn</TT>
altogether.


<BLOCKQUOTE>
	<P>
<HR>
<FONT COLOR="#000077"><B>NOTE: </B></FONT>As shown later in this chapter, the <TT>TDateTime</TT>
	object is declared <TT>delphireturn</TT>. This is necessary because instances 
of
	the object can be passed to VCL functions such as <TT>DateTimeToString</TT>. 
<HR>


</BLOCKQUOTE>

<P>All of this business about <TT>dephireturn</TT> and <TT>pascalimplementation</TT>
has little or no effect on the code written by most BCB 
programmers. <TT>delphiclass</TT>
is slightly more important, because you will likely have occasion to declare a forward
declaration for one of your own descendants of a VCL class. This is clearly a case
where you can indeed afford to &quot;pay no 
attention to the man behind the curtain.&quot;
Most of this stuff is just hand signals passed back and forth between the compiler
and VCL, and you can afford to ignore it. Its impact on the C++ programming as a
whole is essentially nil.
<H3><FONT 
COLOR="#000077">classid(class)</FONT></H3>
<P>Use <TT>classid</TT> if you need to pass the specific type of a class to a function
or method used by the VCL RTTI routines. For instance, if you want to call the <TT>ClassInfo</TT>
method of 
<TT>TObject</TT>, you need to pass in the type of the class you want to
learn about. In Object Pascal you write</P>
<PRE><FONT COLOR="#0066FF">ClassInfo(TForm);

</FONT></PRE>
<P>which means: Tell me about the <TT>TForm</TT> class. Unfortunately, the 
compiler
won't accept this syntax. The correct way to pose the question in BCB is</P>
<PRE><FONT COLOR="#0066FF">ClassInfo(__classid(TForm));

</FONT></PRE>
<P>Again, this is just the compiler and the VCL having a quiet little chat. Pay no
attention 
to the man behind the curtain. RTTI looks one way in the VCL, another in
standard C++. This syntax is used to bridge the gap between the two, and it has no
far reaching implications for C++, the VCL, or anyone else. The excitement is all
centered 
around the property and event syntax; this is a mere trifle.
<H2><FONT COLOR="#000077">__fastcall</FONT></H2>
<P>The default calling convention in Object Pascal is called <TT>fastcall</TT>, and
it is duplicated in C++Builder with the 
<TT>__fastcall</TT> keyword. <TT>__fastcall</TT>
methods or functions usually have their parameters passed in registers, rather than
on the stack. For instance, the value of one parameter might be inserted in a register
such as <TT>EAX</TT> and then 
snagged from that register on the other side.</P>
<P>The <TT>__fastcall</TT> calling conventions pass the first three parameters in
<TT>eax</TT>, <TT>edx</TT>, and <TT>ecx</TT> registers, respectively. Additional
parameters and parameter data larger 
than 32 bits (such as doubles passed by value)
are pushed on the stack.
<H2><FONT COLOR="#000077">Delphi-Specific Classes</FONT></H2>
<P>Not all the features of C++ are available in Object Pascal, and not all the features
of Object Pascal are 
available in BCB. As a result, the following classes are created
to represent features of the Object Pascal language that are not present in C++:</P>
<PRE><FONT COLOR="#0066FF">AnsiString

Variant

ShortString

Currency

TDateTime

Set

</FONT></PRE>

<P>Most of these classes are implemented or declared in <TT>SYSDEFS.H</TT>, though
the crucial <TT>AnsiString</TT> class is declared in its own file called <TT>DSTRINGS.H</TT>.


<BLOCKQUOTE>
	<P>
<HR>
<FONT COLOR="#000077"><B>NOTE: </B></FONT>Neither 
the <TT>real</TT> nor <TT>comp</TT>
	types used in Object Pascal are supported adequately in BCB. Because Pascal programmers
	often used the <TT>comp</TT> type to handle currency, they should pay special attention
	to the section in this chapter on 
the BCB currency type. The real type is an artifact
	of the old segmented architecture days when anything and everything was being done
	to save space and clock cycles. It no longer plays a role in contemporary Object
	Pascal programming. 
<HR>



</BLOCKQUOTE>

<P>I will dedicate at least one section of this chapter to each of the types listed
previously. Some important types, such as <TT>Sets</TT> and <TT>AnsiStrings</TT>,
will receive rather lengthy treatment stretching over several 
sections.</P>
<P>Many C++ programmers will have questions about the presence of some of these classes.
For instance, C++ comes equipped with a great set template and an excellent string
class. Why does BCB introduce replacements for these classes? The 
answer to the question
is simply that BCB needed a class that mimicked the specific behavior of Object Pascal
sets and Object Pascal strings.</P>
<P>Here are some macros you can use with these classes:</P>
<PRE><FONT COLOR="#0066FF">OPENARRAY


ARRAYOFCONST

EXISTINGARRAY

SLICE

</FONT></PRE>
<P>These macros are also discussed in the upcoming sections.
<H2><FONT COLOR="#000077">Introducing the AnsiString Class</FONT></H2>
<P>The C language is famous for its null-terminated strings. These 
strings can be
declared in many ways, but they usually look like one of these three examples:</P>
<PRE><FONT COLOR="#0066FF">char MyString[100]; // declare a string with 100 characters in it.

char *MyString;     // A pointer to a string with no 
memory allocated for it.

LPSTR MyString;     // A &quot;portable&quot; Windows declaration for a pointer to a string

</FONT></PRE>
<P>Declarations like these are such a deep-rooted and long standing part of the C
language that it is somewhat 
shocking to note that they are not as common as they
once were. There is, of course, nothing wrong with these strings, but C++ has come
up with a new, and perhaps better, way to deal with strings. (I speak of these strings
as being exclusive to C, 
though of course these same type of strings are also used
in Object Pascal, where they are called <TT>PChars</TT>.)</P>
<P>The &quot;old-fashioned&quot; types of strings shown previously cause people problems
because it is easy to make memory 
allocation errors with them or to accidentally
omit the crucial terminating zero (<TT>`/0'</TT>) that marks the end of these strings.</P>
<P>These same strings are also famous for their accompanying string library, which
includes a series of cryptic 
looking functions with names like <TT>strcpy</TT>, <TT>strlen</TT>,
<TT>strcmp</TT>, <TT>strpbrk</TT>, <TT>strrchr</TT>, and so on. These functions,
most of which occur in both C++ and Object Pascal, can be awkward to use at times,
and can frequently 
lead to errors if a programmer gets careless.</P>
<P>In this book, I will try to avoid using any of the &quot;old fashioned&quot; C
style strings whenever possible. Instead, I will do things the C++ way and use string
classes. Most C++ programmers 
prefer string classes on the grounds that they are
easier to use, easier to read, and much less likely to lead to an error involving
memory allocation.</P>
<P>In this book there is a fourth reason for using string classes. In particular,
a string 
class called <TT>AnsiString</TT> provides compatibility with the underlying
strings found in the VCL. C++ programmers will find that <TT>AnsiString</TT>s are
similar to the standard ANSI C++ <TT>String</TT> class.</P>
<P><TT>AnsiString</TT>s are very 
easy to use. In fact, many programmers will find
that they have an intuitive logic to them that almost eliminates the need for any
kind of in-depth explanation. However, <TT>AnsiString</TT>s happen to form one of
the key building blocks on which a 
great deal of C++Builder code is based. It is
therefore of paramount importance that users of BCB understand <TT>AnsiString</TT>s.</P>
<P>The next few sections of the book take on the task of explaining <TT>AnsiString</TT>s.
To help illustrate this 
explanation with ready-made examples, you can turn to the
UsingAnsiString program found on the book's CD-ROM. This program provides examples
of essential <TT>AnsiString</TT> syntax and shows several tricks you can use when
you add strings to your 
programs.
<H3><FONT COLOR="#000077">Working with the AnsiString Class</FONT></H3>
<P>The <TT>AnsiString</TT> class is declared in the <TT>DSTRING.H</TT> unit from
the <TT>..\INCLUDE\VCL</TT> directory. This is a key piece of code, and one which
all 
BCB programmers should take at least a few minutes to study.</P>
<P>The declaration for the class in the <TT>DSTRING.H</TT> unit is broken up into
several discreet sections. This technique makes the code easy to read. For instance,
one of the sections 
shows the operators used for assignments:</P>
<PRE><FONT COLOR="#0066FF">// Assignments

    AnsiString&amp; __fastcall operator =(const AnsiString&amp; rhs);

    AnsiString&amp; __fastcall operator +=(const AnsiString&amp; rhs);

</FONT></PRE>

<P>Another section shows some comparison operators:</P>
<PRE><FONT COLOR="#0066FF">//Comparisons

    bool __fastcall operator ==(const AnsiString&amp; rhs) const;

    bool __fastcall operator !=(const AnsiString&amp; rhs) const;

    bool __fastcall 
operator &lt;(const AnsiString&amp; rhs) const;

    bool __fastcall operator &gt;(const AnsiString&amp; rhs) const;

    bool __fastcall operator &lt;=(const AnsiString&amp; rhs) const;

    bool __fastcall operator &gt;=(const AnsiString&amp; rhs) 
const;

</FONT></PRE>
<P>Another handles the <TT>Unicode</TT>-related chores:</P>
<PRE><FONT COLOR="#0066FF">//Convert to Unicode

    int __fastcall WideCharBufSize() const;

    wchar_t* __fastcall WideChar(wchar_t* dest, int destSize) const;


</FONT></PRE>
<P>There is, of course, much more to the declaration than what I show here. However,
these code fragments should give you some sense of what you will find in <TT>DSTRING.H</TT>,
and of how to start browsing through the code to find 
<TT>AnsiString</TT> methods
or operators that you want to use.</P>
<P>The rest of the text in this section of the chapter examines most of the key parts
of the <TT>AnsiString</TT> class and shows how to use them. However, you should definitely
find 
time, either now or later, to open up <TT>DSTRING.H</TT> and to browse through
its contents.
<H3><FONT COLOR="#000077">AnsiString Class Constructors</FONT></H3>
<P><TT>AnsiString</TT>s are a class; they are not a simple type like the string type

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -