?
Solved

C++ - How to further self-education...

Posted on 2003-02-18
12
Medium Priority
?
280 Views
Last Modified: 2010-04-01
I am trying to teach myself C++.  I have experience with like a dozen other languages, but C++ is by far the most complex and the closest to the machine that I have ever tried to learn.

I know PHP, VB (6 and .NET), ColdFusion, JavaScript, a dabbling of Java, Perl, ASP, and a bunch of other stuff.

I have read this book on C++:
http://www.amazon.com/exec/obidos/tg/detail/-/1576760634/qid=1045626723/sr=1-1/ref=sr_1_1/102-0171348-9453700?v=glance&s=books

It was a decent book.  And I understood most of it.  My question: how should I proceed in C++?  I feel that I know a lot about the syntax and capabilities of the language.  But I couldn't make a GUI program (in Windows or anything else).  What are people doing nowadays with C++?  Should I move on to C++ .NET, or is that a doomed thing?  What books should I read?  What websites should I go to?

I know this isn't usually the sort of question that gets posted here.  But there is a lot of expertise here and I would like to try to attain that level as well. :-)

Thanks,

Justin Kohlhepp
justin@coffeegeek.net
0
Comment
Question by:curmudgeon42
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
  • 2
  • +2
12 Comments
 
LVL 8

Expert Comment

by:Exceter
ID: 7979544
>> and the closest to the machine that I have ever tried to learn.

Keep in mind, this is still a high level language. :-)

Exceter
0
 

Author Comment

by:curmudgeon42
ID: 7979620
Yes but in every other language I've learned I've never once had to be concerned with whether a variable was a value or a memory address of a value (i.e. a pointer) and arrays are just pointers that don't do bounds checking and strings don't exist they are just char arrays that are passed around as pointers and ... well you see my point

Don't get me wrong, I can see that the language is extremely flexible and powerful.  I'm just a bit overwhelmed and don't know what to do next.
0
 

Author Comment

by:curmudgeon42
ID: 7979627
Yes but in every other language I've learned I've never once had to be concerned with whether a variable was a value or a memory address of a value (i.e. a pointer) and arrays are just pointers that don't do bounds checking and strings don't exist they are just char arrays that are passed around as pointers and ... well you see my point

Don't get me wrong, I can see that the language is extremely flexible and powerful.  I'm just a bit overwhelmed and don't know what to do next.
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 7

Expert Comment

by:burcarpat
ID: 7979696
> "Yes but in every other language I've learned I've never once had to be concerned with whether a variable was a value or a memory address of a value (i.e. a pointer) and arrays are just pointers that don't do bounds checking and strings don't exist they are just char arrays that are passed around as pointers and ... well you see my point"

from this description, i can easily say that the book you had is a terrible one.  things like char arrays, dynamic arrays which are nothing but pointers, a lot of pointer stuff, etc. is *not* c++; that's c.  sure, c++ includes c and thus you should know about them but it is not encouraged to use those features unless you are absolutely required to do ( and, two common reasons for that is, performance or a need to work with a legacy c api )

when you are writing true c++, pointers have much less use and even then there are smart pointers.  also, there are a bunch container classes ( vector, list, map, etc. ) which has bounds checking and suits a lot of different needs and they should always be preferred over dynamic arrays.  there are many basic algorithms already coded.  and, finally, there is a std::string class with full string semantics which replaces char* ( when you see any example talking about strxxx functions instead; run away.  that means they are talking about c-style strings )  heck, even the i/o is fully object oriented.  old timers would talk about printf, atoi, FILE*, etc.  yet, a good c++ programmer would know the power of iostreams

any c++ book, that doesn't talk about these is a bad book.  i would suggest reading "STL Tutorial and Reference Guide: C++ Programming with the Standard Template Library" by David R. Musser, et. al ( make sure you get the 2nd. ed. )  alternatively, you might wanna try "The C++ Standard Library - A Tutorial and Reference" by Nicolai M. Josuttis, which is an excellent book ( also covers iostreams very nicely ) but not necessarily suited towards starters

