22

The typical reason I hear to why people bash C++ is that they don't actually know C++, they just know "C with classes", which apparently is different. I am just beginning to learn C++, however, I want to actually learn C++ and not simply "C with classes". How can I ensure I learn C++ properly? Some examples would be wonderful.

1
  • 2
    Know and feel RAII. This is the cornerstone to everything C++. Commented Nov 5, 2012 at 15:55

7 Answers 7

27

For one thing, use the STL. Above all, know your containers (vector, deque, list, map, set, &c.) and their performance characteristics. Have a solid understanding of where and how to apply even the basics (accumulate, transform, remove_if) of the algorithmic primitives defined in the <algorithm> header. Understand that C++ is a multi-paradigm language, and don’t try to force everything into the OO model.

If something you’re doing isn’t plain, legible, and type-safe, chances are you're doing it the C way. Learn the basic standards of type safety, const correctness, reference semantics, and RAII, all things that subtly but profoundly set C++ apart from C. Keep up to date on current developments in the language (type inference with auto, lambdas, rvalue references) and apply them to improve the clarity and quality of your code.

2
  • 7
    agree with everything except using for_each, its the least useful algorithm imho
    – jk.
    Commented Feb 16, 2011 at 9:54
  • @jk.: Yes, C++11 range-based for or BOOST_FOREACH are much easier to use than std::for_each.
    – Jan Hudec
    Commented Nov 5, 2012 at 13:59
18

Read good books, blogs, and other resources. Practice.

"C with Classes" was the original (or at least predating "C++") name for the language, but today it is used to convey the sense that someone is essentially writing C using minimal convenience features of C++.

1
  • 3
    +1. As a general guide, any book that mentions stdio.h/string.h/stdlib.h before covering iostream/string/new operator are likely from the "C with Classes" era. Commented Feb 16, 2011 at 14:00
13

@Fred Nurk has already posted a link to the book list, so I won't try to go into detail, but I'd consider Accelerated C++ the first book on that list to study from.

As for an example, let's consider a fairly simple program: a simplified version of the standard Unix "sort" command. To keep the code short (but still at least a little interesting), let's have it operate as a filter, and produce results roughly equivalent to sort -u. In C with Classes type code, you might typically see something on this order:

#include <iostream>
#include <cstdlib>
#include <cstring>

using namespace std;

const int max_lines = 1024 * 1024; // allow up to one megaline of input.

int sort_func(void const *a, void const *b) { 
    return strcmp(*(char const **)a, *(char const **)b);
}

int main() {
    char buffer[1024];
    char **lines;
    unsigned current_line = 0;

    lines = new char *[max_lines];

    while (cin.getline(buffer, sizeof(buffer))) {
        char *temp = new char[strlen(buffer) + 1];
        strcpy(temp, buffer);
        lines[current_line++] = temp;
        if (current_line == max_lines)
            break;
    }

    qsort(lines, current_line, sizeof(lines[0]), sort_func);

    cout << lines[0];

    for (int i=1; i<current_line; i++)
        if (strcmp(lines[i], lines[i-1]))
            cout << lines[i] << "\n";

    for (int i=0; i<current_line; i++)
        delete [] lines[i];
    delete lines;
    return 0;
}

Now, this isn't particular terrible code (if I was being entirely honest, I'd probably make it worse). It passes the buffer size to getline, so the buffer won't overflow. It then allocates a buffer for a line, copies the data to the buffer, and goes on to the next. It even checks for the end of file correctly, etc.

Let's compare that to how I'd probably write the code in C++:

#include <iostream>
#include <iterator>
#include <set>
#include <string>

class line { 
    std::string data;
public:
    operator std::string() const { return data; }   
    friend std::istream &operator>>(std::istream &is, line &l) { 
        return std::getline(is, l.data);
    }    
};

int main() { 
    std::set<std::string> lines((std::istream_iterator<line>(std::cin)), 
                                std::istream_iterator<line>());    
    std::copy(lines.begin(), lines.end(), 
              std::ostream_iterator<std::string>(std::cout, "\n"));
    return 0;
}

