All Comments
TopTalkedBooks posted at August 20, 2017

About two years ago, I made the switch from C# to C++ (after 10 years of writing java). The most useful book for me was Bruce Eckel's Thinking in C++ [AMZN]. You can also read the book online at Eckel's website. It's a well-written book--the kind you can read in bed--that's also useful as a keyboard-side reference. It assumes a significant level of comfort with OO and general programming concepts.

Stroustrup [AMZN] is invaluable as a reference, but basically impenetrable unless you're trying to answer a very specific question--and even then, it's a struggle. I haven't cracked my K&R [AMZN] in a few years. I don't think it's got much value as a C++ reference. Myers' Effective C++ [AMZN] (and, once you get there, Effective STL [AMZN]) are fantastic books. They're very specific, though (e.g., "36. Design functor classes for pass-by-value"), and hence not as useful as Eckel for making the transition.

My experience writing C++ after many years writing managed languages has been great. C++ is a hundred times more expressive than C#, and extremely satisfying to write--where it's warranted. On the other hand, on the rare occasions when I still get to write C#, I'm always amazed by how quickly and succinctly I can get things done.

Anyway, Eckel's Effective C++ can help you make the transition. There's a second volume that's good, but not as good. Stick with the original.

Good luck!

TopTalkedBooks posted at August 20, 2017

Your first case creates a single char element (1 byte) whereas your second case creates 10 consecutive char elements (10 bytes). However, your access of t(x)[100]='m' is undefined in both cases. That is, you are requesting 100 bytes after the position of the pointer, which is most likely garbage data.

In other words, your assignment of 'm' will overwrite whatever is already there, which could be data from another array. Thus, you may encounter some bizarre errors during runtime.

C/C++ allows programmers to access arrays out of bounds because an array is really just a pointer to consecutive memory. The convention t1[100] is just 100 bytes after the pointer, no matter what that is.

If you want "safe" arrays, use the vector class and invoke the at() function. This will throw the out_of_range exception if the access is invalid.

Stroustrup gives the following example:

template<class T> class Vec : public vector<T> {
public:
    Vec() : vector<T>() {}
    Vec(int s) : vector<T>(s) {}

    T& operator[] (int i) {return at(i);}
    const T& operator[] (int i) const {return at(i);}
};

This class is boundary-safe. I can use it like this:

Vec<char> t3(10);                // vector of 10 char elements
try {
    char t = t3[100];            // access something we shouldn't
}
catch (out_of_range) {
    cerr << "Error!" << endl;    // now we can't shoot ourselves in the foot
}
TopTalkedBooks posted at August 20, 2017

According to Stroustrup in the C++ Programming Language:

Which style you use depends on circumstances and taste. I usually prefer to use struct for classes that have all data public. I think of such classes as "not quite proper types, just data structures."

Functionally, there is no difference other than the public / private

TopTalkedBooks posted at August 20, 2017

I want to add to Southern Hospitality's answer Static variables in C and C++

the following remarks:

The use of static to indicate "local to translation unit" is deprecated in C++ ( href="https://toptalkedbooks.com/amzn/0201700735" The C++ Programming Language: Special Edition, Appendix B.2.3, Deprecated Features).

You should use unnamed namespaces instead:

static int reply = 42; // deprecated

namespace {
    int reply1 = 42;  // The C++ way
}

As already said by Southern Hospitality, the order of initialization of global objects is undefined. In that situation, you should consider using the href="http://en.wikipedia.org/wiki/Singleton_pattern#C.2B.2B", Singleton pattern.

UPDATE: GMan commented my answer:

"The order is defined per-translation unit, ...": This really slipped my mind, so I looked it up in The C++ Programming Language.

In Section 9.4.1, Initialization of Non-local Variables, Prof. Stroustrup suggests that "a function returning a reference is a good alternative to a global variable":

int& use_count()
{
        static int uc = 0;
        return uc;
}

"A call to use_count() now acts as a global variable that is initialized at its first use. For example:"

void f()
{
        std::cout << ++use_count() << '\n';
}

