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

📄 ch03.htm

📁 好书《C++ Builder高级编程技术》
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>

<HEAD>
	<META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
	<META NAME="Author" Content="Steph Mineart">
	<TITLE>Ch 3 -- C++Builder and the VCL</TITLE>
</HEAD>

<BODY 
BGCOLOR="#FFFFFF">

<P ALIGN="CENTER"><IMG SRC="sams.gif" tppabs="http://pbs.mcp.com/ebooks/0672310228/buttonart/sams.gif" WIDTH="75" HEIGHT="24" ALIGN="BOTTOM"
BORDER="0"><BR>
<BR>
<A HREF="index-3.htm" tppabs="http://pbs.mcp.com/ebooks/0672310228/index.htm"><IMG SRC="toc.gif" tppabs="http://pbs.mcp.com/ebooks/0672310228/buttonart/toc.gif" WIDTH="40" HEIGHT="40" ALIGN="BOTTOM"
ALT="TOC" BORDER="0" NAME="toc4"></A> 
<A HREF="ch02.htm" tppabs="http://pbs.mcp.com/ebooks/0672310228/ch02.htm"><IMG SRC="back-1.gif" tppabs="http://pbs.mcp.com/ebooks/0672310228/buttonart/back.gif"
WIDTH="40" HEIGHT="40" ALIGN="BOTTOM" ALT="BACK" BORDER="0" NAME="toc1"></A> <A HREF="ch04.htm" tppabs="http://pbs.mcp.com/ebooks/0672310228/ch04.htm"><IMG
SRC="forward.gif" tppabs="http://pbs.mcp.com/ebooks/0672310228/buttonart/forward.gif" WIDTH="40" HEIGHT="40" ALIGN="BOTTOM" ALT="FORWARD" BORDER="0"

NAME="toc2"></A></P>
<H2 ALIGN="CENTER"><FONT COLOR="#000077">Charlie Calvert's C++ Builder Unleashed</FONT></H2>
<P>
<H1 ALIGN="CENTER"><FONT COLOR="#000077">- 3 -<BR>
C++Builder and the VCL</FONT></H1>
<P><BR>
In this chapter you will get a look at 
the interface between BCB and the Object Pascal
code found in the VCL. This is a subject you need to understand if you want to take
full advantage of the power of Borland C++Builder.</P>
<P>There are very few occasions when BCB programmers have to 
think explicitly about
the fact that the VCL is written in Object Pascal. Most of the time you can forget
its Delphi-based heritage without fear of missing out on anything important. There
are, however, a few times when Object Pascal affects your 
programming. Almost all
my descriptions of those occasions are concentrated in this chapter. Throughout most
of the rest of this book the subject will never even arise.</P>
<P>The material in this chapter is divided into three main sections:

<DL>
	
<DD><B>1.</B> Understanding the VCL<BR>
	<B><BR>
	2.</B> Changes to the C++ Language<BR>
	<B><BR>
	3.</B> Classes created to imitate Object Pascal simple types that do not exist in
	C++
</DL>

<H2><FONT COLOR="#000077">Understanding the 
VCL</FONT></H2>
<P>All VCL objects are referenced as pointers. There is no such thing as a static
or local instance of a VCL object. You are always working with a pointer to a VCL
object. This is the result of the VCL's origin in the world of Object 
Pascal.</P>
<P>Delphi sought to simplify its syntax to the greatest degree possible. However,
there were several hurdles that had to be crossed before the language could be made
accessible to a wide variety of programmers. In particular, something had 
to be done
about the complexity of dealing with pointers.</P>
<P>For various reasons related to performance and wise use of memory, it is usually
best to declare an object on the heap, rather than on the stack, particularly if
you are still inhabiting 
the segmented world of 16-bit programming. As a result,
the designers of Object Pascal wanted to make it as simple as possible for their
users to work with objects that live on the heap.</P>
<P>Rather than inflict pointer syntax on unwary Object 
Pascal programmers, the creators
of the VCL decided that all objects would necessarily be created on the heap, but
would support the syntax associated with local objects. In short, they created a
world that eliminated pointer syntax for objects 
altogether. They could afford to
do this because they made it impossible to create an object that was not a pointer.
All other language types, such as strings, integers, arrays, structures, and floating-point
numbers, could be treated either as 
pointers or as static objects. This rule applied
only to objects.</P>
<P>It might help to illustrate this point with examples. Here is hypothetical code
for how an Object Pascal programmer might have treated objects according to the standard
rules of 
Pascal:</P>
<PRE><FONT COLOR="#0066FF">var

  S: ^TObject;

