wants to learn C++

Gingerbread Man

Dark Magus
Joined
Jun 9, 2002
Messages
2,081
Location
Ooorstrailier!
What the title said - I want to learn C++. I have already tried some books, but to no avail. My successes so far:

OK, I learnt C from the book called (IIRC) "The C Programming Language" by Kernigan (the guy who made C) and Ritchie (the guy who made Unix). Also known as the 'Blue Book', as it has blue writing on the cover. And it was the best book I ever read!

The problem is, I cant find any C++ books in that teaching format. If you dont know the book, it teaches you a new concept, e.g. pointers. Then it says something like "Now, write a piece of code using what we just told you". The format:
1) Explain all the code, syntax, etc. of a new topic
2) Give an example
3) make you write a program using what you have just been taught.

This is soooo much better than most of today's books, which teach by the following format:
1) Give a very basic run-down of what you are going to learn
2) Show you a piece of code, make you copy it out of a book
3) Explain to you what you just wrote.

I find that stupid. All you are doing is copying something out of a book, which you dont really understand, then you are explained what you just did. Of course, it never catches on. I dont want to know how to copy things out of a book, I want to know how to write C++ code! With the way Kernigan and Ritchie wrote it, they are ensuring that you understand what you are doing before you write the program. With the popular method of today, all they want is for you to have a feeling of success as quickly as possible, so they can sell better.

Are there any websites/books I should look out for?
 
C and C++ are very similar but there are some subtle differences that you need to watch out for. Check out http://www.cprogramming.com/. I found it from a google search.

Also, if you don't know anything about object oriented (OO) programming then I suggest you first learn the concepts behind OO. It will make learning C++ ALOT easier as you can clearly see the benefits of some of the language constructs such as C++ and the standard template library (STL).

The way I learnt C++ (from C) was to just go in and look at code and have a reference book handy. But like I said before, it helps to understand OO first.

Good luck!
 
Originally posted by Gingerbread Man
<snip>
The problem is, I cant find any C++ books in that teaching format. If you dont know the book, it teaches you a new concept, e.g. pointers. Then it says something like "Now, write a piece of code using what we just told you". The format:
1) Explain all the code, syntax, etc. of a new topic
2) Give an example
3) make you write a program using what you have just been taught.

That's the newbie's book... assuming the reader has no or very few experience on programming (which language doesn't matter). They will take your hand and guide your every step.


This is soooo much better than most of today's books, which teach by the following format:
1) Give a very basic run-down of what you are going to learn
2) Show you a piece of code, make you copy it out of a book
3) Explain to you what you just wrote.

That's for more advanced readers... when you've learnt a few programming languages, these books are what you want when you want to learn a new language - no unnecessary details, just some working code with comments you can quickly copy or learn from.


I find that stupid. All you are doing is copying something out of a book, which you dont really understand, then you are explained what you just did. Of course, it never catches on. I dont want to know how to copy things out of a book, I want to know how to write C++ code! With the way Kernigan and Ritchie wrote it, they are ensuring that you understand what you are doing before you write the program. With the popular method of today, all they want is for you to have a feeling of success as quickly as possible, so they can sell better.

Are there any websites/books I should look out for? [/B]

The best way to learn programming is to have a mantor behind you. He'll show you working code, run it so you know what it is supposed to do, then take a apart into small pieces, explain to you what they does, and give you an assignment to practice what you've just learned.

Failiing that, the books you said that are "stupid" is the next best thing. They give you working examples, tell you what they does, and explain the code to you. The assignment? You can do it yourself.

The site http://www.mindview.net/Books/ have some great, free online books written by Bruce Eckel. Look for the book "Thinking in C++". If you are going to learn C++, you might as well learn Java too, which better supports (and enforce) OO concepts. "Thinking in Java" is a good book to start learning OO concepts.
 
That's for more advanced readers... when you've learnt a few programming languages, these books are what you want when you want to learn a new language - no unnecessary details, just some working code with comments you can quickly copy or learn from.
Actually, it seems rather the opposite. They have a mass of useless information, they drag things out, they are supposed to be teaching books. The book I was talking about was concise, to the point, very dense. It didn't bother with the very basic drivel that you learnt when playing around with BASIC.

But thanks for the site - it is very good. I am getting closer! I am mostly learning from book because I didn't want to join the school's computing studies class and go through BASIC yet again. I would rather learn living languages (e.g. English) as opposed to forgotten ones (e.g. latin)
 
Try subduck.com, lots of C++ guys there will be willing to help you out.
 
Well, programming isn't exactly a spectator sport. The best way to learn to program is not reading a book on how to program or go through step by step instructions on how to construct a program (except int he very beginning). The best way to learn is to actually do it. People often do it with games: Decide on a small scale and simple game that you know how to play, such ans tic-tac-toe, nim, connect-4, etc. and make a two-player ascii interface of it. When youare done, try to contruct a script for the computer to play so that you can either play against the computer or have it play agaiknst itself. It can be a lot of fun.

As for the specific question of C++, I would recommend you that learning C completely first should be a priority, and that pointers isn't something that C++ has that C doesn't. In fact, one of the major changes C++ made to C is an attempt to mask and hide the C addressing scheme. Things will seem really messed up if you know a bit of how pointers work and C and a bit of how reference variables work in C++. I would say that you need to learn C, learn the basic data structures and algorithms, then attempt other languages (which, by then, would seem a lot easier).
 
If you've already got C, the challenge with C++ is the object-oriented concepts. Personally, I prefer Java for an OO tutorial language, as it enforces the OO paradigm by construction.

Now, C++ itself is an over-engineered hairy beast... personally, I am not awfully fond of it and use it only if I really need it (as in, if I need to write truly high-performance OO code). It's definitely not the most elegant language around.

