|
Softpanorama
(slightly skeptical)
Open Source Software Educational Society |
May the
source be with you,
but remember the KISS principle ;-)
|
Slightly Skeptical C++ Links
C++ as a Multiparadigm Language
(or C++ without OO overdose ;-)
Object oriented programming was invented in 1969 by Dr. Kristen Nygaard
of Norway. He was trying to create a simulation model of the movement of
ships passing through Norwegian fjord (a long narrow arm of the sea bordered
by steep cliffs). Simulation programs usually does not separate data
from the procedures and the object-oriented approach is rather natural for
simulation. Natural objects can be represented by a variable (simulated
time), a structure or a procedure(a ship). At the beginning there were special
languages that simplified implementation of simulation programs using built-in
mechanisms and special language constructs. Actually Dr. Kristen Nygaard
was the co-author of one first specialized language for this domain called
Simula, that was pretty popular (BTW
Donald Knuth was the author of
another early simulation language).
But Dr. Nygaard was the first to realize that some simulation-oriented
constructs and programming tricks are useful as a general purpose programming
mechanisms. That's why he decided to create a general purpose language
Simula67 based on his experience with Simula.
Essentially Simula 67 introduced the concept of classes into Algol,
extending the concept of records (that usually consist of data) with procedures
that are included in the class (member functions). This approach with slightly
different syntactic sugar later was called OO programming. Althouth many
consider Smalltalk to be the first OO language I would say that the really
the first OO-oriented language was Simula67. That
means that the OO technology is 30 years old and actually is older than
Unix. C++ design was greatly influenced by Simula 67.
All-in-all Simula 67 was a pretty interesting Algol extension that in
addition to classes introduced into the language a very important and innovative
concept of coroutines. Later
this brilliant concept found its way to Modula,
Icon and
Python (generators) It's interesting
to note that a little bit later the concept of coroutines was introduced
into Unix as pipes -- probably one of the most important Unix innovations
in the area of OS design. C++ inherited only one of two principal
innovations introduced by Simula 67 (classes). The second innovation --
coroutines (and related concept
of internal pipes) is absent in C++.
There are some valid reasons to use C++ over C. First of all most
compilers now can compile both C and C++ so you can use both languages with
the same compiler. Although many consider C++ as object oriented language,
the language itself does not enforce OO-style and that's a good thing. Moreover
it contains some innovations that are not strictly OO-oriented. The major
such innovation is the concept of templates and namespaces. Namespaces permit
more manageable structuring of name space and is a very important language
construct of its own, independent from OO.
Some OO constructs can be used non-traditionally in a pure procedural
fashion. You can imitate read-only variables by using inline methods that
access private variables in a class. Friends provide a decent imitation
of group access to a particular subset of the name space. C++ also
has lots of small improvements over C that any C programmer will be able
to appreciate: strings, exceptions, more flexible O/I, being able
to declare new variables anywhere, inline functions, generic programming.
On high end one should consider learning STL that contains a library of
important algorithms.
You need to chose compiler wisely. Do not stick to gcc. Gcc is
a good compiler, but not for novices. The quality of diagnostics leaves
much to be desired. Also while analyzing the gcc source can be very educational,
in the end you probably never have a compelling need to look into compiler's
source code. You have at least three other choices:
- The learning version of VC6 can be bought with
several books. The amount
of books for VC6 exceed all other compilers. This is the mainstream
compiler and sometimes it makes perfect sense to follow mainstream.
Reasonable quality of diagnostic, reasonable debugger support. Good
documentation. You need to apply patches from Microsoft WEB site after
installing the compiler.
- High quality
Borland C++ Compiler 5.5 is now free. It provides a decent diagnostic
and good debugger. But this compiler has less books devoted to it then
VC6.
-
Intel C++ compiler is available with a non-commercial license, meaning
that anyone can download and use the full compiler for non-profit work.
This is the best optimizing compiler you can get. The installation of
Intel compiler is far faster and easier than the installation of Visual
Studio .NET. The Intel compiler scores are approximately
2.5 times better then gcc 3.2.1 for the Monte-Carlo simulation, which
is a considerably larger margin than for any of the other parts of the
SciMark 2.0 benchmark. For other parts it is outperforming by only small
margins of 10% or less. See
Benchmarking Intel C++ against GNU gcc on Linux.
Never study C++ as if it is limited to OO. OOP isn't a panacea
(from the point of view of programming productivity combination scripting
language and C, for example TCL+C or Python+C can win) and is oversold
as a method of programming. Historically OO popularity was to the large
extent consequence of the growth of the popularity of GUI applications,
not so much by its own merits.
Like for a hummer everything in the world is a nail, for OO evangelists
everything in the world is object ;-). This is not true. Yes, there are
cases when such a uniform vision represents a breakthrough in particular
narrow area (for example Unix idea that all devices are files was a wonderful
breakthrough), but you need to understand the limits of applicability to
benefit from such a vision. See for example
OOP Criticism -- OOP criticism and OOP
problems (The emperor has no clothes!).
In his
recent interview on Slashdot Bjarne Stroustrup wrote about OO blah-blah-blah:
"After 20-some years, it's obvious that object-oriented
programming is not a panacea. What are your thoughts on the future of
the OO paradigm? What other paradigms do you see challenging
it?
"Bjarne: Well. It was obvious to me 20-some
years ago that OOP wasn't a panacea. That's the reason C++ supports
several design and programming styles."
"If you like long words, you can say C++ is a "multi-paradigm
language," but simply saying "C++ is an OOPL" is inaccurate. I wrote
a paper about that "Why C++ isn't just an Object-Oriented Programming
Language" (download from my papers page). I presented that paper at
OOPSLA - and survived."
"In the first edition of "The C++ Programming Language,"
I didn't use the phrase "object-oriented programming" because I didn't
want to feed the hype. One of the problems with OOP is exactly that
unscrupulous people have hyped it as a panacea. Overselling something
inevitably leads to disappointments."
At the same time object orientation was and is used as a most favorite
method to kill interest in programming, as a method of abuse college students
by semi ignorant instructors ;-). OO religion with its ignorant zealots
is a really bad thing. And it's really unfortunate if such a
zealot is your college instructor, especially if he/she for some stupid
reasons teaches OO in the first programming language course :-(. After
all the main idea is to learn programming, not YASLF (Yet Another Stupid
Language Fad). The best thing than can happen to you in this case is when
the course actually contains C subset of the language in the first chapters
like college courses based on
A First Book of C++ From
Here to There (a very good book). Or when the teacher
(and the textbook that he/she selected) tries to teach a C++ as a better
C like in C++ Primer
Plus.
BTW OO religious mentality (or programming fashion, if you wish, because
in programming languages fashion rules, remember all this noise about Java
in 1997-1999) is now extended to another area, patterns. Some of the ideas
that are presented as an ultimate achievement of this movement are valid
(and actually pretty old), but they are mostly drown in the OO blah-blah-blah.
For those who are over-fascinated with the this fad I strongly recommend
to read
Patterns of Software - Tales from the Software Community" by Richard
Gabriel, one of the founding fathers of the "patterns movement". His opinion?
Patterns don't gain you much, unless you're one of the snake-oil salesmen
profiting by selling the idea. Here is another relevant quote from Bjarne
Stroustrup (see also his famous
newsgroup
posting):
Rule: "Don't Try To Force People"
Programmers are smart people. They are engaged in challenging tasks
and need all the help they can get from a programming language as well
as from other supporting tools and techniques. Trying to seriously constrain
programmers to do "only what is right" is inherently wrongheaded and
will fail. Programmers will find a way around rules and restrictions
they find unacceptable. The language should support a range of reasonable
design and programming styles rather than try to force people into adopting
a single notion.
This does not imply that all ways of programming are equally good
or that C++ should try to support every kind of programming style. [...]
However, moralizing over how to use the features is kept to a minimum,
language mechanisms are as far as possible kept policy free, and no
feature is added to or subtracted from C++ exclusively to prevent a
coherent style of programming.
I am well aware that not everyone appreciates choice and variety.
However, people who prefer a more restrictive environment can impose
one through style rules in C++ or choose a language designed to provide
the programmer with a smaller set of alternatives.
-- "The Design and Evolution of C++", page
113
There is a difference between writing 50-line programs, 15,000 line,
and 25,000 lines programs... designed, developed, documented, tested, and
integrated... and all along, As program grow larger writer is confronted
with more software engineering problems
than programming problems. For example the problem of namespaces arise in
large programming projects and here C++ has a definite an edge over C. Templates
also can help in large projects.
Let me try to sum my view on C++ in the following way -- programming
is cranking out a solution to a problem in the most efficient way. But premature
paradigm adoption (for example, OO) like a premature optimization is the
source of major problems. The programming methodology should be tuned to
the problem in hand not vise-versa.
|
Premature paradigm adoption (for example,
OO) like a premature optimization is the source of major problems.
The programming methodology should be tuned to the problem in
hand not vise-versa
|
See
OOP Criticism for more details.
OOP became popular primarily because of GUI interfaces. In fact,
many non-programmers think that "Object" in OOP means a screen object
such as a button, icon, or listbox. They often talk about drag-and-drop
"objects". GUI's sold products. Anything associated with GUI's was sure
to get market and sales brochure attention, regardless of whether this
association was accurate or not. I have even seen salary surveys from
respected survey companies that have a programming classification called
"GUI/OOP Programming".
Screen objects can correspond closely with OOP objects, making them
allegedly easier to manipulate in a program. We do not disagree that
OOP works fairly well for GUI's, but it is now being sold as the solve-all
and be-all of programming.
Some argue that OOP is still important even if not dealing directly
with GUI's. In our opinion, much of the hype about OOP is faddish. OOP
in itself does NOT allow programs to do things that they could not do
before. OOP is more of a program organizational
philosophy rather than a set of new external solutions or operations.
In his old Usenix paper
Objecting To Objects Stephen C. Johnson wrote
Object-oriented programming (OOP) is an ancient (25-year-old) technology,
now being pushed as the answer to all the world's programming ills.
While not denying that there are advantages to OOP, I argue that
it is being oversold. In particular, OOP gives little support
to GUI and network support, some of the biggest software problems we
face today. It is difficult to constrain relationships between objects
(something SmallTalk did better than C++). Fundamentally, object reuse
has much more to do with the underlying models being supported than
with the object-ness of the programming language. Object-oriented languages
tend to burn CPU cycles, both at compile and execution time, out of
proportion to the benefits they provide. In summary, the goods
things about OOP are often the information hiding and consistent underlying
models which derive from clean thoughts, not linguistic cliches.
Actually if we talk about efficiency the rule is that 80% of time are
spend in 20% of code and if you really care about efficiency those 20% of
code should be written in a simpler more efficient language -- for
C++ than means C , for C it means assembler. That's why the bible of system
programmers The Art of Computer Programming
by Donalds Knuth is still as important
as it was 30 years ago.
As problem complexity increases, C++ become more and more viable
solution although I would prefer with the combination of TCL and C, or
Python and C++ to plain-vanilla C++ in many practical situations.
Software engineering is about developing the solution to a complex problem
in a manner that others can understand and maintain; that is not only well
documented but preferably self-documented. In many cases C++ as a higher
level language (especially with STL) is good enough and is a viable choice
(the quality of C++ compilers is pretty decent these days). But again the
main word here is choice; if I can
produce a solution in TCL+C or Python and C++ that takes at least 50%
less lines of code in comparison with plain vanilla C++ I will stick
with it unless there are other important considerations that can move me
to C++.
At the same time C++ is less restrictive, support multiparadigm
programming and can be 10 times (or more) efficient than Java :-).
Like OO, Java is definitely oversold and does not provide flexibility and
efficiency of the server side in comparison with C++ (at least with today's
implementations of Java). If you have nice hardware and not so many visitors
that's OK. If this is not the case, C++ wins. And to add insult to injury
C++ debuggers are generally better then Java debuggers :-)
Dr. Nikolai Bezroukov
Notes:
- This is a Spartan WHYFF (We Help
You For Free) site written by people for whom English
is not a native language.
Some amount of grammar and spelling errors should be
expected.
- The site contain some broken links
as it develops like a living tree...
Please try to use Google, Open directory,
etc. to find a replacement link (see
HOWTO search the WEB for details). We would appreciate
if you can
mail us a correct link.
|
|
|
|
To preserve bandwidth for humans as opposed to robots News now are
moved in a separate subdirectory. As with any move some of them were lost...
Sorry for any inconvenience.
by dkf (304284)
C/C++ are the languages you'd want to go for. They can do *everything*,
have great support, are fast etc.
Let's be honest here. C and C++ are very fast indeed if you use them
well (very little can touch them; most other languages are actually
implemented in terms of them) but they're also very easy to use
really badly. They're genuine professional power tools: they'll do what
you ask them to really quickly, even if that is just to spin on the
spot chopping peoples' legs off. Care required!
If you use a higher-level language (I prefer Tcl, but you might prefer
Python, Perl, Ruby, Lua, Rexx, awk, bash, etc. - the list is huge) then
you probably won't go as fast. But unless you're very good at C/C++
you'll go acceptably fast at a much earlier calendar date. It's just
easier for most people to be productive in higher-level languages. Well,
unless you're doing something where you have to be incredibly close
to the metal like a device driver, but even then it's best to keep the
amount of low-level code small and to try to get to use high-level things
as soon as you can.
One technique that is used quite a bit, especially by really experienced
developers, is to split the program up into components that are then
glued together. You can then write the components in a low-level language
if necessary, but use the far superior gluing capabilities of a high-level
language effectively. I know many people are very productive doing this.
About: Sunifdef is a command line tool for eliminating superfluous
preprocessor clutter from C and C++ source files. It is a more powerful
successor to the FreeBSD 'unifdef' tool. Sunifdef is most useful to
developers of constantly evolving products with large code bases, where
preprocessor conditionals are used to configure the feature sets, APIs
or implementations of different releases. In these environments, the
code base steadily accumulates #ifdef-pollution as transient configuration
options become obsolete. Sunifdef can largely automate the recurrent
task of purging redundant #if logic from the code.
Changes: Six bugs are fixed in this release. Five of these
fixes tackle longstanding defects of sunifdef's parsing and evaluation
of integer constants, a niche that has received little scrutiny since
the tool branched from unifdef. This version provides robust parsing
of hex, decimal, and octal numerals and arithmetic on them. However,
sunifdef still evaluates all integer constants as ints and performs
signed integer arithmetic upon them. This falls short of emulating the
C preprocessor's arithmetic in limit cases, which is an unfixed defect.
August 20, 2007 | www.artima.comSummary Readily available
frameworks and APIs can make developers very productive. However, they
can also limit developers' imagination, explains Overstock.com principal
software engineer Chris Maki in this brief audio interview with Artima.
One of Java's key strengths today is its multitude of APIs and frameworks,
addressing a wide range of problem domains. Such APIs and frameworks
provide ready-made answers to many programming problems. Indeed, programming
in Java today is to a great extent an exercise in learning to identify
and use APIs and frameworks suited to a problem area.
Using readily available APIs and frameworks can keep a developer
at a fairly high level of abstraction: Part of a Java developer's productivity
comes from not having to reinvent the wheel with every project—instead,
a developer can apply high-level frameworks to a set of similar projects
and problems, expecting generally high-quality results.
While productivity is very important in a developer's work, so is
originality and innovation. In a conversation at JavaOne earlier this
year, Chris Maki, a principal software engineer at Overstock.com and
leader of the Utah Java Users Group, told us that the frameworks and
APIs that make us so productive also impose upon us their design decisions
and their solutions to problems, sometimes leaving little room for innovation
and originality:
When I first started as a software engineer... we used to think
that anything you could think of, that anything you could conceive
of, was possible with software, and that the sky was the limit.
And we tried to do that. Today, it seems like we look at the Java
APIs and the different packages, and say, "Well, this is all we
can do. This is what the APIs tell us."
Back in those days, we were doing more typical client-server
type applications. We would have a database, and most of the logic
was in what we would call a fat client today. In the graphical or
presentation layer, we would [use] animations... One of the applications
I was working on was a pipeline application, which doesn't sound
very sexy or interesting, yet as data moved through the pipeline,
we used animations to show pictures of the different places the
product would go, have [part of the UI] fade in and fade out...
to visualize this movement of data...
If I was going to do that in Java [today], it would seem to me
like a daunting task, given the complexities of some of the Swing
APIs. I know that they made a lot of improvements, but when I sit
down to do an app today, I don't think [that] whatever I can think
of I'm going to do. I typically think the APIs and the design patterns
tell me I've got to do this [or that]. While we made a lot of improvements
by having cross-platform code, and write once, deploy anywhere kind
of things, we've also limited our thinking.
 |