In my understanding, this is very similar to the Singleton pattern.

GMan commented further: "We need to limit our ability to create these objects to one, and provide global access to it." Does the limiting to one really relate to anything in the problem? We may need one globally, but who's to say we don't want it in other places?"

Some quotes from Singleton(127) (Gamma et al, Design Patterns):

"The Singleton pattern is an improvement over global variables. It avoids polluting the name space with global variables that store sole instances."

"The pattern makes it easy to change your mind and allow more than one instance of the Singleton class."

Singletons are initialized in the order they are first used.

In Herb Sutter, Andrei Alexandrescu, C++ Coding Standards, Item 10 says:

"Avoid shared data, especially global data."

Therefore I use often Singletons to avoid global data. But of course, as everything is overusable, this could be a overuse of the Singleton pattern. (Johshua Kerievsky calls this "Singletonitis" in his book "Refactoring to Patterns".)

UPDATE 2:

(Sorry, but I cannot write comments, therefore this Update.)

Jalf wrote in his comment: "The gang of four were smoking something illegal when they wrote about the singleton pattern."

Obviously, other C++ developers smoked interesting substances, too. For example, Herb Sutter (he served for over a decade as secretary and chair of the ISO C++ standards committee during the development of the second C++ standard, C++0x, and as lead architect of C++/CLI at Microsoft. Herb is currently the designer of the Prism memory model for Microsoft platforms and the Concur extensions to Visual C++ for parallel programming), wrote in C++ Coding Standards, Item 21:

"When you need such a (namespace level) variable that might depend upon another, consider the Singleton design pattern; used carefully, it might avoid implicit dependencies by ensuring that an object is initialized upon first access. Still, Singleton is a global variable in sheep's clothing, and is broken by mutual or cyclic dependencies."

So, avoid global data, if you can. But if you have to use global data in separate translation units, Singleton should be an acceptable solution for enforcing a specific initialization sequence.

Note that in the Java language global data does not even exist. Obviously, global data is substituted/emulated by the use of the Singleton design pattern.

(For I am working in my dayjob with a Java team, I strive for a maximal similarity of my C++ programs with Java programs. E.g, every class is situated in its own source file/translation unit.)

TopTalkedBooks posted at August 20, 2017

C++: Stroustrup's book and/or Stroustrup's D&E or Stroustrups ARM though the latter two are not in date. The ISO spec is available (see Charles bailey's answer) and is the final word if that's the type of doc you want. The most thorough answer is in the comments by aJ :- The Definitive C++ Book Guide and List. The equivalent of K&R for C++ is the first one.

C#: The C# Programming Language (3rd Edition) by Anders Hejlsberg, Mads Torgersen, Scott Wiltamuth, and Peter Golde). If you're looking for the generally accepted definitive book on C#, that's C# in depth.

TopTalkedBooks posted at August 20, 2017

Multiple inheritance is not often used in C++. In most cases it's a mixin of interface / implementation. It's not forbidden, also. The need for (virtual) multiple inheritance comes from design decisions to derive from one general base class:

class Window 
{ /* draw, show, hide, background ... */ };

class WindowWithBorder : public virtual Window 
{ /* methods to manipulate / draw border ... */ };

class WindowWithMenu : public virtual Window
{ /* methods to manipulate / draw Menu ... */ };

class MyWindow : public WindowWithBorder, public WindowWithMenu
{ /* now it's your turn ... */ };

Those diamond-shaped inheritance graphs must be foreseen by the library implementer. Without virtual there would be two base Window objects, with virtual it's only one, but not a singleton, since there can be many windows.

Libraries can often (but not in every case) avoid such situations, e.g. by implementing a composite design pattern, having a "fat" base class, by implementing abstract interface classes, or by using templates with traits / policies.

I would recommend to read the chapter on class hierarchies in Bjarne Stroustrup's The C++ Programming language (ch. 15 in my 3rd edition, I borrowed the example from).

Top Books
We collected top books from hacker news, stack overflow, Reddit, which are recommended by amazing people.