I started learning C++ from the base of knowing Java and C. One might say that I had a fairly strong basic programming background by then... the worst thing for me was the concept of "references". They are truly elusive and abstract when you first meet them... I would say they are the only very C++ -specific thing around.. they're not really pointers (even if the compiler implements them as such), and they're not quite Java-style references either... they're just compile-time alternate names. Grasping that was my biggest C++ hurdle.

Nihilistic, I would not recommend that a newbie learns "C completely first". I would say he should jump straight to C++. Learning C first will just teach bad habits, both design and syntax-wise (especially because of subtle differences). Also, I don't think C in itself teaches anything special that could not be learned in the process of learning C++.
 
In my view, the most difficult thing about learning C++ is that, although C++ tries to abstract many things away, all of the abstractions it uses are somewhat 'leaky', forcing you to understand how the underlying components work anyway.

Yes, good C++ programmers will avoid using pointers directly, and with the standard containers, smart pointers, etc etc, it's possible to use pointers very little. However can you be a good C++ programmer without knowing how pointers work in-depth? Unfortunately not. You will have to know how they work, and you will have to know about C-style strings, the difference between new, malloc, and new[], and all that nasty stuff.

Then there are so many C++ 'gotchas', that are difficult to understand. Why object myobject; does something completely different to object myobject() ; When to use virtual destructors. The relationship between assignment operator and copy constructor, and when each should be defined. Base-class symbol suppression, and so on and so forth.

If you already know C well, then I think the transition should be much easier: Just learn one feature of C++ at a time. Program in 'C with classes' - just using C but with classes that have member functions. Then add inheritance, and virtual functions, and so forth.

-Sirp.
 
An excellent resource for all those "gotchas" and the like:

C++ FAQ Lite

IMO, the "gotchas" and syntactic bloat are C++'s worst characteristics. It's just got stuff slapped on it to add features, and in the end, you have something that has more syntax than any other programming language...

And of course, then there's the manual memory management which can be a pain unless you're really careful about it...

Will return to comment in-depth later tonight :)
 
Originally posted by HuckFinn

IMO, the "gotchas" and syntactic bloat are C++'s worst characteristics. It's just got stuff slapped on it to add features, and in the end, you have something that has more syntax than any other programming language...

Now you haven't programmed in Perl, have you? :-)

Sirp
 
I'll just insert the stuff from the Programming thread here, as this is the more current one...

Originally posted by Sirp
Now you haven't programmed in Perl, have you? :-)

I've read through a Perl tutorial, but haven't really used the language for anything, ever... it does seem like its context-sensitivity is a bit perverse :)

If you already know C well, then I think the transition should be much easier: Just learn one feature of C++ at a time.

That is certainly the redeeming quality of C++'s bloat... if you don't use it, you don't pay for it.

C++ is syntactically heavy in the sense that you need far more pages to describe all of C++ syntax than you need to describe Java syntax. I think I should sometimes check out some formal C++ grammar, I assume it is fairly nasty reading / parsing...

Most of the gotchas also stem from this syntactic complexity and subtleties in semantics. A lot of the competence of a C++ programming comes from knowing the difference between stuff like footype foo; and footype foo();

When I programmed in Java, it just made it incredibly irritating to do all the things you typically want to do in a program.

I have found this to be a matter of taste... I suppose you were doing C++ before Java? When you change to a language you haven't done anything in before, of course it feels difficult to do things in general... 100% Java programmers might moan hard about, for example, lack of garbage collection and its implications when you do something as simple as, say, a string class with operator overloading... and use those overloading in a chained fashion, such as string x = a + b + c;

Considering that Java of course does not do the operator overloading bit (which is mere syntactic sugar anyway), this still trivial bit requires some thought and planning to get running right before leaking anything... I've seen people just throw out pointers when creating the intermediate results and not getting it why it is wrong.

Say you want to store a whole heap of integers, in a long list,

(...)

Not so bad either way.

Disagreed. C++ needs to introduce a whole new concept, the templates... which are the worst implemented C++ feature anyway (I don't claim that they don't -work- if you know how to use them, though).

About C++ templates at kuro5hin

Java manages it within the core framework of the language... you get a collection the way you would get any other object.

The C++ compiler will guarantee that you really do add an integer to the list of numbers.

I have also seen the other side use the inverse of this argument -- in C++ you need to resort to void pointers or a common base class to store heterogenous collections... depends on what you prefer as standard behaviour.

It's quite likely that in the case of heterogenous collections you end up using runtime type checking anyway, which is more convenient in Java... the alternative would be to add an extra identifier attribute, and I consider this ugly design.

((Integer)mynumbers.get(2)).intValue()

While in C++ it's,

mynumbers[2]

Java can indeed get hideous with its casting. I've had a modular IRC bot as a hobby project this summer, and I have lines like that that take up about two screen widths :) Certainly you can and should break them up by using local variables, but modern IDEs like Eclipse make it very easy to create casting monsters, because they automatically add the casts for you... and of course, the code looks much more leet that way ;)

When it comes to the [] operator, it is handy syntactic sugar, but in most cases, you're better off using a pair of getter and setter methods. It could be my incompetence with the language, but when an [] implementation gets complex enough, especially when paired with dynamic memory allocation and tricks like copy-on-write, stuff starts to seem too hairy to be motivated.

The problem with [] is that you don't know whether you're reading or writing through it. To get past this, you need to resort to your "C++ programmer's bag of tricks to get around C++". I think this too symptomatic and common in C++ at large... there is too much black magic involved to get C++ to do your bidding. Of course if you're doing operating system programming you need to be bothered with reference counting, smart references and whatnot, but things like this are why I don't use C++ unless I can justify its use.


It's a nice feature that Java has well-defined behavior on an array-out-of-bounds error. The problem is what that behavior is: anytime I make such a programming error, I want to get an immediate assertion failure of some type, hopefully with a nice stack trace. Instead Java throws an exception.

Why would someone want to throw an exception on a programming error?

That's a nice philosophical question, but I am afraid I am not getting what your complaint with the actual behaviour is, in practical terms. Your program still dies immediately, as if you were doing an assertion, and barfs a stack trace, does it not?