begin

  S := New(Tobject, Create);

  S^.DoSomething;

  S^.Free;

end;

</FONT></PRE>
<P>The preceding code will not compile in Delphi, but it is an example of how Delphi
code might have 
looked had the developers not done something to simplify matters.
In particular, Delphi eliminated some syntactical clutter by enabling you to write
the following:</P>
<PRE><FONT COLOR="#0066FF">var

  S: TObject;

begin

  S := TObject.Create;

  
S.DoSomething;

  S.Free;

end;

</FONT></PRE>
<P>Clearly this is an improvement over the first example. However, both samples produce
essentially the same underlying machine code. In other words, both examples allocate
memory for the object, call a 
constructor called <TT>Create</TT>, implicitly call
a method called <TT>DoSomething</TT>, call a destructor called <TT>Destroy</TT>,
and then <TT>Free</TT> the memory associated with the object. In the second example,
all of this can be done without 
any need to dereference a pointer with the &quot;<TT>^</TT>&quot;
symbol or without making explicit reference to the act of allocating memory. The
point being that the compiler knows that the variable <TT>S</TT> has to be a pointer
to an object, 
because Object Pascal forbids the creation of objects that are not
pointers.</P>
<P>Clearly, in the Object Pascal world, it made sense to decide that all objects
had to be pointers. There is no significant overhead involved with using pointers,
and 
indeed they are often the fastest way to manipulate memory. So why not make this
one hard and fast rule in order to make everyone's life simpler?</P>
<P>Translate this same concept into C++, and suddenly the rule doesn't make quite
as much sense. In 
particular, you can only dare go so far when changing the C++ language
to accommodate a new paradigm, and you therefore can't reap any of the benefits that
adhered to the Object Pascal code shown in the second of the two most recently listed
code 
samples. In other words, C++ reaps no benefits from this rule, while it does
tend to limit your choices. In other words, you are no longer free to create VCL
objects locally, but must perforce create them on the heap, whether you want to or
not.</P>

<P>I will therefore take it as a given that the need to create VCL objects on the
heap is not particularly beneficial to C++ programmers. On the other hand, there
is no particular hardship inherent in doing so, nor does it force you to endure any
hit 
on the performance of your application. It is therefore merely a fact of life,
neither inherently good nor inherently bad. If you find this unduly irksome, you
might consider the many other benefits that BCB brings you, and consider this one

limitation as a small price to pay for getting the benefit of this product's strengths.</P>
<P>One final, and not at all unimportant, point: Only VCL objects have to be created
on the heap. All standard C++ objects can be handled as you see fit. In 
other words,
you can have both static or dynamic instances of all standard C++ objects. It's only
VCL objects that must be addressed with pointers and must be allocated on the heap!
<H2><FONT COLOR="#000077">Changes to the C++ Language</FONT></H2>

<P>It's now time to wrap up the introductory portion of this chapter, which provided
an overview of the VCL and BCB programming. The next subject on the agenda involves
how the VCL has impacted the C++ language and how the C++ language has affected 
the
VCL. It's perhaps simplest to start with a run down of the new features in the C++
language.</P>
<P>I am, of course, aware of how controversial it is to add extensions to C++. However,
I personally am only interested in good technology and the 
quality of the products
I use. BCB is a good product, and part of what makes it good is the power of the
VCL and the power of the component, property, event model of programming. The new
extensions have been added to the language to make this kind of 
programming possible,
and so I am in favor of these changes. The C++ committee has done excellent work
over the years, but no committee can keep up with the furious pace of change in this
industry.</P>
<P>The following extensions have been added to 
the language in order to support the
VCL and the component, property, and delegation model of programming:</P>
<PRE><FONT COLOR="#0066FF">_ _declspec(delphiclass | delphireturn)

_ _automated

_ _published

_ _closure

_ _property

_ _classid(class)


_ _fastcall

</FONT></PRE>
<P>As you can see, all of these keywords have two underscores prefixed to them. In
this instance, I have separated the underscores with a single space to emphasize
the fact that not one, but two underscores are needed. In 
your programs, the underscores
should be contiguous, with no space between them.</P>
<P>I am going to go through all these new keywords and make sure that you understand
what each means. The purpose of each of these sections is not to explain the how,