Chris Maki, principal software engineer at
Overstock.com, talks
about how frameworks and APIs can limit developers' imaginations.
(3 minutes 10 seconds) |
To what extent do you think there is a role for the in-the-trenches
enterprise developer to devise innovative and out-of-the-box solutions?
In your projects, how do you mitigate the need for productivity that
comes from following the prescriptions of a high-level framework, and
the desire to come up with original and sometimes surprising, solutions?
The author discusses how the use of generic programming in C++
can lead to conflicts with object-oriented design principles.
He demonstrates how a technique known as type erasure can often
be used to resolve these conflicts. An in-depth example is presented:
any_iterator, a type-safe, heterogeneous C++ iterator.
In his glossary of terms[1],
Bjarne Stroustrup has described the C++ programming language that
he created as "a general-purpose programming language [...] that
supports procedural programming, data abstraction, object-oriented
programming, and generic programming." The fact that C++ supports
these different programming paradigms makes it unique—and uniquely
powerful—among today's programming languages. On the other hand,
it should not come as a surprise that the close coexistence of such
vastly different paradigms can cause considerable friction, especially
in large software systems.
In this article, I will focus on the tension that can occur when
object-oriented programming (classes, objects, and runtime polymorphism
come to mind) meets generic programming (algorithms, templates,
and compile time polymorphism come to mind).
The article consists of two parts. In the first part, I will
demonstrate how the coexistence of OO and generic programming can
cause serious friction in real-life software engineering. I will
then explain how a technique known as type erasure can be used to
alleviate these problems.
The second part explains how type erasure can be implemented
in C++. Specifically, I will elaborate on an example used in the
first part, namely, C++ iterator type erasure. I will discuss the
design and implementation of a class template[2]
any_iterator that provides type erasure for C++ iterators.
The Trouble with Object-Oriented and Generic Programming
A Little Trivia Quiz
Let us start with a little trivia quiz. Who said the following
things about object-oriented programming?
- "I find OOP technically unsound."
- "I find OOP philosophically unsound."
- "I find OOP methodologically wrong."
- "I have yet to see an interesting piece of code that comes
from these OO people."
- "I think that object orientedness is almost as much of a
hoax as artificial intelligence."
All the quotes above are from an interview with Alexander Stepanov[3],
the inventor of the STL and elder statesman of generic programming.
As a practicing software engineer who works on large commercial
software projects, I know better than to hold such a negative view
of OO programming. But when someone like Alexander Stepanov says
such a thing, then I don't think it should be taken lightly.
My experience as a software engineer in the trenches has taught
me that there is much more tension, if not contradiction or incompatibility,
between OO programming and generic programming than many people
care to admit. It is easy to dismiss Alexander Stepanov's rejection
of OO programming as extreme and unrealistic. It is much harder
to make the OO and generic programming paradigms coexist and cooperate
in real-life software engineering.
In the next three sections, I will illustrate the problem with
an example from the real world, and I will suggest a less radical
remedy than to disavow OO programming as a tool in software design
altogether.
SWIG is a software development tool that connects programs written in
C and C++ with a variety of high-level programming languages. SWIG is
primarily used with common scripting languages such as Perl, PHP, Python,
Tcl/Tk, and Ruby, however the list of supported languages also includes
non-scripting languages such as C#, Common Lisp (CLISP, Allegro CL,
UFFI), Java, Modula-3, OCAML, and R. Also several interpreted and compiled
Scheme implementations (Guile, MzScheme, Chicken) are supported. SWIG
is most commonly used to create high-level interpreted or compiled programming
environments, user interfaces, and as a tool for testing and prototyping
C/C++ software. SWIG can also export its parse tree in the form of XML
and Lisp s-expressions.
Release focus: Minor feature enhancements
Changes:
shared_ptr support was added for Java and C#. STL support for Ruby was
enhanced. Windows support for R was added. A long-standing memory leak
in the PHP module was fixed. Numerous fixes and minor enhancements were
made for Allegrocl, C#, cffi, Chicken, Guile, Java, Lua, Ocaml, Perl,
PHP, Python, Ruby, and Tcl. Warning support was improved.
Hello, world! Today, I (Stephan T. Lavavej, library dev) would
like to present one question and one Orcas bugfix.
First,
the question: What is the future of C++? Or, phrased crudely,
does C++ have a future? Will it grow and evolve, with programmers
using it in new application domains and finding ways to use it more
effectively? Or will it stagnate, with programmers using it in
fewer and fewer application domains until nothing new is being invented
with it and it enters "maintenance mode" forever? After C++'s
explosive growth over nearly the last three decades, what is going to
come next?
This
question has a finite horizon. No language can possibly be eternal,
right? (Although C is certainly making a good run for it.)
I don't expect C++ to be vibrant in 2107, or even 2057. 50 years
is an almost incomprehensible span of time in the computer industry;
the transistor itself is turning 60 years old this year. So when
I ask, "what is the future of C++?", I'm really asking about the next
10, 20, and 30 years.
Here's
how I see it. First, consider C++'s past. As it happens,
Bjarne Stroustrup recently released an excellent paper covering C++'s
recent history, "Evolving a language in and for the real world: C++
1991-2006", at
http://research.att.com/~bs/hopl-almost-final.pdf
. There's also a wonderful 1995 interview with Alexander Stepanov
at
http://stepanovpapers.com/drdobbs-interview.html
which explains C++'s machine model.
C++'s
machine model has a relentless focus on performance, for several reasons.
Being derived from C, which was "fat free", is one reason - in the realm
of performance, C++ has never had to lose weight. It's just had
to avoid gaining weight. Additions to C++ have always been structured
in such a way as to be implementable in a maximally efficient manner,
and to avoid imposing costs on programmers who don't ask for them.
(As the Technical Report on C++ Performance, now publicly available
at
http://standards.iso.org/ittf/PubliclyAvailableStandards/c043351_ISO_IEC_TR_18015_2006(E).zip
, explains, exception handling can be implemented with the "table" approach,
which imposes minimal run-time overhead on code that doesn't actually
throw. VC uses the "code" approach on x86 because of historical
reasons, although it uses the "table" approach on x64 and IA-64.)
Historically, C++ ran on very small and slow machines that couldn't
bear any unnecessary costs. And now, C++ is used to tackle huge
problems where performance is critical, so unnecessary costs are still
unthinkable!
Aside
from the elevator controllers and supercomputers, does performance still
matter for ordinary desktops and servers? Oh yes. Processors
have finally hit a brick wall, as our Herb Sutter explained in 2005
at
http://gotw.ca/publications/concurrency-ddj.htm
. The hardware people, who do magical things with silicon, have
encountered engineering limitations that have prevented consumer processors
from steadily rising in frequency as they have since the beginning of
time. Although our processors aren't
getting any slower, they're also not getting massively faster anymore
(at least, barring some incredible breakthrough).
And anyways, there isn't plenty of room at the bottom anymore.
Our circuits are incredibly close to the atomic level, and atoms aren't
getting any smaller. The engineering limit to frequency has simply
arrived before the physical limit to circuitry. Caches will continue
to get larger for the foreseeable future, which is nice, but having
a cache that's twice as large isn't as nice as running everything at
twice the frequency.
As programmers, we are faced with a future
that looks radically different from what we're used to: the processors
we have today are about as fast as we will ever have.
The computer industry undergoes constant change, of course, but we rather
liked the kind of change that made our programs run twice as fast every
couple of years with no extra work on our part.
Undaunted,
the hardware engineers have begun putting multiple cores in each processor,
which is actually increasing overall performance quite nicely.
(I'd sure like to have a quad-core machine at work!) But not everything
is as embarrassingly parallel as compiling. Single-core performance
still matters. And the problems that we, as programmers, are asked
to solve are getting bigger every year, as they always have.
Therefore,
I say that C++ is uniquely positioned to weather this performance storm.
Other languages will continue to find uses in application domains that
aren't performance-critical, or that are embarrassingly parallel.
But whenever the speed at which an individual core crunches stuff matters,
C++ will be there. (For example, 3D games. When Halo Infinity
is released in 2027 - and yes, I totally just made that up - I fully
expect it to be written in C++.)
Among
C++0x's biggest core language changes will be variadic templates, concepts,
and rvalue references. The first two will make writing templates
a lot more fun. That's great, because templates are a powerful
way to produce highly efficient code. And the third will address
one of the flabbiest areas in C++03 - its tendency to make copies of
values. (Things that have value semantics are great - unnecessary
copies aren't.) By eliminating unnecessary copies through "move
semantics", rvalue references will make value-heavy code, like any code
that uses the STL, significantly faster. The future is bright!
Actually Spolsky does not understand the role of scripting languages.
But hi is right of target with his critique of OO. Object oriented programming
is no silver bullet.
Dec
14, 2006
(InfoWorld)
Joel Spolsky is one of
our most celebrated pundits
on the practice of software
development, and he's full of
terrific insight. In a recent
blog post, he decries the fallacy
of
"Lego programming" -- the
all-too-common assumption that
sophisticated new tools will
make writing applications as
easy as snapping together children's
toys. It simply isn't so, he
says -- despite the fact that
people have been claiming it
for decades -- because the most
important work in software development
happens before a single line
of code is written.
By way
of support, Spolsky reminds
us of a quote from the most
celebrated pundit of an earlier
generation of developers. In
his 1987 essay
"No Silver Bullet," Frederick
P. Brooks wrote,
"The essence of a software entity
is a construct of interlocking
concepts ... I believe the hard
part of building software to
be the specification, design,
and testing of this conceptual
construct, not the labor of
representing it and testing
the fidelity of the representation
... If this is true, building
software will always be hard.
There is inherently no silver
bullet."
As Spolsky
points out, in the 20 years
since Brooks wrote "No Silver
Bullet," countless products
have reached the market heralded
as the silver bullet for effortless
software development. Similarly,
in the 30 years since Brooks
published "
The Mythical Man-Month"
-- in which, among other things,
he debunks the fallacy that
if one programmer can do a job
in ten months, ten programmers
can do the same job in one month
-- product managers have continued
to buy into various methodologies
and tricks that claim to make
running software projects as
easy as stacking Lego bricks.
Don't you
believe it. If, as Brooks wrote,
the hard part of software development
is the initial design, then
no amount of radical workflows
or agile development methods
will get a struggling project
out the door, any more than
the latest GUI rapid-development
toolkit will.
And neither
will open source. Too often,
commercial software companies
decide to turn over their orphaned
software to "the community"
--
if such a thing exists --
in the naive belief that open
source will be a miracle cure
to get a flagging project back
on track. This is just another
fallacy, as history demonstrates.
In 1998,
Netscape released the source
code to its Mozilla browser
to the public to much fanfare,
but only lukewarm response from
developers. As it turned out,
the Mozilla source was much
too complex and of too poor
quality for developers outside
Netscape to understand it. As
Jamie Zawinski
recounts, the resulting
decision to rewrite the browser's
rendering engine from scratch
derailed the project anywhere
from six to ten months.
This is
a classic example of the fallacy
of the mythical man-month. The
problem with the Mozilla code
was poor design, not lack of
an able workforce. Throwing
more bodies at the project didn't
necessarily help; it may have
even hindered it. And while
implementing a community development
process may have allowed Netscape
to sidestep its own internal
management problems, it was
certainly no silver bullet for
success.
The key
to developing good software
the first time around is doing
the hard work at the beginning:
good design, and rigorous testing
of that design. Fail that, and
you've got no choice but to
take the hard road. As Brooks
observed all those years ago,
successful software will never
be easy. No amount of open source
process will change that, and
to think otherwise is just more
Lego-programming nonsense.
About 10 months ago, I was writing a library. As I was writing
it, I started to look at the whole issue of notifying the caller
of errors. In typical fashion, I tried to optimize the error
handling problem rather than just do the right thing, and just
use error codes. I did a ton of research. Here is a current
list of links and articles on the subject.
Getting Started
To get you started here are some good starting points. They
both received a lot of attention on the internet.
A colorful
post by Damien Katz.
A nice
opinion piece that is pro-error codes by the famous Joel
of
Joel on Software.
Read my
original post with excellent comments by
Daniel Lyons,
Paul Clegg, and Neville of the North.
Nutshell
The default and standard way of handling errors since the
begining is to just use error codes with some convention of
noticing them. For example, you could document the error condition
with an api and then set a global variable for the actual code.
It is up to the programmer calling the function to notice the
error and do the right thing.
This is the technique used by operating systems and most
libraries. Historically, these systems have never been consistent
or compatable with other conventions. The most evolved system
for this would probably be the
Microsoft COM system. All functions return an HRESULT, which
is essentially an error code.
The next system was the ‘exception-handling’ system. In this
system errors cannot be ingored. Exception handlers are declared,
optionally, at a given scope. If an exception is thrown (ie
an error has occurred), handlers are searched up the stack until
a matching handler is found.
IMHO, the exception system isn’t used properly in 90% of
the cases. There is a fine balance between a soft error and
something exceptional. The syntax also tends to get in the way
for even the simplest of errors. I agree that there should be
errors that are not ignored, but there has to be a better way.
So, old skoolers are ‘we use error codes, and we
like them, dammit - aka, super disciplined programming,
usually for real-time, embedded and smaller systems.
The new schoolers are, ‘you have to be kidding about error-codes,
use exceptions’ - aks, yeah, we use exceptions, that is what
the language gives us… and btw, no, we don’t mind typing on
our keyboards a lot
Somehow, there has to be a better way. Maybe it will be system
or application, specific.
Moving On - Old / New Ideas
If you don’t mind it being a C++ article,
here is an amazing one from Andrei Alexandrescu and Petru
Marginean. (Andrei is widely known for his great work on Policy
Based design with C++, which is excellent) The artcle is well
written and practical. In fact, the idea was so good, the language
‘D’ made it part of the language.
Here is an example:
void User::AddFriend(User& newFriend)
{
friends_.push_back(&newFriend);
try
{
pDB_->AddFriend(GetName(), newFriend.GetName());
}
catch (...)
{
friends_.pop_back();
throw;
}
}
10 lines, and this is for the super-simple example.
void User::AddFriend(User& newFriend)
{
friends_.push_back(&newFriend);
ScopeGuard guard = MakeObjGuard(friends_, &UserCont::pop_back);
pDB_->AddFriend(GetName(), newFriend.GetName());
guard.Dismiss();
}
In D it would look even cleaner:
void User::AddFriend(User& newFriend)
{
friends_.push_back(&newFriend);
scope(failure) friends_.pop_back();
pDB_->AddFriend(GetName(), newFriend.GetName());
}
IMHO, I think exception handling will move more towards systems
like this. Higher level, simpler and cleaner.
Other interesting systems are the ones developed for Common
Lisp, Erlang, and Smalltalk. I’m sure Haskell has something
to say about this as well.
The Common Lisp and Smalltalk ones are similar. Instead of
forcing a mechanism like most exception handlers. These systems
give the exception ‘catcher’ the choice of retry’ing or doing
something different at the point of the exception. Very powerful.
Speaking of smalltalk, here is an excellent
article called
Subsystem Exception Handling in Smalltalk. I highly recommend
it.
My Recomendation
If you are building a library, use error codes. Error codes
are much easier to turn into exceptions by the language wrapper
that will eventually be built on top.
When programming, don’t get trapped into think about the
little picture. A lot of these errors are just pawns in the
grand scheme of assuring that you have all of your resources
in place before you begin your task at hand. If you present
your code in that manner, it will be much easier to understand
for all parties.
More Links
Error Codes vs. Exceptions by Damien Katz.
opinion piece that is pro-error codes by the famous Joel
of
Joel on Software.
Read my
original post with excellent comments by
Daniel Lyons,
Paul Clegg, and Neville of the North.
Microsoft COM
D Language - Exception Safe Programming
Subsystem Exception Handling in Smalltalk - nice section
on history as well
http://www.gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html
A nice long thread on comp.lang.c++.moderated
*Slightly Wacky, But Neat *
http://www.halfbakery.com/idea/C20exception20handling_20macros
http://www.nicemice.net/cexcept/ http://home.rochester.rr.com/bigbyofrocny/GEF/
http://www.on-time.com/ddj0011.htm
|
About:
Doxygen is a cross-platform, JavaDoc-like documentation
system for C++, C, Objective-C, C#, Java, IDL, Python, and
PHP. Doxygen can be used to generate an on-line class browser
(in HTML) and/or an off-line reference manual (in LaTeX
or RTF) from a set of source files. Doxygen can also be
configured to extract the code-structure from undocumented
source files. This includes dependency graphs, class diagrams
and hyperlinked source code. This type of information can
be very useful to quickly find your way in large source
distributions.
Changes:
This release fixes a number of bugs that could cause it
to crash under certain conditions or produce invalid output.
|
[Feb 14, 2006]
OOP Criticism Object Oriented Programming Oversold by B. Jacobs.
OOP criticism and OOP problems. The emperor has no clothes! Reality
Check 101. Snake OOil. Updated: 5/14/2005
I am not saying OOP is useless, per se; many are just frustrated
with the fact that OOP has slowed or even reversed programming progress
in other areas. I have debated OO fans that appear ignorant to some
nifty techniques available in old-fashioned procedural programming.
Often times someone will compare C to C++ and conclude that the differences
are paradigm differences.
... ... ...
OOP is the greatest boon for those who like to write bloated code.
I am not saying that all OOP code is bloated. But, something
or someone is encouraging the practice of taking the most amount of
code to do the fewest things. Further, OOP has added new ways to write
bloated code that procedural has a hard time competing with. Hypothetical
example for adding two numbers:
... ... ...
OOP sometimes takes credit for ideas that are not necessarily part
of OOP. For example, some criticize the variable scoping rules of procedural
languages, saying that OOP improved it. However, some procedural languages
like Pascal already allowed multiple levels of variable and procedure
scoping before OOP became a mainstream fad.
Having variable parameter types and quantities has been part of many
interpreted procedural languages a good time before OOP became a mainstream
fad. For example, in XBase you can use the Type() function to query
a parameter type. (It lacked formality, but it was there.)
Summary
It is hard to summarize such a complex,
involved topic; but here goes an attempt anyhow. Most problems with
OOP can be summed up in a handful of general principles.
-
The real world does not change
in a hierarchical way for the most part. You can force a hierarchical
classification onto many things, but you cannot force change requests
to cleanly fit your hierarchy. Just because a structure is conceptually
simple does not necessarily mean it is also change-friendly.
-
There are multiple orthogonal
aspect grouping candidates and the ones favored by OOP are probably
not the best in many or most cases. OO literature is famous for
only showing changes that benefit the aspects favored by OO. In
the real world, changes come in many aspects, not just those favored
or emphasized by OO. Encapsulating by just a single dimension is
often a can of worms.
-
OOP's granularity of grouping
and separation is often larger than actual changes and variations.
OOP's alleged solutions to this, such as micro-methods and micro-classes,
create code management headaches and other problems.
-
OOP designs tend to reinvent the
database in application code. In particular, OO generally reinvents
navigational databases, which were generally rejected in the 1970's
and replaced by
relational techniques. It is my opinion that relational theory
is generally superior to navigational theory. It can provide more
structure, cleaner queries, and automated optimization. Plus, the
usage of databases allows multiple tools and languages to share
and use data without writing explicit access methods for each new
request.
-
There is no decent, objective,
and open evidence that OOP is better. It may just all be subjective
or domain-specific. Software engineering is sorely lacking good
metrics.
-
There is a large lack of
consistency in OO business design methodologies. Procedural/relational
approaches tend to be more consistent in my experience. (Group code
by task, and use database to model noun structures and relations.)
-
Many of the past sins that OOP is
trying to fix are people and management issues (incentives,
training, etc.), and not the fault of the paradigms involved. Until
true A.I. comes along, no paradigm will force good code. If anything,
OOP simply offers more ways to screw up.
OOP Myths Debunked:
- Myth: OOP is a proven general-purpose technique
- Myth: OOP models the real world better
- Myth: OOP makes programming more visual
- Myth: OOP makes programming easier and faster
- Myth: OOP eliminates the "complexity" of "case" or "switch"
statements
- Myth: OOP reduces the number of places that require changing
- Myth: OOP increases reuse (recycling of code)
- Myth: Most things fit nicely into hierarchical taxonomies
- Myth: Sub-typing is a stable way to model differences
- Myth: Self-handling nouns are more useful than self-handling
verbs
- Myth: Most operations have one natural "primary noun"
- Myth: OOP does automatic garbage-collection better
- Myth: Procedural cannot do components well
- Myth: OO databases can better store large, multimedia data
- Myth: OODBMS are overall faster than RDBMS
- Myth: OOP better hides persistence mechanisms
- Myth: C and Pascal are the best procedural can get
- Myth: SQL is the best relational language
- Myth: OOP would have prevented more Y2K problems
- Myth: OOP "does patterns" better
- Myth: Only OOP can "protect data"
- Myth: Implementation changes significantly more often than interfaces
- Myth: Procedural/Relational ties field types and sizes to the
code more
- Myth: Procedural cannot extend compiled portions very well
- Myth: No procedural language can re-compile at the routine level
- Myth: Procedural/Relational programs cannot "factor" as well
- Myth: OOP models human thought better (Which human?)
- Myth: OOP is more "modular"
- Myth: OOP divides up work better
- Myth: OOP "hides complexity" better
- Myth: OOP better models spoken language
- Myth: OOP is "better abstraction"
- Myth: OOP reduces "coupling"
- Myth: OOP does multi-tasking better
- Myth: OOP scales better
- Myth: OOP is more "event driven"
- Myth: Most programmers prefer OOP
- Myth: OOP manages behavior better
[Feb 14, 2006] Free Microsoft compilers
-
Get a Free Copy of Visual Studio 2005 Express Editions
Download a copy of Visual Studio 2005 Express
Editions today – easy to use tools for the hobbyist, novice and student
developer.
-
Visual C++ Toolkit 2003 The Microsoft Visual C++ Toolkit 2003 includes
the core tools developers need to compile and link C++-based applications
for Windows and the .NET Common Language Runtime – compiler, linker,
libraries, and sample code.
In case of broken links
please try to use Google search. If you find the page please notify
us about new location
Generally search engines are the only way to keep up in this area. So
links below are just a small sample that I have found useful.
Bookshelf
Magazines:
See also ../Links/links2magazines.shtml
See also
C++
Resource Directory: Links to C++ info, courses and resources on
a variety of compilers and extensions to the C++ language. For OO terminology
see
Glossary of Object-Oriented Terminology for Business and
www.webreference.com
Dinkum C-C++ Library Reference by P.J. Plauger.
The Standard Template Library: Reference to STL maintained by
Silicon Graphics.
C++ Reference Material -- nice site
The
ISO/ANSI C++ Standard: New C++ standard as of 1998.
g++ info at
Cygnus.
C++ Standards FAQ
C++ Standards
and Architecture, Nat Myers
Information About IOstreams
Operator Precedence and Associatively Rules in C & C++
C++ quick-reference -- small printable quick reference
C++ Programming Language Tutorial Handouts
C++ Technical Manual: An extensive description of the C++ language,
including the new standard.
Learning C++: A student's on-line C++ tutorial.
C++ FAQ: Descriptions and examples of the syntax of C++.
Bruce Eckel's
Home Page - C++ and Java: Eckel's book Thinking in C++.
Can serve as reference
ACM Classic
Articles
COMP435 - References and Pointers a-nd Constants, Oh My!
Microsoft Visual Studio 6.0 Service Pack 5 - Download
Namespaces:
Scoping and visibility rules:
-
O'Reilly Network Programming with Exceptions in C++ [May. 05, 2003]
- *****
Handling Exceptions in C and C++, Part 1 by Robert Schmidt, May
10, 1999 In his inaugural column, Robert Schmidt shows you how to
handle exceptions in C++.
-
Handling Exceptions in C and C++, Part 2
-
Handling Exceptions in C and C++, Part 3
-
Handling Exceptions in C and C++, Part 4
-
Handling Exceptions, Part 5
-
Handling Exceptions, Part 6
-
Handling Exceptions, Part 7
-
Handling Exceptions, Part 8
-
Handling Exceptions, Part 9
-
Handling Exceptions, Part 10
-
Handling Exceptions, Part 11
Handling Exceptions, Part 12
-
Handling Exceptions, Part 13
-
Handling Exceptions, Part 14
-
Handling Exceptions, Part 15
- EDM-2
- OOPS Avenue - C++ Exceptions -short intro
-
C++ Exceptions
-
-- a very good paper
-
March 96 - Using C++ Exceptions in C
-
SPC Seminar Series - C++ Exceptions and C++ Under the Hood
-
Exceptions: Using MFC Macros and C++ Exceptions
-
C++ Exceptions
-
MFC Programmer's SourceBook : C++ & MFC
- EDM/2
- OOPS Avenue - C++ Exceptions
-
Exception Handling Topics (C++)
-
Exception Handling Differences
-
C++ Exceptions. Review.
-
C++ Exceptions
- Teach Yourself C++, 5th ed. Al Stevens. MIS:Press (1997).
- C++ How to Program, 2nd ed. Deitel & Deitel. Prentice-Hall
(1998).
-
Error Handling with C++ Exceptions, Part 1
-
March 96 - Using C++ Exceptions in C
-
Software Techniques/Structured Exception Handling - slides
-
Exceptions (see Ch 16) -- slides by David Till
- Java exception handling -- slightly different, but some materials
might be useful
-
Handling Errors with Exceptions
The Java TM Tutorial Start of Tutorial > Start of Trail Search Feedback
Form Trail : Essential Java Classes Lesson: Handling Errors with
Exceptions If there's a golden rule of programming it's this: Errors
occur in software programs.
-
Exceptions in Java - JavaWorld July 1998 by Bill Venners. For
those of you who need a refresher on exceptions, this cover story
companion piece is a valuable tutorial on the nuts and bolts of
what exceptions are and how they work in the Java language and virtual
machine.
-
Designing with exceptions - JavaWorld July 1998 -- This installment
of the Design Techniques column discusses design guidelines that
pertain to exceptions. It focuses primarily on how to decide when
to use exceptions, and gives several examples
-
How exceptions work - JavaWorld June 1996 -- Comprising one
of the critical features of the Java programming language, exceptions
allow for changing the flow of control when some important or unexpected
event, usually an error, has occurred.
How the Java virtual machine handles exceptions - JavaWorld January
1997 --All Java programs are compiled into class files that
contain bytecodes, the machine language of the Java virtual machine.
This article takes a look at the way exceptions are handled by the
Java virtual machine, including the exception table.
Dealing with Exceptions from Sun's Java Tutorial
****
TutorialIndex.com C and C++ Pointers and Memory -- nice collection of
links
*****
Tourist Guide to Pointer Traps
Data Abstraction and Structures Using C++ Headington and Riley Chapter 7
Pointers and Dynamic Data
c, c++, c__,Pointers Tutorial.
C++ Tutorial 3.3, Pointers. -- good tutorial
apcmag:
Programming July 99: C++ pointers (Jun 30, 1999)
Pointer Variables --slide show here is another one
Learning C++
C-C++ Pointers tutorial
Humor
C++ style and pointers
Book reviews
Reference
A lot of things depend on the quality of complier, see for example
Coyote Gulch Productions - Benchmarking Intel C++ against GNU gcc on Linux
Generally Intel compiler is a better optimizing compilers that any of the
competitors.
C++ Data
Display Debugger (RPI - ACM)
Visual C++ Guide - Debugging
Program Styles & Debugging Tools in Visual C++
Debugging with MS Visual C++
Visual Studio
Unix
Mistakes the compiler doesn't catch (the hardest problems to solve sometimes)
-
cin/cout outputs wrong number of items or just completely
skips some
-
Check that you have arrows, not commas, between every 2 items
(variables, strings, function calls, etc., all count as separate items.
-
Loop or decision statement doesn't work
-
Check for semicolons at the end of a loop or decisiont statement. They
don't belong there (
if, do, while, for, etc. do not
take a semicolon at the end of the line)!
-
switch/case statement 'bleeds' from one case to the
next
-
There must be a
break; at the end of every case
in a switch() block.
-
Wrong answer to a seemingly correct formula
-
Remember operator precedence! Start by adding lots of parentheses--it
can't hurt to have a lot of them! This is especially important in complex
formulas where the precedence may be obvious to you, but not to the
compiler.
-
BITPEN Week 13 Lecture 1 - C++ Debugging on Unix
Frequently asked questions about the GNU C++ compiler - debugging on SVR4
systems
"How do I get debugging to work on my System V Release
4 system?"
Most systems based on System V Release 4 (except Solaris)
encode symbolic debugging information in a format known as `DWARF'.
Although the GNU C compiler already knows how to write
out symbolic debugging information in the DWARF format, the GNU C++
compiler does not yet have this feature yet. However, work is in progress
for DWARF 2 debug support for gcc and g++ and will be available in a
future release (probably 2.8.0).
In the meantime, you can get g++ debugging
under SVR4 systems by configuring gcc with the --with-stabs
option. This causes gcc to use an alternate debugging format, one more
like that used under SunOS4. You won't need to do anything special to
GDB; it will always understand the "stabs" format.
See also C programming style
Inheritance in C++
When creating the class descriptions you will see
that the example Bank Accounts classes contain three sections, namely
public, private and protected, and this latter section is something
new. Here is a simple difference between these three sections:-
· public - visible to the world and therefore
usable by any other object
· private - visible solely within one object
i.e. local to an object
· protected - visible to an object, its friends
and any derived classes
Multiple inheritance
you are familiar with C++, you know that multiple
inheritance allows an object to inherit the functionality of two or
more classes. It can be a very powerful tool, but is not without its
drawbacks. Base classes with identical function names, or even worse
base classes with common base classes, can create headaches for even
the most experienced developers.
Java gets rid of the headaches associated with multiple
inheritance by not even supporting multiple inheritance. It can be argued
that multiple inheritance isn’t really necessary even in C++. Any time
you think you need multiple inheritance it can usually be replaced by
a container or delegate pattern. The title of this article may confuse
you since Java doesn’t actually support multiple inheritance. I’m going
to show you some techniques that can be used to get the advantages of
multiple inheritance without some of the drawbacks.
In order to accomplish this goal, we first need to
know the drawbacks and advantages of multiple inheritance. Multiple
inheritance allows us to give classes with different bases new common
functionality. It allows us to add that functionality automatically
while maintaining the code for the functionality in once place. On the
other hand, multiple inheritance can cause a lot of confusion when two
base classes implement methods with the same name. This results in two
implementations for the same function identifier in the derived class.
Java fixes the problem by only allowing classes in Java to inherit functionality
from one class. This has the unfortunate side effect of removing all
of the benefits you get from multiple inheritance. This article will
show you how you can use interfaces and a delegate model to reclaim
some of those benefits.
Classes in Java can only extend one class. However,
classes can implement as many interfaces as they want. Let’s talk for
a little bit about what this means. Extending a class means the derived
class inherits all of the data members, functions, and function definitions
of the base class. The derived class can add to or completely replace
implementations of the base class functions. The derived class will
also show up as an instance of the base class when you use the operator
"instanceof". Implementing an interface means the derived class must
provide its own implementation for each function in the interface. There
is no base functionality. If a class implements two interfaces that
both happen to have identical functions, the derived class will only
have one implementation of that function. While somewhat limiting, this
removes a lot of the headaches associated with multiple inheritance.
It is impossible for a class to inherit two sets of functionality for
the same function name. If it happens to inherit the same function name
from two different interfaces, the class is forced to resolve the conflict
and callers to the class do not have to figure out which implementation
to call.
Look at the version 001 of the Java files included
with this article (see link at end of article). This program draws a
line on the screen in Cartesian coordinates where the origin is in the
lower left hand corner of the screen, the x-axis is positive to the
right, and the y axis is positive to the top. Screen coordinates on
the other hand have the origin at the upper left corner of the screen
with the y-axis positive to the bottom. There are a few things that
you should note about this program. First, both classes implement the
functions called mapWorldToScreen and mapScreenToWorld. These functions
convert screen coordinates to Cartesian coordinates and vice versa.
If you want to change how your space is mapped (perhaps you would like
to change the origin of the Cartesian space), you will need to make
changes to both files. Second, CLine has to know that its parent is
a CCartesianPlane object, and CCartesianPlane expects CLine as its child.
This causes CLine to be strongly coupled to CCartesianPlane. If we wanted
to add a new shape, it would be nearly impossible at this point. While
not really dealing with multiple inheritance, strong coupling is something
you generally want to avoid because it reduces the flexibility and reusability
of your code.
Version 002 takes a first step towards multiple inheritance
by defining an interface that both classes can support to map points
between the screen and Cartesian spaces. We now have two disjoint classes
with similar functionality that can be referenced the same way. The
cast to CCartesianPlane in CLine has been changed to a cast to ICoordinateSpace.
It is worth noting here that casting an object like this is considered
to be weak object oriented program. It could be argued that the ICoordinateSpace
interface should support the concept of a parent instead of using the
Component’s parent. When we are dealing with interfaces, I usually break
this rule of OOP. My feeling is that the class knows what interfaces
it uses and can act accordingly if a member variable does not support
that interface.
The implementations of ICoordinateSpace in CCartesianPlane
and CLine still duplicate a lot of code. Version 003 puts all of this
duplicated code into a new class called CCoordinateSpaceImplBase. This
new class provides a base implementation of ICoordinateSpace. CLine
and CCartesianPlane now contain an instance of CCoordinateSpaceImplBase.
The implementations of ICoordinateSpace are now routed to this data
member. Had the classes been derived from CCoordinateSpaceImplBase,
these calls would have looked something like "super.mapScreenToWorld(p)".
CCartesianPlane still provides its own implementation of mapScreenToWorld
and mapWorldToScreen. In a sense, it is overriding the functionality
of its 'base class' CCoordinateSpaceImplBase.
The base functionality for ICoordinateSpace is now
contained in a single class. If we want to change how our coordinate
space works, all we need to do is change this one file. We have now
recovered two of the benefits of multiple inheritance. The third benefit,
automatically inheriting default behavior, will not be possible with
this method. However, if you compare the code in CLine and CCartesianPlane,
you will notice that it is almost identical. You could copy this code
directly into a new class to obtain the new results. So, while the inheritance
isn’t quite automatic, it is extremely easy to add.
Although the examples themselves aren’t very exciting,
it could be jazzed up with new shapes or perhaps even transforms to
rotate and scale the coordinate spaces. What is exciting is your ability
to approximate multiple inheritance in Java. I hope you find this technique
as useful as I have. If you have any comments or questions, please e-mail
naoursla@iftech.com.
Multi-Inheritance_Java_Examples.zip contains code
examples described by this article.
Get
Multi-Inheritance_Java_Examples.zip (16K).
You do know what "private parts" are, right? ;) Now with the help of
Grady Booch you can understand what are friends for! :)
... C++ offers even more flexible control over the visibility of
member objects and member functions. Specifically, members may be placed
in the public, private, or protected parts of a class. Members declared
in the public parts are visible to all clients; members declared in
the private parts are fully encapsulated; and members declared in the
protected parts are visible only to the class itself and its subclasses.
C++ also supports the notion of *friends*: cooperative classes
that are permitted to see each other's private parts.
-- Grady Booch, "Object Oriented Design with Applications"
A friend function is not a class member and yet it
can have access to private and protected members of a class. Friends
are not called by using member selection operators such as “ . or ->”
unless they are members of another class. Friend functions can be defined
inside a class declaration. Friend functions declared within a class
are inline just like other inline member functions. These functions
act as though they were defined immediately after all class members
have been seen but before the end of the class declaration. Even though
friend functions are declared inside class declarations, they are not
considered in the scope of the enclosing class. They are normally considered
in the file scope. An entire class can be declared as a friend of another
class.
To declare a function as a friend of a class, put
the word “friend” before the function prototype in the class definition.
For example, you want to show that ClassTwo is a friend of ClassOne,
simply put the word “friend” in front of ClassTwo like:
friend class ClassTwo;
This line should be inside the definition of class
ClassOne and declared explicitly. The friendship between ClassOne and
ClassTwo is neither symmetric nor transitive. This means that ClassTwo
is a friend of ClassOne but ClassOne cannot be assumed to be a friend
of ClassTwo. Same concept applies when you have multiple classes connected
by multiple friendships. Friendship can only go one way.
A partial example of friends accessing private members
of a class goes something like this:
class ClassOne{
// friend declaration should appear before the declaration of public
and private member function
friend void ClassTwo ( ClassOne &, int); // friend declaration
public:
Count( ) { x = 0; } // constructor
Void print( ) const { cout << x << endl;} // output
Private:
Int x; // data member
};
//ClassTwo is declared as a friend
function of ClassOne
void ClassTwo( ClassOne &c, int val)
{
c.x = val;
}
int main( )
{
ClassOne counter;
counter.print ( );
ClassTwo( counter,10); // set x with a friend
Counter.print( );
Return 0;
}
The purpose of using friend function is to improve
performance. Sometimes when a member function cannot be used in a certain
operation, using friends would be able to solve that problem.
A virtual function is declared in a base class of a program
and can then be redefined in each derived class. Virtual functions give
you polymorphism, which means derived classes can implement the same function
differently. The declaration in the base class acts as a kind of template
which can be enhanced by each derived class.
- In the base class, you must begin the function declaration with
the keyword virtual.
- The keyword virtual is
not used in the derived functions.
- The number and type of parameters in the derived function must
match the number and type in the initial declaration of the virtual
function.
class vehicle { public: virtual void run();
}; void func(vehicle* v) { v->run(); }
In the above code, the 'run' method called by function 'func' is not
necessarily vehicle::run method. It may be
car::run or train::run
( where car and train are derived from vehicle class and they override the
run method). The actual run method called depends where
'v' points. If 'v'
points to a car object, then car::run is called
and so on.
While compiling the above code compiler may not see the derived classes
(car, train etc.) of vehicle class. So compiler has to somehow arrange to
call car::run or train::run depending on where 'v' points. This is called
dynamic binding.
When you have a pointer to an object, the object may actually be of a
class that is derived from the class of the pointer (e.g., a Vehicle*
that is actually pointing to a Car object). Thus there are two
types: the (static) type of the pointer (Vehicle, in this case),
and the (dynamic) type of the pointed-to object (Car, in this case).
Static typing means that the legality of a member function invocation
is checked at the earliest possible moment: by the compiler at compile time.
The compiler uses the static type of the pointer to determine whether the
member function invocation is legal. If the type of the pointer can handle
the member function, certainly the pointed-to object can handle it as well.
E.g., if Vehicle has a certain member function, certainly Car
also has that member function since Car is a kind-of Vehicle.
Dynamic binding means that the address of the code in a member
function invocation is determined at the last possible moment: based on
the dynamic type of the object at run time. It is called "dynamic binding"
because the binding to the code that actually gets called is accomplished
dynamically (at run time). Dynamic binding is a result of virtual
functions.
****
15 Polymorphism & Virtual Functions. from Thinking in C++, 2nd ed. Volume
1 ©2000 by Bruce Eckel. Here is a fast mirror of
Thinking
in C++
Polymorphism (implemented in
C++ with virtual functions) is the third essential feature
of an object-oriented programming language, after data abstraction
and inheritance.
It provides another dimension of separation of interface from implementation,
to decouple what from how. Polymorphism allows improved
code organization and readability as well as the creation of
extensible programs that can be “grown” not only during the
original creation of the project, but also when new features are
desired.
Encapsulation creates new data types by combining characteristics
and behaviors. Access control separates the interface from the implementation
by making the details private. This kind of mechanical organization
makes ready sense to someone with a procedural programming background.
But virtual functions deal with decoupling in terms of types.
In Chapter 14, you saw how inheritance allows the treatment of an
object as its own type or its base type. This ability is
critical because it allows many types (derived from the same base
type) to be treated as if they were one type, and a single piece
of code to work on all those different types equally. The virtual
function allows one type to express its distinction from another,
similar type, as long as they’re both derived from the same base
type. This distinction is expressed through differences in behavior
of the functions that you can call through the base class.
In this chapter, you’ll learn about virtual functions, starting
from the basics with simple examples that strip away everything
but the “virtualness” of the program.
****
Chapter 16- Polymorphism, late binding and virtual functions from
C++ Annotations Version 4.4.2
****
www.objectmentor.com/publications/abcpvf.pdf Abstract Classes
and Pure Virtual Functions -- not bad explanation despite OO fundamentalist
style
****
CS170 C++ Virtual Functions Lab -- Department of Computer Science, University
of Regina. From
CS170 Labs Index
****
[19] Inheritance -- virtual functions, C++ FAQs Lite, ...
C++ Inherited Virtual Function Declarations and Definitions
If a class base contains a virtual function
vf, and a class derived derived from it also contains
a function vf of the same type, then a call of vf
for an object of class derived invokes derived::vf
(even if the access is through a pointer or reference to base).
The derived class function is said to override the base class
function. If the function types are different, however, the functions
are considered different and the virtual mechanism is not invoked.
It is an error for a derived class function to differ from a base class'
virtual function in the return type only.
C++ Q&A- Inline Virtual Functions, AVI Files in EXEs, and ... by Paul
DiLascia (Microsoft) . How does C++ handle inline virtual functions? When
a function is inline and virtual, will code substitution take place or is
the call resolved using the vtable?
Eiffel vs. C++ (by Bertrand Meyer - 4 June 89)
Dynamic binding Dynamic binding is the default mechanism
for routine calls in Eiffel (achieved without any undue effect on performance).
The default policy in C++ is static binding; dynamic binding is only
applied to routines declared as ``virtual''. This may look like an acceptable
requirement to impose on programmers but I believe it is not. The whole
idea of inheritance is that you may reuse a class later on by writing
a descendant and adapting it to new uses by overriding some of the routines
of the original - within the original semantic constraints, as defined
by assertions. This should be done without impacting the original, which
may be used by many other ``client'' classes. (These concepts are explained
in my book ``Object-Oriented Software Construction, Prentice-Hall, 1988,
as the ``Open-Closed Principle'', section 2.3.) In such a case the designer
of the original routine may have had no inkling whatsoever that the
routine would ever be redefined and subjected to dynamic binding. This
is incompatible with the requirement that the original designer should
have declared the routine as virtual in the first place. Instead of
forcing the programmer to take care of low-level optimizations, the
Eiffel approach makes the compiler responsible for exploiting the performance
of static over dynamic binding. The optimizer, working on a set of classes,
generates code that applies static binding to any routine which warrants
it (because it is never redefined). Performing tedious and potentially
dangerous optimizations in a safe way should be the role of computers,
not humans.
[20] Inheritance virtual functions, C++ FAQ Lite
Virtual Functions from
C++ versus C
C++ internals - Virtual Functions
Virtual functions in constructors
Implementation issues
-
IDevResource.com - VS.NET Articles Virtual Functions and their implementation
in C By Shivesh V.
This is about C
-
Comp.compilers New Implementation of Virtual Functions in C++
A colleague informs me that virtual functions
are now more commonly implemented via thunks (instead of class vtbls).
He couldn't cite a source for this. Can you?
[I would be astonished if this were true, regardless
of whether he means real Algol-style thunks or Microsoft's misnamed
function wrappers. Every C++ compiler I've ever seen uses vtbls,
perhaps optimized to a straight call when the compiler or linker
can be sure it'll never be overridden. -John]
Comp.compilers Re New Implementation of Virtual Functions in C++
Maybe he's thinking not of the functions themselves,
but of the class
pointer adjustment for multiple inheritance.
In earlier (CFront based, I think) implementations
of multiple inheritance, class vtbls used two "words" per function:
A pointer to the function code and an offset for adjusting the
class pointer. This introduced a time and space disadvantage,
so some vendors (I remember Apple's MPW C++ compiler) introduced
language extensions to declare that some class would only be
used as a base class in single inheritance hierarchies.
Newer implementations (I specifically know
that Metrowerks CodeWarrior switched to this at some point)
only use a single "word", the pointer to the function code.
If the class pointer *does* need to be adjusted, a thunk is
generated.
This probably saves both space and time since in many programs,
the vast majority of virtual calls don't need to adjust the
class pointer (code is in most derived class or in a base class
starting at the same physical address as the most derived class).
Matthias
Etc
-
Bjarne Talks Up C++
... hierarchies. Use the style of the C++ Standard
Library rather than the ... find their
way into interfaces. Use abstract classes to define major
interfaces. ...
http://www.ddj.com/articles/2000/0050/0050g/0050g.htm
CSC270 C++ Templates
C++ Templates Tutorial see also google cashe
templates.htm+c%2B%2B+templates&hl=en
C++ Templates -- tips
C++ Templates - Integer Parameters
C++ Templates as Partial Evaluation
CSE2305-CSC2050 Topic 20 C++ Templates
Five compilation models for C++ templates (ResearchIndex)
next-prog archive- SUMMARY- C++ Templates
Instantiating C++ templates
About C++ Templates
C++ Templates and the STL from
Contents CPPvm: C++ Interface to PVM (Parallel Virtual Machine)
B5 as C++ templates
CIS 251 OOP -- C++ Templates and Genericity
comp.std.c++ frequently asked questions
Compile Time Symbolic Derivation with C++ Templates
Brad Appleton's C++ Links good collection of links
Cliff's Teaching Info and Technical Resources
CP Archives - March 1999 - The C++ Interview
by Alex Bykov
How do you rank your C++ skills on a scale of 1
to 10?
This is often the first question you will hear on
an interview for a C++ contract. You will be tempted to rate yourself
high, and you should. This is your chance to convince the client that
you are just what he is looking for--an assertive and knowledgeable
professional who will be productive either working on a team or on your
own. Naturally, though, you should be able to support the ranking you
gave yourself by doing well on the interview. This article will help
you prepare for your C++ interview.
I put together a list of 40 questions that I have
had to answer during numerous technical interviews in the past few years.
You, too, will have to answer at least some of them during an interview.
Even if you use C++ on a daily basis, it pays to go through the questions.
Most of us, no matter how experienced, use only a segment of the language
that we are most comfortable with. Brief answers are included, but you
can find more information in the references listed.
Q1. Is there anything you can do in C++
that you cannot do in C?
A1. No. There is nothing you can do in C++
that you cannot do in C. After all you can write a C++ compiler in C.
Q2. What is the difference between C++
structure and C++ class?
A2. The default access level assigned to members
of struct is public while the default access level assigned to a class
is private.
Q3. What is encapsulation?
A3. Encapsulation is welding of code and data
together into objects.
Q4. What is inheritance?
A4. Inheritance is a mechanism through which
a subclass inherits the properties and behavior of its superclass.
Q5. What is polymorphism?
A5. In Greek this means "many shapes." As a
consequence of inheritance and virtual functions, a single task (for
example, drawing a geometrical shape) can be implemented using the same
name (like draw()) and implemented differently (via virtual functions)
as each type in object hierarchy requires(circle.draw() or rectangle.draw()).
Later, when a polymorphic object (whose type is not known at compile
time) executes the draw() virtual function, the correct implementation
is chosen and executed at run time.
Q6. What would you say if you saw "delete this"
while reviewing your peer's code?
A6. You should never do this. Since compiler
does not know whether the object was allocated on the stack or on the
heap, "delete this" could cause a disaster.
Q7. What is the difference between public, protected,
and private members of a class?
A7. Private members are accessible only by
members and friends of the class. Protected members are accessible by
members and friends of the class and by members and friends of derived
classes. Public members are accessible by everyone.
Q8. What is the difference between non-virtual
and virtual functions?
A8. The behavior of a non-virtual function
is known at compile time while the behavior of a virtual function is
not known until the run time.
Q9. What is a pure virtual function?
A9. "A pure virtual function is a function
declared in a base class that has no definition relative to the base."
Q10. What is an abstract base class?
A10. It is a class that has one or more pure
virtual functions.
Q11. What is the difference between MyClass
p; and MyClass p();?
A11. MyClass p; creates an instance of class
MyClass by calling a constructor for MyClass. MyClass p(); declares
function p which takes no parameters and returns an object of class
MyClass by value.
Q12. How do you know that your class needs a
virtual destructor?
A12. If your class has at least one virtual
function, you should make a destructor for this class virtual. This
will allow you to delete a dynamic object through a pointer to a base
class object. If the destructor is non-virtual, then wrong destructor
will be invoked during deletion of the dynamic object.
Q13. Why were the templates introduced?
A13. Many data structures and algorithms can
be defined independently of the type of data they work with. You can
increase the amount of shared code by separating data-dependent portions
from data-independent portions, and templates were introduced to help
you do that.
Q14. What is a static member of a class?
A14. Static data members exist once for the
entire class, as opposed to non-static data members, which exist individually
in each instance of a class.
Q15. What feature of C++ would you use
if you wanted to design a member function that guarantees to leave "thisÓ
object unchanged?
A15. It is "const" as in: "int MyFunc (int
test) const;"
Q16. Can you overload a function based only
on whether a parameter is a value or a reference?
A16. No. Passing by value and by reference
looks identical to the caller.
Q17. What is the difference between function
overloading and function overriding?
A17. Overloading is a method that allows defining
multiple member functions with the same name but different signatures.
The compiler will pick the correct function based on the signature.
Overriding is a method that allows the derived class to redefine the
behavior of member functions which the derived class inherits from a
base class. The signatures of both base class member function and derived
class member function are the same; however, the implementation and,
therefore, the behavior will differ.
Q18. Can derived class override some but not
all of a set of overloaded virtual member functions inherited from the
base class?
A18. Compiler will allow this, but it is a
bad practice since overridden member functions will hide all of the
inherited overloads from the base class. You should really override
all of them.
Q19. What is the difference between assignment
and initialization in C++?
A19. Assignment changes the value of the object
that has already been constructed. Initialization constructs a new object
and gives it a value at the same time.
Q20. When are copy constructors called?
A20. Copy constructors are called in three
cases: when a function returns an object of that class by value, when
the object of that class is passed by value as an argument to a function,
and, finally, when you construct an object based on another object of
the same class (Circle c1=c2;).
Q21. Why do you have to provide your own copy
constructor and assignment operator for classes with dynamically allocated
memory?
A21. If you don't, the compiler will supply
and execute the default constructor and the assignment operator, but
they will not do the job correctly. The default assignment operator
does memberwise assignment and the default copy constructor does memberwise
copy. In both cases you will only assign and manipulate pointers to
dynamic memory, which will lead to memory leaks and other abnormalities.
You should write your own assignment operator and copy constructor,
which would copy the pointer to memory so that each object has its own
copy.
Q22. Does compiler guarantee that initializers
will be executed in the same order as they appear on the initialization
list?
A22. No. C++ guarantees that base class subobjects
and member objects will be destroyed in the opposite order from which
they were constructed. This means that initializers are executed in
the order, which supports the above-mentioned guarantee.
Q23. What is function's signature?
A23. Function's signature is its name plus
the number and types of the parameters it accepts.
Q24. What does extern "C" int func(int *, Foo)
accomplish?
A24. It will turn off "name mangling" for this
function so that one can link to code compiled by C compiler.
Q25. Why do C++ compilers need name mangling?
A25. Name mangling is the rule according to
which C++ changes function's name into function signature before passing
that function to a linker. This is how the linker differentiates between
different functions with the same name.
Q26. What is the difference between a pointer
and a reference?
A26. A reference must always refer to some
object and, therefore, must always be initialized; pointers do not have
such restrictions. A pointer can be reassigned to point to different
objects while a reference always refers to an object with which it was
initialized.
Q27. How can you access the static member
of a class?
A27.
<ClassName>::<StaticMemberName>.
Q28. How are prefix and postfix versions of
operator++() differentiated?
A28. The postfix version of operator++() has
a dummy parameter of type int. The prefix version does not have dummy
parameter.
Q29. What functions does C++ silently write
and call?
A29. Constructors, destructors, copy constructors,
assignment operators, and address-of operators.
Q30. What is the difference between new/delete
and malloc/free?
A30. Malloc/free do not know about constructors
and destructors. New and delete create and destroy objects, while malloc
and free allocate and deallocate memory.
Q31. What is the difference between delete and
delete[ ]?
A31. Delete deletes one object; delete[ ] deletes
an array of objects.
Q32. Name two cases where you MUST use initialization
list as opposed to assignment in constructors.
A32. Both non-static const data members and
reference data members cannot be assigned values; instead, you should
use initialization list to initialize them.
Q33. What is the difference between const char
*myPointer and char *const myPointer?
A33. Const char *myPointer is a non constant
pointer to constant data; while char *const myPointer is a constant
pointer to non constant data.
Q34. Suppose that objects A, B, and C are instances
of class MyClass (MyClass A, B, C;). How should you design an assignment
operator so that the "A=B=C;" statement would be allowed by a compiler
but "(A=B)=C;" would not be allowed by a compiler?
A34. Make operator=return a reference to a
const object.
Q35. Is there any problem with the following:
char *a=NULL; char& p = *a;?
A35. The result is undefined. You should never
do this. A reference must always refer to some object.
Q36. Class B is derived from class A. Function
f is A's friend. Is f B's friend as well?
A36. No. Friendship cannot be inherited.
Q37. What issue do auto_ptr objects address?
A37. If you use auto_ptr objects you would
not have to be concerned with heap objects not being deleted even if
the exception is thrown.
Q38. What happens when a function throws an
exception that was not specified by an exception specification for this
function?
A38. Unexpected() is called, which, by default,
will eventually trigger abort().
Q39. Why should you prefer throw/catch mechanism
to setjmp/longjmp?
A39. The main problem with longjmp() is that
it does not destroy local objects properly.
Q40. Can you think of a situation where your
program would crash without reaching the breakpoint which you set at
the beginning of main()?
A40. C++ allows for dynamic initialization
of global variables before main() is invoked. It is possible that initialization
of global will invoke some function. If this function crashes the crash
will occur before main() is entered.
If you feel comfortable answering these questions,
then rest assured that your chances of impressing any interviewer are
very high. Be prepared to know basic computer science concepts such
as data structures, search and sort algorithms, basic database concepts,
etc. The client's needs will determine what particular branch of computer
science you have to be familiar with, but you should always be ready
to implement the stock, the queue, and the linked list data structures
with either C or C++ programming languages. And know how to write your
own version of strcpy (string copy) in C programming language since
very often they ask you to do that.
[Aug 11, 2003]
C++ Memory Management: From Fear to Trimph, part 3 George
Belotsky explains
Common C++ Memory Management Errors and
C++ Memory Management Principes in two previous article. He concludes
his series by exploring good memory management in C++.
[ Linux DevCenter]
See also Skeptical OO page
OO zealots critique
Dr. Dobb's Journal Spring 1998 Passing the C++ Test
C ++ Syntax Computer Free Test Quiz Online
The C++
self assessmnet quiz
C++
Interview Quiz
Quia - Java
Quiz - AP C++ Quiz #1
C-C++ Programming - Fall 1999 - Quiz III - November 9, 1999
eecs380.html
CSC100- Introduction to C and C++ (quiz #0)
C++
Level 1 Quiz
C++
Level 2 Quiz
Recruitment
- Quiz C++
Sean Corfield's
site summarizing the changes from ARM C++ to Standard C++.
Gnarly New
C++ Language Features
Addison-Wesley Innovations Interview (1997)
Innovations: Who is the audience
for this book?
Stroustrup: All C++ programmers, and all experienced programmers
who would like to learn C++. Also, students who already know how
to program and want to learn C++ and the techniques it supports.
It is not a book for people who have never programmed before or
have only the most casual acquaintance with programming.
Innovations: What is different in this edition?
Stroustrup: This is really a complete rewrite. Less than
a quarter of this edition was in the second edition. I could have
given this edition a new title, but I like The C++ Programming
Language. There is a greater emphasis on technique: The language
features are more systematically described in the context of their
effective use. When I suggest that the book is for every C++ programmer,
I don't exclude the many who learned C++ from my second edition.
The standard library and its use is described in detail. I believe
- based on comments from readers of draft versions - that there
is significant new information for even the most experienced C++
programmer. Yet, the presentation is easier for C++ novices. The
reason is partly the standard library. The standard library makes
a new and smoother approach to teaching C++ possible: It is much
easier to use a standard library feature such as a string or a list
than to write the equivalent code using the bare C++ language features
only. I have taken advantage of that fact to present language features
and techniques in a more logical order than was possible before.
Innovations: What are new features that C++ programmers
must know about?
Stroustrup: Templates, exceptions, run-time type information,
namespaces, etc. The third edition describes the language features
and library facilities provided by the C++ draft ISO standard.
However, language features by themselves are uninteresting and can
even be detrimental by distracting the programmer from the primary
task of building clean and effective systems. What the programmer
really must learn - and what this book tries to teach - is when,
where, and how facilities can be used effectively. The language
and library facilities are described in the context of the programming
and design techniques that they support.
Innovations: Where do you see C++ used in the future?
Stroustrup: Essentially everywhere. C++ is fast enough for
the most demanding real-time applications and flexible enough for
the largest and most complex systems.
The basic concepts of the language and its standard library are
simple enough for a novice to learn (for example, I have taught
C++ to teenagers). Yet, there is room to learn and grow for years
as the programmer masters more and more advanced and powerful techniques.
Innovations: What are the more difficult parts of the
C++ programming language to learn? How are you addressing the problems?
Stroustrup: What is difficult depends on your background.
For most, the hardest part of learning C++ is to look up from the
programming language constructs and focus on concepts in the application.
That is, to learn to think abstractly and to design with a focus
on classes rather than on sequences of operations.
I tackle this tricky problem by presenting each feature of the C++
language in the context of its use. For key C++ facilities - such
as classes and class hierarchies - I accompany the discussion of
what the language offers with a discussion of the design techniques
they exist to support.
Each chapter has a final section, called 'Advice,' which summarizes
the recommendations found in that chapter (with references back
to the more extensive discussion in the text). My expectation is
that novice C++ programmers will use these rules of thumb to guide
their initial use of C++. Experienced C++ programmers will use the
pieces of advice to determine what is new in C++ programming and
as starting points for experimentation with new programming and
design techniques.
Innovations: Is a thorough understanding of object-oriented
design required to learn C++?
Stroustrup: The two are symbiotic. Learning to use C++ well
is to learn to master the principles and practical aspects of design.
On the other hand, you can no more learn object-oriented design
without building programs than you can learn bicycling or dancing
just by reading a manual. Practice and experimentation are essential,
and they can only be done using a suitable programming language
- such as C++. Consequently, I present the features of C++ in the
context of small examples of good design.
The design section of the book sums up and makes explicit the principles
and techniques that have been quietly used throughout the book.
In general, the book approaches topics by starting with the concrete
and familiar and then gradually moving towards the more general.
That way, we always have concrete examples to help us understand
more general and abstract notions. This, after all, is the way most
of us think and learn.
Innovations: How much of the new C++ standard libraries
does a programmer need to know to develop industrial applications?
Stroustrup: As much as is needed for the application in hand. Seriously,
the standard libraries provide many useful facilities as well as
examples of many general techniques. I mine the standard library
for useful techniques. However, it takes far less knowledge to use
a library than to understand it completely. I give overviews of
facilities so that people can select what they want and quickly
find more information about the library facilities they decided
to use. The book's extensive index and cross referencing are very
important for programmers who use the library before they have read
all of the book and or even the library section - and most programmers
will do that.
Programmers can use standard library facilities such as vectors,
strings, lists, maps, and stream I/O long before they master the
advanced C++ features. People who do not come from a C background
will appreciate that they can use these library facilities long
before they understand the trickier parts of the C subset of C++.
Innovations: What is the difference between STL and the
standard libraries?
Stroustrup: The original STL was the basis for the container
and algorithms parts of the standard library, and those parts are
now commonly referred to as "the STL." Thus, when you sort a vector
or merge two lists using the standard library you are using the
STL. In addition to the STL, the standard library offers strings,
I/O, numerics, and of course the C standard library.
Innovations: Why is C++ the best language for mission
critical application development and large scale development?
Stroustrup: I don't think it makes sense to deem a single
language "the best" for broad application areas. People and problems
differ too much for that. However, C++ is a great language for applications
with stringent requirements, and the standards effort has significantly
strengthened it for many large and critical uses.
C++ has the close-to-the-machine features that allow the programmer
to do even the most efficiency-demanding systems programming tasks.
The facilities for data abstraction and object-oriented programming
allow this basic efficiency to be applied in large and complex applications
where facilities for organizing the code are essential.
I find that C++ has a real strength in projects and organizations
that span several traditional application areas - such as a project
involving networking, visualization, database access, and numerical
analysis. More specialized language have problems spanning such
diverse areas, and C++ allows programmers to build libraries to
efficiently support the different parts of such an application.
After all, my initial reason for creating C++ was to combine C's
raw efficiency with facilities for program organization. For ambitious
projects, I consider C++'s flexibility and the basic efficiency
of its facilities critical. Trying to restrict what a programmer
can do in the name of some philosophy is asking for trouble. We
must encourage programmers and designers to use proven techniques,
but we must not limit them to those proven techniques by trying
to force them to use only "good" style by limiting the set of language
facilities offered. The problem with "fool proof" languages is that
"fools" are so clever. You can write bad code in any language; what
matters is how easy it is to write good and elegant code. For C++,
the aim is to allow people to write good and elegant code under
the stringent requirements of everyday industrial software development.
Innovations: What does final-draft standard mean? What
does ANSI/ISO standardization mean for the C++ programming language?
Stroustrup: A "final draft standard" is the last draft produced
before submitting the standard to the national standards bodies
for approval as an international (ISO) standard. Nothing significant
is supposed to change between the final draft standard and the international
standard. However, the international community scrutinizes the final
draft standard for completeness and clarity of presentation. No
new features are supposed to be added at this stage and no current
features are supposed to be removed.
The main benefit of a standard is stability. It gives the implementers
a fixed target to work towards. This should result in more solid
implementations, more and better tools, and more and better libraries.
For programmers, the standard presents a base on which portable
code can be written. The necessary system dependencies can be clearly
delineated and isolated. From a teacher's point of view, the standard
provides a stable environment in which to teach concepts and techniques.
Having a widely used standard language and library is important
here because it ensures that what is learned is widely applicable.
It also ensures that what is learned will be useful for many years
to come.
Finally, an international standard makes it much harder and much
less attractive for various companies to "play games" with the language.
Innovations: Given that the C++ language, and especially
its standard library, has grown so much since the second edition
of the book, did new pedagogical challenges arise?
Stroustrup: Certainly, but the standard library is also a
major pedagogical opportunity. Relying on the standard library allows
me to present much better examples early on, and to postpone the
discussion of trickier language features until the reader can be
assumed to have a bit more experience with C++. For example, the
standard library vector and list are far easier to understand and
use than the built-in array type and the pointer operations needed
to do the equivalent vector and list manipulation without a standard.
Having the standard library available allows me to present arrays
and pointers as implementation details of higher-level concepts.
Explaining the standard library in detail is a challenge. I present
the key ideas and facilities early on so that people can use them,
and then go into significant detail later on. In all, the book must
have about 300 pages related to the standard library. That library
is not just useful, it is also a mine of examples of useful design
and programming techniques. There are powerful and elegant techniques
in that library that go beyond what C++ programmers have traditionally
used.
Innovations: What is the one C++ feature you find most
valuable, and which one do you find least valuable?
Stroustrup: What is the one aspect of the English language
you like best and which do you like the least? These questions are
hard, and their answers can easily be misleading.
It is no secret that I dislike the syntax derived from C, some aspects
of arrays, and the promiscuous conversion rules for built-in types
(see The Design and Evolution of C++ for details). The beauty
of a language feature lies primarily in the ways it combines with
other features in the support of useful and elegant programming
techniques. Thus, it is hard to praise a single language feature
in isolation. However, let me point to abstract classes and the
way overload resolution interacts with templates as examples of
features that allow some really nice code to be written.
There is no major feature in C++ that is surplus in the sense that
you could remove it without forcing some programmers to rewrite
their code in an uglier, less maintainable, and/or less efficient
way. There are details of C++ that I dislike, but those are nits,
and in general I'm very happy with the language as it is emerging
from the standards process. Standard C++ is a closer approximation
to my original ideal for C++ than any previous version. I hope that
my new book will show people what that is and help them take advantage
of this latest C++ to write better code.
Innovations: How does a new programmer choose between
learning C++ and learning Java?
Stroustrup: Since Sun chose to make Java syntactically very
similar to C++, comparison between the languages becomes inevitable.
However, Java and C++ are very dissimilar when you consider how
you design systems and write good code (you can, of course write
lousy code in any language). In particular, Java lacks most of the
facilities that C++ provides for statically (compile-time) checked
flexible code. This leads Java code to rely on run-time facilities
in a way that would be inappropriate for a C++ program, and often
inherently far less efficient.
I think that if you plan to do serious programming in C or C++,
you should learn C++ and the techniques that go with it. It is always
useful to learn many languages and no serious programmer should
be monolingual. Knowing just one language is inherently limiting,
and learning the second, third, É tenth, etc. language is far easier
than learning the first. However, it would be a mistake to think
that you can become a good C++ programmer just by learning Java
and then applying your newly-developed skills in a C++ environment.
Similarly, I doubt that learning C++ is sufficient to make you a
good Java programmer.
Another issue is that the Java libraries are very different from
the C++ libraries. Syntax is always the most visible part of code,
and always the least significant aspect of that code.
Innovations: Are you satisfied with the scope of the changes
introduced as part of the ISO standardization process? Are there
any features left out that you would have preferred to have included?
Stroustrup: Yes, I'm basically happy with Standard C++ and
its library. There are details I would have chosen to do differently
had I had the opportunity, but there are no major features I would
like to remove or "missing" features I realistically think I could
have added. Standard C++ enables a new level of elegance compared
to previous versions of C++. That's the main reason I re-wrote
The C++ Programming Language more or less from scratch. The
new facilities and techniques deserve nothing less. A minor revision
could never do justice to the language we now have.
|
Standard C++ vs. Traditional C++
- C++ released in 1985: "cfront"; features included:
- "better C"
- classes, virtual, overloading
- Later versions added features:
- multiple inheritance
- templates
- Annotated Reference Manual "ARM" in 1989 added:
- ISO/ANSI Committee convened end of 1989
- adopted ARM, iostream library
- main job was to clarify language definition
- secondary job was to make the language more useful
- Committee voted out "Committee Draft 2" (CD2) in November 1996;
language is officially stable.
Stroustrup
C++ links
Open Directory: Computers > Programming > Languages > Simula
On the important of the quality of diagnostics in programming languages:
Caroline,
I believe that C++ is a disaster as a first language -- it is just
too complex.
Java is slightly better, and has (somewhat) simpler string handling,
but usually it is also a torture for students, unless you find a suitable
subset.
Implementations of both languages
are extremely bad in diagnostic quality. And the quality of implementation
is as important as the language itself. Often one can be better off
with a decent implementation of even old language (Basic, Pascal) that
with bad implementation of a new one (Karel++
http://csis.pace.edu/~bergin/karel.html is a
well known example of a decent first language -- Java-like Logo with
a horrible implementation).
OO-related complexity is an additional drawback, also it can (and
IMHO should) be avoided during at least first semester. Here C++ is
preferable as one can completely ignore OO at the beginning, and introduce
it later, but subsetting Java will also work.
Anyway I would try to outline a subset of Java and compare implementations
to find more or less suitable for introductory course if any.
I really hate to see how students serve as guinea pigs for some new
and untested language just to satisfy ambitions of the teacher. And
misuse of OO in teaching introductory courses is a bad thing. It's just
the same self righteous religious fundamentalism that we see in other
spheres of life so often.
Dr. Nikolai Bezroukov
www.softpanorama.org
Standard disclaimer applies carolan@my-deja.com wrote:
> I am currently completing a Masters Degree in
Computing & Information
> Systems. As part of the program I am obliged to submit a
> dissertation/thesis. The topic I have chosen is: "Which Programming
> Language should be taught to Students first?" (I am mainly concentrating
> on C++ and Java, as these are the languages I know.) If anyone has any
> information on this topic, or knows any useful web sites/books etc,
> which will help me, please let me know. Thank You.
>
> Sent via Deja.com http://www.deja.com/
> Share what you know. Learn what you don't.
Copyright © 1996-2009 by Dr. Nikolai Bezroukov.
www.softpanorama.org was
created as a service to the UN Sustainable Development Networking Programme (SDNP)
in the author free time.
Submit
comments This document is an industrial compilation designed and created
exclusively for educational use and is placed under the copyright of the
Open Content License(OPL).
Site uses AdSense so you need to be aware of Google privacy policy. Original materials copyright belong to respective owners. Quotes are made
for educational purposes only in compliance with the fair use doctrine.
Disclaimer:
- The statements, views and opinions presented on
this web page are those of the author and are not endorsed by, nor do they necessarily
reflect, the opinions of the author present and former employers, SDNP or any other
organization the author may be associated with.
- We do not warrant the correctness of the information provided or its
fitness for any purpose
- In no way this site is associated with or endorse cybersquatters
using
the term "softpanorama" with other main or country domains (e.g. softpanorama.com) with
bad faith intent to profit from the goodwill belonging to
someone else.
Last modified:
August 12, 2009