It (transactional safety with exceptions) can be implemented in C++ without any try blocks at all, and with lots less headaches for the programmer.

I've heard about this problem earlier in other discussions, but haven't quite looked deeper into it... off the top of my head, I can't figure out what makes C++ exception handling so different from that of Java's that Java makes things more difficult to do... is the argument that in C++, you simply don't do things with exceptions, but Java forces you to?

The only truly 'elegant' languages I have used aren't used nearly enough in practice - languages like Haskell and Lisp.

Well, we all know that God codes in Lisp, don't we? That's why the universe takes billions of years to run.. ;)
 
C++ is syntactically heavy in the sense that you need far more pages to describe all of C++ syntax than you need to describe Java syntax. I think I should sometimes check out some formal C++ grammar, I assume it is fairly nasty reading / parsing...

There is a C++ grammar in one of the appendices of "The C++ Programming Language" by Stroustrup. I will not deny that the grammar is disgusting, and Stroustrup even admits that it's a 'simplified' version of the grammar that a compiler would have to use.

Most of the gotchas also stem from this syntactic complexity and subtleties in semantics. A lot of the competence of a C++ programming comes from knowing the difference between stuff like footype foo; and footype foo();

Yes, things like that are very annoying about C++. Once again I won't deny it. However there are far worse subtleties than footype foo() ; Try working out what the following does:

Code:
ifstream file("myfile.txt");
vector<char> v(istream_iterator<char>(file),istream_iterator<char>());

It's meant to be a rather 'cool' way of reading a file into a vector.

In fact, the second line declares a function which returns a vector<char>, takes an istream_iterator<char> named 'file' as its first parameter, and an unnamed parameter which is a pointer to a no-argument function that returns an istream_iterator<char> as its second parameter.

The second line has to be rewritten with some type of syntax that will make it clear to the compiler that it's a variable declaration, not a function declaration. The simplest is probably,

Code:
vector<char> v((istream_iterator<char>(file)),istream_iterator<char>());

I will openly agree that this is likely to be rather confusing to someone learning the language.

I have found this to be a matter of taste...

Isn't this entire discussion a 'matter of taste'?

I suppose you were doing C++ before Java?

No, I was doing mainly C before Java. I had programmed in C++, but I did not know it well or like it at the time I learnt Java.

When you change to a language you haven't done anything in before, of course it feels difficult to do things in general...

Yes it does, however this is not the reason I don't like Java. I programmed in Java for more than 2 years, and it was my language of choice at one stage. It was only after I learnt C++ properly that I realized I could do things easily that I had been wishing I could do in Java.

100% Java programmers might moan hard about, for example, lack of garbage collection and its implications when you do something as simple as, say, a string class with operator overloading... and use those overloading in a chained fashion, such as string x = a + b + c;

Huh? Are you talking about using the C++ string class, or writing your own? If you're using the C++ string class, then everything is handled for you. No need to worry about memory management of the string at all. string x = a + b + c; will work fine.

If you're writing your own string class, well, why? Both Java and C++ have string classes. Even if you did write your own string class, you could trivially implement it in terms of vector, and not have to worry about any memory management issues.

To address your more general point, I can see how lack of garbage collection in C++ would be very difficult for someone coming from a GC-oriented language to deal with. That's a normal part of learning a new language, and yes, C++ is harder to learn than most.

Once you've learnt the techniques that C++ makes available to manage resources, I think they are as good as Java's - each have their own advantages and disadvantages. Java's garbage collection is good for managing heap-allocated memory, but it fails to address the more general issue of arbitrary resources - network sockets, open files, and so forth. Finalizers are not an acceptable solution, since Java lacks any guarantee about when they will run (or even run at all).

C++'s solution of using destructors extensively to precisely specify the scope of a resource is one I personally prefer, although I see advantages and disadvantages of each approach.

Disagreed. C++ needs to introduce a whole new concept, the templates... which are the worst implemented C++ feature anyway (I don't claim that they don't -work- if you know how to use them, though).

I don't see the problem with introducing a 'whole new concept' for something as important as containers. Java specifically tries not to add any new concepts, just implements containers in normal classes, and ends up with very bad containers.

Following this logic we could say, "C++ is a worse language than Java because it has more features".

About C++ templates at kuro5hin

I've seen this article before. The author is saying that templates are a good idea, he just thinks they are better implemented in some other languages. I don't think that C++ templates are brilliantly implemented, but I don't think they are awful either.

I certainly think C++ having templates vs Java not having them is a huge plus for C++.

Also, writing your own templates might be a little difficult, but using templates provided by others or by the language really isn't that difficult. It's easy once you learn how templates work.

Java manages it within the core framework of the language... you get a collection the way you would get any other object.

C++ manages it 'within the core framework' of the language too, it's 'core framework' is just different to Java's.


I have also seen the other side use the inverse of this argument -- in C++ you need to resort to void pointers or a common base class to store heterogenous collections... depends on what you prefer as standard behaviour.

It's quite likely that in the case of heterogenous collections you end up using runtime type checking anyway, which is more convenient in Java... the alternative would be to add an extra identifier attribute, and I consider this ugly design.

Firstly, if you need heterogenous collections, your program probably has a design flaw. The 'object oriented' approach to this is to have a polymorphic function in a common base class (or interface in Java), and then call the polymorphic function on each item in the collection. This has a similiar implementation in both Java and C++.

If you are needing to use RTTI, then you are probably doing something wrong. However, in C++ you could do it, as you say, either by declaring a common base class, or, the worst solution, using void pointers and using dynamic_cast.

