|
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 ;-)
"C makes it easy to shoot
yourself in the foot. C++ makes it
harder, but when you do, it blows away your whole leg."
- Bjarne Stroustrup
The most difficult work of programmers, and also the
most rewarding,
is not writing programs but rather designing abstractions.
Peter Van Roy
and Seif Haridi:
Concepts,
Techniques, and Models of Computer Programming
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.com
Summary
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-2008 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).
Original materials copyright belong to respective owners. Quotes are made
for educational purposes only in compliance with the fair use doctrine.
Standard 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:
April 05, 2009