another alternative is at,

    http://www.mindview.net/Books/TICPP/ThinkingInCPP2e.html

this might be the best link for you because if you download the html version of the book, it has an interactive index, which means you can lookup for certain topics and immediately see examples and explanation.  alternatively, you can read through the book like a regular book, too ( it almost reads like a novel ).  this link points to a free downloadable version of bruce eckel's very good "thinking in c++" book, which is a 4.5/5 stars book on amazon and a $30 value

note that, this book is not as good as the previous two, especially not at the josuttis caliber but it's still a good one.  yet, it does *not* remove your need to buy one of those previous books for improving your STL skills

so, to summarize:  it's common for books to start talking about pointers, char*, arrays, etc. when teaching c++ but the real c++ lies within STL and iostreams.  learn those and never mind the other details.  i have been doing c++ programming for years now and have been involved in very large projects and never felt the need to use c-like features of c++, other than when i needed to connect to a legacy c api

oh, almost forgot:  if you are into GUI building and you want to do that under Windows, C++.NET is a good choice.  standard c++ does not have a GUI toolkit and thus you are always gonna end up using a platform-specific of vendor-specific api for that purpose.  thus, you might choose C++.NET as well.  note that, if you are really into GUIs and windows programming, then i suggest you to skip c++ altogether and to learn microsoft's c#, which is java-like and better suited for windows programming
0
 

Author Comment

by:curmudgeon42
ID: 7979711
the book i had covered STL and iostreams - i don't know if it covered them completely, but it seemed fairly extensive to me

i don't know about C# b/c it seems like no one is using it - am I wrong in this biased opinion? :-)
0
 
LVL 8

Expert Comment

by:akshayxx
ID: 7979762
if u really want to appreciate the "POWER" of C++ in the sense of its being closer to machine .. then first get the feel of C. C++ is nothing but C with objects and classes stuff.  ( yes there is objective C also).

as burcarpat already mentioned .. pointers and all that sort of stuff is more of C than C++,
and also  if u r fascinated about having  closeness with machines in terms of (programming language), then  how come you havent heard of Assembly language as yet?
 may be u heard but didnt accept it as programming language?

 



0
 
LVL 12

Accepted Solution

by:
Salte earned 300 total points
ID: 7980715
First off, C# is a relatively new language. There are some but not many who use it today but I guess many will use it in the future.

One drawback with C# is that it lacks templates. MS is working on that and generic C# should be available at some point in the future.

Another - and perhaps the biggest - drawback of C# is that it is only running on M$ platforms. However, the mono project and similar efforts tries to port C# to Linux and other systems as well. So again, this is mostly a temporary drawback which will be diminished at some point in the future.

Secondly, I won't say you should run away when people talk about strcmp() etc. There are tons of useful software around in C which has no choice but to use C style strings as well as lots of C++ software around that also uses them. They are cheaper in some ways than std::strings and when all you need is a small buffer of a relatively fixed size then writing char buf[100] is just as easy and safe for you as writing std::string buf; and it even gives you a more raw buffer where you can do what you want with the string. An std::string "suffer" from the fact that you can only get a const char * pointer to it but not a modifiable pointer. This is because the string object may share the actual string with other string objects. The std::string class uses reference counting to handle this sharing, but it means that the class do not want you to mess with the string directly. Normally this is a good thing and so the "suffer" really must be in quotes, it isn't any bad thing at all. However, once in a while you really would like to mess with the string yourself and you know what you're doing, that's when those C style strings come very handy and strcmp() etc becomes your preferred choice.

I am not saying that you shouldn't use std::string, by all means it should be the 'normal' choice for most people when they just want a string and manipulate it. But I am saying that you shouldn't shy away from char [] just because it isn't std::string. However, if you don't know what you're doing and you do pointer arithmetic without limitations you are far safer with std::string than with a char [] since the chances for error is less. It is still possible to crash with std::string but the probability that you do so is smaller.