The thing is, using void pointers and dynamic_cast is the same way Java does it. That is my entire point: The worst way to do it in C++ is the only way you can do it in Java. That it might be slightly 'more convenient' in Java hardly makes a difference. (And for that matter, it isn't really much more convenient than Java at all).

This is one of the core reasons I dislike Java collections: the Java ArrayList is more or less equivalent to having to use a vector<void*> everywhere in C++.

Java can indeed get hideous with its casting. I've had a modular IRC bot as a hobby project this summer, and I have lines like that that take up about two screen widths Certainly you can and should break them up by using local variables, but modern IDEs like Eclipse make it very easy to create casting monsters, because they automatically add the casts for you... and of course, the code looks much more leet that way

Yes it can, and not only is the code verbose, it has a hideous number of possible paths through the code with all the exceptions that can be thrown.

Breaking them up with local variables simply means that you are taking 5 lines to do something which should be doable in one line.

When it comes to the [] operator, it is handy syntactic sugar, but in most cases, you're better off using a pair of getter and setter methods.

Oh the point of my example wasn't the [] operator. It is syntactic sugar, with only mild advantages. Vector also supports the at() function which you could use instead.

However there are a few advantages of having operator overloading, the biggest of which is that it provides a language-mandated way of doing things. The way to make an indexable object in C++ is to overload the [] operator. In Java it's to use the get() function, but the encouragement to follow that standard isn't nearly as strong. Further, Java's own builtin arrays violate that standard.

Suppose you have a lot of code that uses an array. Suppose that you need to add a feature which requires the array to be dynamic in size, so you want to switch it to being an ArrayList. How many changes would you have to make in Java? If you wanted to switch it to being a vector in C++, very few changes would be needed. This is even more important for C++, since it supports templates, and one might want to write a function template which could accept either an array or a vector, however it is less important for Java, since Java does not support templates.

It could be my incompetence with the language, but when an [] implementation gets complex enough, especially when paired with dynamic memory allocation and tricks like copy-on-write, stuff starts to seem too hairy to be motivated.

Hmm....you were just saying a moment ago that the [] operator is just syntactic sugar, and now you're saying there is something inherently more complex about operator []? Huh?

Tricks like copy-on-write? I'm afraid I don't understand......you don't have to know anything about copy-on-write unless you're trying to implement an optimized container yourself. If you fiddle with the internals of the standard libraries supplied by your compiler vendor, then sure it's going to be hairy. But I don't understand why you'd do this. There is also no reason at all why this has anything to do with operator [] vs getter and setter methods.

The problem with [] is that you don't know whether you're reading or writing through it.

The semantics are exactly the same as for a normal variable or a builtin language array. I don't understand how this could possibly be a problem. Can you provide an example where it is unclear whether you are reading or writing? Are you saying that some people who implement operator [] may return by value when they mean to return by reference?

Of course if you're doing operating system programming you need to be bothered with reference counting, smart references and whatnot, but things like this are why I don't use C++ unless I can justify its use.

I'm afraid I don't understand your complaint here either.

Reference counting is an optimization technique that will reduce the number of copies of an object in certain situations. There is nothing inherent in C++ that has anything to do with reference counting. So what does this have to do with anything? You might as well blame C++ for the Knuth-Morris-Pratt string searching algorithm being complicated because you had to implement KMP in it once.

Some standard library container implementations use reference counting on the string class, but that's completely irrelevant because it is an implementation detail you will never have to deal with. Complaining about that would be like complaining that Java's mark-and-sweep garbage collection algorithm is complicated.

As for 'smart references', there are no such things in C++. You might be talking about smart pointers, in which case, similiar comments to reference counting apply.

That's a nice philosophical question, but I am afraid I am not getting what your complaint with the actual behaviour is, in practical terms. Your program still dies immediately, as if you were doing an assertion, and barfs a stack trace, does it not?

It depends upon whether you catch the exception or not. Since it's often useful to catch(Exception) at other points in the program, the error will often cause unexpected behavior rather than a stack trace.

That's a relatively minor thing, but more generally, I do think the Java misuses exceptions rather badly. Exceptions are useful for reporting errors *outside* of the program. Not inside of it.

I've heard about this problem earlier in other discussions, but haven't quite looked deeper into it... off the top of my head, I can't figure out what makes C++ exception handling so different from that of Java's that Java makes things more difficult to do... is the argument that in C++, you simply don't do things with exceptions, but Java forces you to?

Firstly, in C++, you do do things with exceptions. Many standard library functions throw exceptions. new will throw an exception if it fails. dynamic_cast throws an exception if it fails if it's trying to cast to a reference.

The problem is that in Java you have to use try...catch statements:

Code:
op1();

try {
	op2();
} catch(Exception e) {
	rollbackOp1();
	throw e;
}

In C++, you can use a helper class:

Code:
class execute_rollback
{
	bool cancelled_;
public:
	execute_rollback() : cancelled_(true) {}
	~execute_rollback() { if(!cancelled_) rollbackOp1(); }
	void cancel() { cancelled_ = true; }
};

This class would be written once and made slightly more generic and powerful, and then would be used throughout an entire project.

Then when you want to do the transactional operations:

Code:
op1();

execute_rollbacker guard;

op2();

guard.cancel();

Simple, and with no control statements at all. It is far more scalable to a larger function as well. This is just one of many applications of the "Resource Acquisition Is Initialization" (RAII) resource management idiom, support of which, is one of the best features of C++.

Yes, it would probably take a novice a little longer to understand the second one (although not much longer, if they know neither approach to begin with), but the second approach is far more powerful, flexible, and less error prone than the first.

-Sirp.
 
I'm scared...

1) I want to learn C++. I could learn something else that you say is better, but I know a bit about C. It is logical to learn C, then learn C++. I learnt C a while back, and the info is in the back of my head somewhere, so it wont be a massive learning curve.

2) I dont see what is the big deal about pointers. They seem straightforward enough for me, but maybe that is saying something about how much I know...