when, where, and why of a particular keyword, but only to give you a sense of what
you can and can't do with them. I will also say something about the relative importance
of each new piece of syntax. My goal is to create a handy reference for the new 
keywords,
but I will wait until later to explain most of them in real depth. For instance,
a lengthy discussion of the <TT>__automated</TT> keyword appears in Chapter 27, &quot;Distributed
COM,&quot; which covers DCOM and Automation, and I discuss 
properties at length in
Chapters 19 through 24, which cover creating components.
<H3><FONT COLOR="#000077">Automated</FONT></H3>
<P>The automated keyword is for use in OLE automation classes. Only classes that
descend from <TT>TAutoObject</TT> or a 
descendant of <TT>TAutoObject</TT> would have
a use for this keyword.</P>
<P>Here is an example of a class that sports an automated section:</P>
<PRE><FONT COLOR="#0066FF">class TMyAutoObject : public TAutoObject

{

private:

public:

  virtual 
__fastcall TMyAutoObject();

__automated:

  AnsiString __fastcall GetName(void) { return &quot;MyAutoObject&quot;; }

};

</FONT></PRE>
<P>If this class were compiled into a working program, the <TT>GetName</TT> function
would be available to other 
programs through OLE automation. They can call the function
and it will return the word <TT>&quot;MyAutoObject&quot;</TT>.</P>
<P>The reason the <TT>GetName</TT> function can be accessed through OLE automation
is because it appears in the automated 
section of an object. Notice that it is also
declared <TT>__fastcall</TT>. This is necessary with automated functions. It means
the compiler will attempt to pass the parameters in registers rather than on the
stack.</P>
<P>The <TT>__automated</TT> 
directive makes OLE automation programming much easier,
but it's effect is limited to this one area. It has no far reaching effect on the
whole of the C++ language.
<H3><FONT COLOR="#000077">The Published Keyword</FONT></H3>
<P>In addition to public, 
protected, and private, C++ now supports two new keywords
used to delineate a section in a class declaration where properties that are to appear
in the Object Inspector can be declared. If you are creating a component with new
properties that you want 
to appear in the Object Inspector, you should place those
properties in the published section. Properties that appear in the published section
have very complete RTTI generated for them by the compiler.</P>
<P>It is only legal to use the 
__<TT>published</TT> keyword in VCL classes. Furthermore,
though the compiler may or may not enforce the rule, it is generally not sensible
to use the <TT>__published</TT> keyword in objects that do not descend from <TT>TComponent</TT>
or from a 
descendant of <TT>TComponent</TT>. The reasoning here is simply that <TT>TComponent</TT>
is a necessary ancestor of all components, and the <TT>__published</TT> keyword exists
because it helps to enhance components. The RTTI associated with the 
<TT>__published</TT>
section will have some effect on program performance, so you don't want to use it
unless it will be helpful. Therefore, use <TT>__published</TT> only in classes that
you want to make into components.</P>
<P>Here is an example of 
an object that features a published section:</P>
<PRE><FONT COLOR="#0066FF">class TMyObject : public TComponent

{

private:

  int FSomeInteger;

protected:

  int AnotherInteger;

public:

  int PublicInteger;

__published:

  __property int 
SomeInteger={read=FSomeInteger, write=FSomeInteger};

};

</FONT></PRE>
<P>In this declaration, the property called <TT>SomeInteger</TT> is published, will
be illuminated with RTTI, and will appear in the Object Inspector if you install

<TT>TMyObject</TT> as a component.</P>
<P>The <TT>__published</TT> directive changes the way I think about classes, and
it changes the way I write code. It currently has significance only for VCL classes
and for your components. At this time it has no 
far-reaching implications in regard
to the structure of the C++ language. It is just something that aids in the construction
of VCL components.
<H3><FONT COLOR="#000077">Properties</FONT></H3>
<P>Properties represent one of the most important, and 
most beneficial additions
to C++ that you will find in BCB. There will be several places in this book where
I discuss properties in depth. In this section I simply give you a general outline
of the key points regarding this subject.</P>
<P>Properties 
have four primary purposes:

<DL>
	<DD><B>1. </B>They support a technology that allows you to expose part of an object
	to visual programmers via the Object Inspector.<BR>
	<B><BR>
	2. </B>They provide an excellent means of creating a rigidly defined, 
and thoroughly
	correct, interface for an object.<BR>
	<B><BR>
	3.</B> They make it easy for you to protect the private data of an object, and the
	private portions of your implementation.<BR>
	<B><BR>
	4</B>. They support a very sophisticated form of 
RTTI which allows them to be both

⌨️ 快捷键说明

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