This version is clearly a bit shorter. We've also eliminated most of the fixed limits such as the maximum line length and maximum number of lines. More importantly, however, it contains no explicit loops -- the input loop is handled implicitly in the constructor for the set, and the output loop is handled in the call to copy. Sorting and eliminating duplicates is implicit in the definition of set.

8
  • 7
    I find it a bit ironic that the C with classes example does not contain a class declaration, but the other one does.
    – Spoike
    Commented Feb 16, 2011 at 8:29
  • 1
    @Spoike: Yes, I considered including a semi-pointless class or two, but it would have made the code longer without adding much. Despite the lack of defining a class, I think the general flavor comes through... Commented Feb 16, 2011 at 8:35
  • Yeah. I believe in order to do good C++ code you need to start using template libraries and "code smarter" that way. Beginning C++ programmers don't know what a template class is, let alone program with them.
    – Spoike
    Commented Feb 16, 2011 at 8:42
  • 4
    +1 Awesome demonstration sample! This succinctly demonstrates the difference in thinking behind "C with Classes" (just write C code but use the 'new C++ bits') and C++. Commented Feb 16, 2011 at 14:04
  • 2
    @PabloAriel: As much as anybody might like to pass strcmp's address directly to qsort, doing so isn't allowed or portable -- the signature for qsort's comparison function is required to be int (*)(void const *, void const *), and that doesn't match what strcmp provides. Commented Nov 5, 2012 at 15:11
3

Read what the designer of C++ thinks on Learning C++ as a new language.

To get the most out of Standard C++ [C++,1998], we must rethink the way we write C++ programs. An approach to such a "rethink" is to consider how C++ can be learned (and taught). What design and programming techniques do we want to emphasize? What subsets of the language do we want to learn first? What subsets of the language do we want to emphasize in real code?

This paper compares a few examples of simple C++ programs written in a modern style using the standard library to traditional C-style solutions. It argues briefly that lessons from these simple examples are relevant to large programs. More generally, it argues for a use of C++ as a higher-level language that relies on abstraction to provide elegance without loss of efficiency compared to lower-level styles...

2
  • link out of date?
    – funkybro
    Commented Nov 5, 2012 at 13:37
  • fixed the link now.
    – grrussel
    Commented Nov 5, 2012 at 14:39
0

C++ is C with classes, some automatic-cleanup in destructors (RAII), exceptions, polymorphism, operator overloading, templates (generics), together with a standard library built on generics that gives you collections and algorithms.

When you say "C with classes", well yes it is to some extent as much of the above is part of what is a feature of a class.

If you know C and wish to learn C++ you might read "Accelerated C++", although to some extent that may be a bit dated as I am not sure it covers shared_ptr which is almost a "must use" part of C++ now (part of C++0x but available in boost for a long time now and may be already in your std now).

Therefore after "Accelerated C++" read "Beyond the Standard Library".

0

I know this is going to be controversial but to really study C++, don't use pointers. Pointers are useful in C++, but their usage in beginning may influence one to perceive C++ as 'C with classes'

0

C with classes with a good organization of source code files you can make your app faster for both compiling and running, while abusing of the later "academic C++" will increase compiling up to 100 times slower and your application will never be able to run properly if performance does matter. In the company I work on (probably the biggest in its sector) they have some tools that take up to 30 minutes or even more to compile, while I wrote the same functionality for myself at home and the compiling times are BELOW THE MINUTE, and it does have many less bugs and is far more maintainable that the spaghetti of templates used at work. So what really matters is if you want to get the job done or if you just want to say you code perfect academic C++.

But to realize this, you have to code a lot and learn how to properly code C with classes. Which probably would require you to learn academic C++ first :), or not, it depends a lot on your skills and will and perseverance, so you don't end up coding terrible either C++ or C with classes.

2
  • I don't entirely disagree with the point I think you are trying to make here, but some examples/guidelines of good organization vs going too far on the theoretical purity of your code would make this a better answer.
    – Bill
    Commented Nov 5, 2012 at 14:02
  • Thanks for the feedback, I'm gonna try to improve my answer for it to be more explicative for those who don't have enough experience for understanding what I mean. Commented Nov 8, 2012 at 17:54

Not the answer you're looking for? Browse other questions tagged or ask your own question.