3) This has turned into an interesting discussion. That I dont understand much of! Somebody, please tell me what Sirp and Huckfinn are on about! I get some of it, but can one of you please tell me what you are saying? e.g.
Tricks like copy-on-write? I'm afraid I don't understand......you don't have to know anything about copy-on-write unless you're trying to implement an optimized container yourself. If you fiddle with the internals of the standard libraries supplied by your compiler vendor, then sure it's going to be hairy. But I don't understand why you'd do this. There is also no reason at all why this has anything to do with operator [] vs getter and setter methods.

Ok, I know that [] is about arrays, and get() set() is about members of classes getting and setting private data (IIRC), but the rest is lost to me. Things like Copy-on-write, optimised container, etc. Maybe we could start some HOWTOs or lessons on this...
 
Glad you're enjoying our discussion and sorry if it has become a little technically intense, Gingerbread Man.

(1) If you know C I suggest going ahead with C++. Learn one C++ feature at a time and start using it. Don't try to learn the whole thing at once. That's exactly how I learnt C++. It works well.

(2) You may have noticed that the most common time when your programs crash and have bugs is due to use of pointers. Pointers are confusing to most programmers and are considered the most difficult part of C.

C++ attempts to allow programmers to 'wrap' pointers up so they don't have to be used directly very much, to try to improve program stability.

Java removes any direct use of pointers at all, allowing only 'references' to be used.

(3) The thing about [] is that C++ has a concept known as 'operator overloading', which allows you to give [] a special meaning for a certain class.

You may have noticed that a problem with arrays in C is that they cannot change their size after you create them. This greatly limits their use. In C++ it is possible to make a class that acts alot like an array, so much so that you can use [] with it just like an array, but it can provide additional functionality like being resized. There is such a class [1] called a vector that is available in the C++ language itself.

Java does not allow this. In Java you can only use [] with arrays, and you cannot give [] a special meaning for a certain class. So, if you want to create a class that acts like an array, you will have to use it like mypretendarray.get(4) rather than mypretendarray[4] that you can do in C++.

Likewise in C++ you can make almost any operator work differently for classes you create. So you could make a special matrix class that allows m1 = m2 + m3; to sum together two matrices.

You may have also noticed that in C, with C-style strings, you can't go s1 = s2 + s3; because C-style strings are just pointers. In C++, there is a string class supplied with the language that allows precisely this - things like string s1 = s2 + "blah"; through operator overloading

Some people consider this a significant advantage of C++ that you can make your own classes behave differently with operators, while some people think it's just a minor syntax thing, and that it's ok to just do something like m1 = m2.add(m3) ; for the matrix example above.

As for an 'optimized container', a container is basically a class [1] that contains alot of other objects. vector is a container. list is another example of a container - it is useful for storing a list of objects. A string is also a container because it contains chars. An optimized container is simply a container that has been programmed well so that operations on it go fast :-)

Copy-on-write is one way to make strings (and some other types of containers) go faster, by using special tricks. However you only have to know about copy-on-write if you are actually making the string class, not if you are using it. For that reason I don't even know why Huck Finn brought it up. It's kinda like scaring someone whose knew to Java by telling them about reference counting vs mark-and-sweep :-)

Uhmmm....I'm not sure if any of that will actually clear anything up for you but I hope it will!

-Sirp.

[1] actually it's a 'class template' meaning a special template which allows you to make many classes
 
That clears things up quite a bit. Though I will have to read it a couple of times. Thanks!

EDIT: Put it this way, that is soo much easier to understand then what the quantum physics site I was looking at was trying to tell me.
 
First of all, may I commend you for a very insightful post...

Originally posted by Sirp
Stroustrup even admits that it's a 'simplified' version of the grammar that a compiler would have to use.

:lol: I always thought that it is the compiler whose job it is to handle disgusting grammars as they are probably quite hard for human beings to read and understand :)


Yes, things like that are very annoying about C++. Once again I won't deny it. However there are far worse subtleties than footype foo() ; Try working out what the following does:

(...)

I will openly agree that this is likely to be rather confusing to someone learning the language.

Sheesh. :rolleyes:

I must admit I spent some time looking at that, and would probably have fallen for it had I tried to write it myself. And I don't even consider myself a total C++ newbie anymore, either...

Isn't this entire discussion a 'matter of taste'?

Of course it is, for the most part at least. Yet, I do think there are some absolutes to even programming languages... like, Brainf**k or something else based on pure lambda calculus is probably something one wouldn't like to write big systems in ;)

The fun part is finding out where the matter of taste ends and absolutes begin...

Yes it does, however this is not the reason I don't like Java. I programmed in Java for more than 2 years, and it was my language of choice at one stage. It was only after I learnt C++ properly that I realized I could do things easily that I had been wishing I could do in Java.

Okey, respect to that position then. I might still be a little bit a the "preference due to familiarity" stage... it will be interesting to see if my ideas change over time when I actually write bigger programs in C++. Just haven't found the right hobby project yet...

Huh? Are you talking about using the C++ string class, or writing your own? If you're using the C++ string class, then everything is handled for you. No need to worry about memory management of the string at all. string x = a + b + c; will work fine.

Yes and no. Of course there is no reason to write an actual string class from scratch, but you must realize it still is a very representative programming excercise... I am yet to see a Programming 101 that wouldn't tell folks to write their own string class. This is simply because the string implementation has a lot of things in it that you are bound to meet elsewhere in your programming.

As an example, I was once writing a matrix class, which is another very, very typical programming problem, and to really make it pretty and fast and functional and whatnot, you really had to have your bag of tricks handy. Browsing the web for the ways to implement it in C++, I learned more about C++ programming than ever before, I think. In Java, this would require much less "idiomatic" knowledge about the "best practices of the language".


To address your more general point, I can see how lack of garbage collection in C++ would be very difficult for someone coming from a GC-oriented language to deal with. That's a normal part of learning a new language, and yes, C++ is harder to learn than most.

Yes, but still, there are good GC languages around that, because of GC among other things, make them easier general-purpose languages IMO. Of course, this is a case of "right tool for the job". Like, only crazies would use something as slow as Lisp to code an editor... it would just turn out to be eight megabytes and constantly swapping. :)