And so, it IS important to know when a variable is lvalue and when it is rvalue. This is very important in C and therefore also in C++ which includes most of the C stuff as a subset. It is really also important in other languages but in those you seldom end up with things being lvalues when you don't expect them to and so most people don't think in terms of lvalue/rvalue when try to understand what is going on.

x = x + y;

Look at the expression above. Here the expression is an assignment and since it is an assignment you must have a lvalue on the left side (lvalue originally meant left-value). The variable x's lvalue is the location in memory that the variable x refer to. If x is a constant value it doesn't have any lvalue and so the above expression is meaningless. In other words: you can't assign to a constant value. Now, in most other languages you don't learn this as an lvalue/rvalue thing because this is basically the only situation where it occur and so the rule "you can't assign to a constant" is simpler than the rule "you can't assign to a rvalue" and so most languages doesn't touch into it. Another rule you might learn is that you can't assign to expressions, just like constants expressions doesn't have any lvalue:

(x + 3) = 2;

doesn't make sense. Now in your random language this is an extra rule in addition to the constant rule "don't assign to expressions" but in C we recognize that it is the same thing. (x + 3) is something that doesn't have any lvalue associated with it and so therefore you can't assign to it.

However, it is a trap to think that all lvalues are memory locations. For example a machine register can be allocated to store a variable. Such a variable can have values and can change just like any other variable but it has no memory address associated with it - it is not in RAM. You can still assign to it and so it is still an lvalue though. Bitfields are in a similar situation, you can't take the address of them but they are still lvalues and can be assigned to.

Since C has pointers the lvalue/rvalue problems occur in more situations:

*(x + 3) = a + b;

If x is a pointer of type T then *(x + 3) is simply the same as x[3] and so the above statement is clearly legal, even though we previously said you can't assign to expressions this is legal. Clearly the previous rule is wrong. Languages that only allow assignment to simple variables wouldn't have this situation but most languages in the world are a tad more complicated than that and so the simplistic "you can't assign to expressions" is blatantly wrong and the correct rule is "you can't assign to rvalues" or "you need an lvalue in order to assign to it".

A simple variable has both an rvalue and lvalue, the variable x may have the value 3 at the moment and if so then that is the lvalue of the variable, the rvalue will frequently change and that is why it is called a variable. Constants, on the other hand, have constant rvalues and do not change them during their life time. The lvalue of a variable indicates where you store the rvalue in order to change the value of the variable. If the variable is allocated in RAM then it is typically associated with the address of the RAM location. However, for local variables it is more commonly associated with an offset into the stack frame for the function, since each function call instance has its own copy of the variable and so the RAM address isn't really the normal way to access such a variable.

My point here is that pointers, lvalue and rvalue IS important and should be important for C, C++ and other languages. A programmer should know about those concepts it will make it a lot easier for him or her to understand what is going on when he or she becomes aware of questions and the answers to them like "where is the space for this variable allocated?", "when does it start its life time?", "when does it die?".

These are even more important for C++ since the creation is when the constructor is called and the destruction is when the destructor is called and so the life time and where a variable is allocated becomes important issues that a C++ programmer SHOULD understand.

Now, for a plain windows application writing hello world or some other simplistic thing or a standard ANSI C++ application writing to stdout and reading from stdin and doing relatively simple tasks you don't have to know about those things, that is true. The STL does a good job in "hiding" all the nitty gritty details about object allocation, creation, destruction, pointer arithmetic etc etc for you and you can get a long way working with high level constructs like std::string, std::map, std::list, std::vector etc etc etc.

However, it sure helps to know what those data structures does with your data when you do a cin.getline(), what does that cin.getline() function do? It also helps very much to understand what goes on under the hood if you want to make your own iostream class that read/write to some other location or if you want to make a template class for a new type of data structure that you use in your software.