If you need something native-compiled and manually resource-managed, of course you should use a language like C++... but in that case, the burden on the designer should be justified by the project requirements.

(Actually, I love Emacs and do all my coding in it...)

Once you've learnt the techniques that C++ makes available to manage resources, I think they are as good as Java's - each have their own advantages and disadvantages.

For the interested parties, it should be noted that for C++ there is such a thing as the Boehm GC, which sounds pretty good if you can afford the unpredictability that automated GC brings...

Java's garbage collection is good for managing heap-allocated memory, but it fails to address the more general issue of arbitrary resources - network sockets, open files, and so forth. Finalizers are not an acceptable solution, since Java lacks any guarantee about when they will run (or even run at all).

I would say this is a highly interesting point... I will remember this. I never really thought of it from the perspective of a finalizer possibly never running... enlightening.


Following this logic we could say, "C++ is a worse language than Java because it has more features".

I do value compactness in the spirit of Occam's razor... after all, deep down it's just a Turing machine... :)

I certainly think C++ having templates vs Java not having them is a huge plus for C++.

It could be. I am still not certain if I would like to see them in Java. It could possibly bloat the language... What I would like to see in Java are enums. Current Java alternatives just don't cut it.

One of my pet hates in C++ templates is that you need to write the implementation into the header. While I like open source, it breaks the conventions of the C/C++ way quite glaringly...


C++ manages it 'within the core framework' of the language too, it's 'core framework' is just different to Java's.

And Java's core framework is smaller than C++'s, thus being more logically economical.


Firstly, if you need heterogenous collections, your program probably has a design flaw. The 'object oriented' approach to this is to have a polymorphic function in a common base class (or interface in Java), and then call the polymorphic function on each item in the collection. This has a similiar implementation in both Java and C++.

I am not sure if I want my language to enforce design quite up to that point. The core competency of a software designer is to design well... I would hope he's capable of making up his own mind :)

The thing is, using void pointers and dynamic_cast is the same way Java does it. That is my entire point: The worst way to do it in C++ is the only way you can do it in Java. That it might be slightly 'more convenient' in Java hardly makes a difference. (And for that matter, it isn't really much more convenient than Java at all).

Fair enough... you've got me pretty much convinced there. If you really wanted to enforce a type for a collection in Java though, there's nothing stopping you from extending a collection and doing instanceof checks... maybe a bit wrong way around from your point of view though.


Tricks like copy-on-write? I'm afraid I don't understand......you don't have to know anything about copy-on-write unless you're trying to implement an optimized container yourself.

What if I am? :)

"Don't try doing complex things because they are, well, complex" is not really an excuse... yes, standard libraries have lots of nice stuff ready made, but I wouldn't think you can always just pull something out of the library... you don't need to be trying to reinvent the STL to know, for example, copy-on-write.


There is also no reason at all why this has anything to do with operator [] vs getter and setter methods.

Returning a reference to a content object from, for example, []. Correct me if I'm wrong, but you don't know whether you're using the reference as an rvalue or lvalue. Using getters and setters, you do have a way of telling apart the operations. Yes, there is the smart reference trick, but it's contrived... the point is that you do need to know a lot of idiomatic ways to get around the language before you're proficient... Java has idioms too, but I don't think they reach the level of obscurity and number that C++ has.


Reference counting is an optimization technique that will reduce the number of copies of an object in certain situations. There is nothing inherent in C++ that has anything to do with reference counting. So what does this have to do with anything?

Definitely there is nothing inherent in the language that has anything to do with reference-counting, but it's still another bag of tricks idiom you're bound to be using when you start to write high-performance code that has large objects with dynamic allocation.


Some standard library container implementations use reference counting on the string class, but that's completely irrelevant because it is an implementation detail you will never have to deal with.

Programmers implement stuff so I think they should be interested in implementation details... I for one am very interested in how my memory is managed, when I have to do it by hand.

Complaining about that would be like complaining that Java's mark-and-sweep garbage collection algorithm is complicated.

Java's mark and sweep is always transparent to the programmer (unless you somehow muck about with JVM internals...). I don't think you can compare it in any way to refcounting, which is not, because as I said, you can't ignore efficient memory management techniques in your own code if you're the one deleting your new's.

As for 'smart references', there are no such things in C++. You might be talking about smart pointers, in which case, similiar comments to reference counting apply.

"Smart reference" is a way to know whether your reference is being used as lvalue/rvalue. I once googled on this subject, so I am sure it is still there somewhere. :)


Since it's often useful to catch(Exception) at other points in the program, the error will often cause unexpected behavior rather than a stack trace.

Could be "useful", but a lot of people would also say that catching Exception is also Evil, for the reason you mentioned. Exception catching should always be as specific as possible... even if it indeed does lead to horrendous try-catch blocks.

That's a relatively minor thing, but more generally, I do think the Java misuses exceptions rather badly. Exceptions are useful for reporting errors *outside* of the program. Not inside of it.

An interesting proposition... I do like the idea that a program's internal state should never lead to an exception.


Re transactions and exceptions... I read some other argumentation against Java in this regard, and I do see the point. I've been cursing Java for this very reason myself... "finally" is a good idea in resource release, but doesn't quite get the job done in a comprehensive way.

Very enlightening indeed! I still think that I won't be hacking for sheer fun with C++ any time soon still, but I might have to change some of my ideas...
 
Sheesh.

I must admit I spent some time looking at that, and would probably have fallen for it had I tried to write it myself. And I don't even consider myself a total C++ newbie anymore, either...

Yes, even many experienced C++ programmers have trouble with that. I admit it's a problem.

Of course it is, for the most part at least. Yet, I do think there are some absolutes to even programming languages... like, Brainf**k or something else based on pure lambda calculus is probably something one wouldn't like to write big systems in

The fun part is finding out where the matter of taste ends and absolutes begin...

True...also, being such a young industry, software engineering is still very early on in developing a sense of what is good in an absolute sense and what is not. No-one really knows, yet.

Yes and no. Of course there is no reason to write an actual string class from scratch, but you must realize it still is a very representative programming excercise... I am yet to see a Programming 101 that wouldn't tell folks to write their own string class. This is simply because the string implementation has a lot of things in it that you are bound to meet elsewhere in your programming.

I don't think it's terribly 'representative' of the things a typical C++ programmer will have to do. It's not representative of the kinds of things I program.

Anyhow, implementing a string class is trivial: just implement it in terms of vector. (That's the way STLPort does it, for instance). If you're not allowed to use vector, well, we're talking about a voluntary restriction that means you're programming in only a subset of the language. It might be a useful teaching exercise, but I am not saying C++ is not difficult to learn.

As an example, I was once writing a matrix class, which is another very, very typical programming problem, and to really make it pretty and fast and functional and whatnot, you really had to have your bag of tricks handy. Browsing the web for the ways to implement it in C++, I learned more about C++ programming than ever before, I think. In Java, this would require much less "idiomatic" knowledge about the "best practices of the language".

But any advanced C++ tricks you would use would only have to be used if you need the matrix to be very very fast. If you need it to be very fast, then any comparison with Java is irrelevant, because Java is completely unsuitable for doing things very fast.

If you don't need it to be fast, then you can simply implement your matrix trivially in terms of valarray or vector, and it'll still be faster than any matrix you could implement in Java.

Yes, but still, there are good GC languages around that, because of GC among other things, make them easier general-purpose languages IMO.

Sure, I don't deny that GC is a potentially useful feature.

Of course, this is a case of "right tool for the job". Like, only crazies would use something as slow as Lisp to code an editor... it would just turn out to be eight megabytes and constantly swapping.

I think this needs to be updated to eighty megabytes and constantly swapping :-)

If you need something native-compiled and manually resource-managed, of course you should use a language like C++... but in that case, the burden on the designer should be justified by the project requirements.

And in my opinion, if you need a decent program that works, you should also consider C++, because it's a good language for that kind of thing - but leave all your fancy coding tricks and optimizations at home.

For the interested parties, it should be noted that for C++ there is such a thing as the Boehm GC, which sounds pretty good if you can afford the unpredictability that automated GC brings...

There are several GCs available for C++. Nothing in the C++ standard prohibits an implementation implementing garbage collection.

Even if there were a GC available for my implementation, I would likely not use it, since I think controlling when your memory allocation occurs using destructors and the Resource Acquisition Is Initialization (RAII) C++ language idiom is better for ensuring program correctness.

It could be. I am still not certain if I would like to see them in Java. It could possibly bloat the language... What I would like to see in Java are enums. Current Java alternatives just don't cut it.

Not having enums is also irritating, but it can be worked around in a semi-acceptable way. Unlike not supporting genericity, which can't really be worked around.

One of my pet hates in C++ templates is that you need to write the implementation into the header. While I like open source, it breaks the conventions of the C/C++ way quite glaringly...

Yes, this is annoying. It is actually possible to write them in the source file in standard C++ using the 'export' keyword. However, only one implementation currently supports this, and its usefulness is still considered dubious.


And Java's core framework is smaller than C++'s, thus being more logically economical.

I have little doubt that it's going to get much bigger though. Just like C++'s has...


Firstly, if you need heterogenous collections, your program probably has a design flaw. The 'object oriented' approach to this is to have a polymorphic function in a common base class (or interface in Java), and then call the polymorphic function on each item in the collection. This has a similiar implementation in both Java and C++.


I am not sure if I want my language to enforce design quite up to that point. The core competency of a software designer is to design well... I would hope he's capable of making up his own mind

Uhhh....are you arguing in favor of C++ or Java here? :)

C++ is the language that trusts in the competency of the software designer. Java heavily restricts what the developer can do in many ways. C++ does not restrict using heterogenous collections, it just has special support for homogenous collections, since these are used far, far more often in real world situations.

Fair enough... you've got me pretty much convinced there. If you really wanted to enforce a type for a collection in Java though, there's nothing stopping you from extending a collection and doing instanceof checks... maybe a bit wrong way around from your point of view though.

So to get yourself a decent sequential container, of even the most primitive of types, you have to implement it yourself with a class? Do I even have to comment on how bad that is?

If I ever have to program in Java again, I think I am going to have to use a preprocessor...

Tricks like copy-on-write? I'm afraid I don't understand......you don't have to know anything about copy-on-write unless you're trying to implement an optimized container yourself.


What if I am?

There are two main classes of programs with respect to efficiency:

(1) programs that need to be very very fast
(2) programs that need only to be average speed

If you are writing a program in class (1) then you may be writing an optimized container yourself, and having to use copy-on-write. However if this is the case, any comparison between C++ and Java with respect to suitability is irrelevant, since Java is already disqualified by its lack of speed.

If you are writing a program in class (2) then clearly you do not need such an optimized container. Your code will still run faster than Java without such 'tricks', so don't use them.

If you are using such tricks anyway, then in my opinion, you are not writing good C++ code. You are violating the principle of 'premature optimization is the root of all evil', and indeed, you will encounter much evil on this root.

I will compare your preferred way of writing Java to my preferred way of writing C++. However I will not compare your preferred way of writing Java to your preferred way of writing C++. That is not a fair comparison. Such a comparison can be full only of strawmen. With the coding techniques you describe, sure, I agree that Java is a better language than C++ in most situations.

"Don't try doing complex things because they are, well, complex" is not really an excuse... yes, standard libraries have lots of nice stuff ready made, but I wouldn't think you can always just pull something out of the library... you don't need to be trying to reinvent the STL to know, for example, copy-on-write.

But you do need to be trying to do something highly efficient. If this is the case, you are outside of the application domain of what Java is suitable for anyhow, so any comparison between Java and C++ is irrelevant.