It also helps to know when you should NOT use the STL classes. For example in code that need to be fast you might choose to not use one STL class but instead opt for either another STL class or perhaps make your own that is specifically suited to your needs. True, it is not a good idea to write your own string class "just because". If you do it just because you want to have your own class you might as well use the STL class, but in some situations your own class to solve a specific problem is exactly what you need and that's when it is good to know how you can implement functionality that is similar to the STL classes or perhaps make your own class derive from a stl class or make your own class in such a way that it can be used as template argument for a specific concept used in STL.

I have myself over and over again found it useful to make traits classes, using the same mechanism as used in the iostream and std::string classes from STL. Now, I might be able to figure out how to make those without ever seeing STL doing it, but it sure helped to use those as models in order to figure out how to do it and not the least get the confidence that you can do this efficient just as it is done in STL.

template <class T>
class traits_t {
public:
  typename unsigned_type_t;

  static size_t size_in_bits();
  static T null_value();
  static T max_value();
  static T min_value();
  static descriptor_t * descriptor();
};

template <>
class traits_t<int> {
public:
   typedef unsigned int unsigned_type_t;

   static sizet size_in_bits() { return 32; }
   static int null_value() { return 0; }
   static int max_value() { return 0x7fffffff; }
   static int min_value() { return -0x80000000; }
   static descriptor_t * descriptor()
   { return & int_descriptor; }
};

Now you can write template functions such as:

template <class T>
void do_something(const T & v)
{
   descritor_t * d = traits_t<T>::descriptor();
   d -> func(v.traits_t<T>::min_value());
}

descriptor_t is a class with virtual functions that does different things depending on the actual type. The int_descriptor may be an instance of a subclass that can handle numeric data types up to 32 bits and can implement
algorithms efficient for that. However, since it is a pointer, the descriptor is available at run time and can provide some "extended RTTI" info for class T.

As long as you provide a descritor_t * pointer to T that you give as instance argument to do_something<T>() this should work beautifully.

Of course, if you don't need the dynamic stuff you can use only the static functions in the traits_t type itself such as min_value() etc. They are all inlined and evaluate to constant values at compile time.

I guess that if I had never heard of STL I would still come up with a design like that but I wouldn't jump to it as fast as I am ready to do now - the STL gives one the confidence that this is a tried and tested method that works. However, I would NEVER come up with such a design if I had no idea what STL did under the hood probably mostly because in that case I would also have no interest to try to figure out such ways of doing things and I would generally be a bad programmer but these things are connected and one comes with the other and so I think it is a good thing that programmers knows what STL does under the hood and to know and understand that you have to know the basic C stuff that C++ is built on top of. STL uses pointers and C style arrays all the time. STL ALSO uses concepts, templates and classes all the time but they are typically in the end implemented using C style arrays and pointers.

Alf
0
 

Author Comment

by:curmudgeon42
ID: 7982794
Okay.  Thanks for all the help.  Looks like there are many different ways to go w/ this.  ALf, since yr questions obviously took tons of time to write, I will give you the points.  Sorry I can't give some to everybody who responded.
0
 
LVL 8

Expert Comment

by:Exceter
ID: 7988637
Oh man!!! Salte that post is long winded even for you!!! :-)
0
 
LVL 8

Expert Comment

by:Exceter
ID: 7988719
Salte, have you written any books about C++? You seem to know enough to have done so.
0
 
LVL 8

Expert Comment

by:akshayxx
ID: 7990745
nice post salte..
>>Salte, have you written any books about C++?
yea lets us know if u have written books .
0
 
LVL 12

Expert Comment

by:Salte
ID: 7992566
Never written any, probably could if I were asked to but nobody has ever asked me to write one :-)

I heard of C++ back in 1985 and was thus probably one of the first to hear of the language. In those days it was called "C with classes" the name C++ came later. Bjarne Stroustrup had a presentation of the language in the company I worked for at that time. In those days I mostly programmed in a propietary language used by that company and had just recently learned C.

I wrote most of my programs in C since around 1988 and programmed C++ actively since around 1989 and used both C and C++ actively since then so I think I know the language pretty well :-)

If anyone want me to write a book, let me know :)

Alf
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
Suggested Courses

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question