If you don't need high efficiency, then don't use such complicated algorithms.

Also, FWIW, years of experience have actually taught us that copy-on-write is not nearly so efficient as some people have thought. The major standard library implementations are moving away from copy-on-write, since it turns out to be a pessimization in as many or more situations than it is an optimization. Especially in multi-threaded programs.


Returning a reference to a content object from, for example, []. Correct me if I'm wrong, but you don't know whether you're using the reference as an rvalue or lvalue. Using getters and setters, you do have a way of telling apart the operations.
Yes, there is the smart reference trick, but it's contrived... the point is that you do need to know a lot of idiomatic ways to get around the language before you're proficient... Java has idioms too, but I don't think they reach the level of obscurity and number that C++ has.

Well, you assume that if the non-const version of [] is being called, then it could be setting, while if the const version is being called, it can only be getting. Admittedly many users will call the non-const version when they are only getting, so you are right in that get and set methods do give you slightly more information like this.

However in Java you don't know either, unless your container is only storing immutable objects. For mutable objects, it's harder to tell in Java, because Java doesn't have a concept of const.

This is another major thing missing from Java: Using const consistently throughout your program greatly helps with readability imho. You can tell if a function is going to mutate an object's state just by looking at the function prototype. In Java you better hope that they've documented the function well.

Definitely there is nothing inherent in the language that has anything to do with reference-counting, but it's still another bag of tricks idiom you're bound to be using when you start to write high-performance code that has large objects with dynamic allocation.

All you need is a utility like boost's shared smart pointer, and it's incredibly easy to do reference counting.


Complaining about that would be like complaining that Java's mark-and-sweep garbage collection algorithm is complicated.

Java's mark and sweep is always transparent to the programmer (unless you somehow muck about with JVM internals...). I don't think you can compare it in any way to refcounting, which is not, because as I said, you can't ignore efficient memory management techniques in your own code if you're the one deleting your new's.

Firstly, the reference counting used in some implementations of the standard library is always transperant to the programmer too. (Unless you somehow muck about with standard library internals). It may have some efficiency implications, but so does Java's mark and sweep.

If you choose to use reference counting yourself for whatever reason, then you are making an explicit design decision to program in a more complicated way in exchange for more speed. You can go simple and slower with no reference counting or you can go complex and faster with reference counting. Java offers no such choice: simple and slow is the only choice. (imho less simple and more slow than C++'s simple and slow option).

Good languages should make the simple things easy, and the complex things possible. C++ achieves this - you can choose not to use things like reference counting and program simple programs, or you can put in the extra effort for the complex things. Java does not achieve this: you can only do the simple things, but the complex things are typically not possible.

As an analogy, it is like comparing two cars. One car is more modern, faster - it can go 90 miles per hour, and equipped with all the latest safety features. One car is older, slower - it can go only 50 miles per hour, and is not equipped with advanced safety features.

Your argument is like saying to me, "well, I'm going to drive the slower car on this trip, because I want to be safe, and going at 90 miles per hour is not safe."

Of course you could just drive the 90mph car at 50mph and be safer than you would be in the slower car. But you say, "But if I'm going to drive the fast car, I want to drive it at its maximum speed."

In that case, all I can shrug and say "okay". If someone is not disciplined enough to use C++ in a way that meets the requirements of the project they are programming, and instead feels the need to always try to optimize, then yes, I suppose that Java is a better language for them, since it will enforce the discipline they need. Just like if you were giving your 16 year old son a car, you might prefer to give him the one that only goes 50 miles per hour, even if the more modern one is safer if he were to stick to driving at 50 miles per hour.

If a programmer is professional, mature, and experienced, and is going to use a coding style appropriate for the project they are working on, then I would say that C++ is a better language, since they will have the discipline to only use its speed where necessary, and elsewhere focus on its features that facilitate program correctness.

"Smart reference" is a way to know whether your reference is being used as lvalue/rvalue. I once googled on this subject, so I am sure it is still there somewhere.

I suppose you are talking about what is commonly called a 'proxy object'. A 'smart reference' would be an object that overloads operator '.' - just as a 'smart pointer' overloads operator unary * and operator ->. However overloading the '.' operator is not possible in C++.

Using proxy objects is not an acceptable solution, and using them will likely cause a container to fail the C++ standard's requirements for a container.

(continued in next post...)
 
Since it's often useful to catch(Exception) at other points in the program, the error will often cause unexpected behavior rather than a stack trace.

Could be "useful", but a lot of people would also say that catching Exception is also Evil, for the reason you mentioned. Exception catching should always be as specific as possible... even if it indeed does lead to horrendous try-catch blocks.

Well, catching Exception is okay as long as you rethrow the exception. But yes, catching it and not rethrowing is evil.


That's a relatively minor thing, but more generally, I do think the Java misuses exceptions rather badly. Exceptions are useful for reporting errors *outside* of the program. Not inside of it.

An interesting proposition... I do like the idea that a program's internal state should never lead to an exception.

This proposition is now generally accepted in the C++ community. Exceptions are intended as a more elegant alternative to return-code error handling. When was the last time you saw a C program that has functions that return a result that means 'this function has a bug in it'? Exceptions are just not useful for this purpose, just like returning an error code wouldn't be either.

Re transactions and exceptions... I read some other argumentation against Java in this regard, and I do see the point. I've been cursing Java for this very reason myself... "finally" is a good idea in resource release, but doesn't quite get the job done in a comprehensive way.

Writing try...finally blocks everywhere is highly error prone. I rarely have to write any kind of try blocks in C++.

In conclusion, I honestly cannot think of a project where I would use Java over C++. Possibly something that needs to be highly portable, but I have had good success writing programs that need to run on Windows and Linux using C++.

Maybe something involving server-side web, but in that case, I'd likely use Perl, or maybe Python.

-Sirp.
 
I guess I'll just go

:worship: :worship: :worship:

Good stuff.
 
Back
Top Bottom