The C++ Programming Language: Special Edition (3rd Edition)

Category: Programming
Author: Elida Maria Szarota
All Stack Overflow 25
This Year Stack Overflow 3
This Month Stack Overflow 2


by anonymous   2019-07-21

Indeed, in those circumstances you would normally use method 2.

Typically, you would only use method 1 if the object is tiny, so that it's cheaper to copy it once than to pay to access it repeatedly through a reference (which also incurs a cost). In TC++PL, Stroustrup develops a complex number class and passes it around by value for exactly this reason.

by anonymous   2019-07-21

Thanks to the link provided by Bo Persson I've found the following to be a relevant answer:

The members and base classes of a struct are public by default, while in class, they default to private. Note: you should make your base classes explicitly public, private, or protected, rather than relying on the defaults.

struct and class are otherwise functionally equivalent.

OK, enough of that squeaky clean techno talk. Emotionally, most developers make a strong distinction between a class and a struct. A struct simply feels like an open pile of bits with very little in the way of encapsulation or functionality. A class feels like a living and responsible member of society with intelligent services, a strong encapsulation barrier, and a well defined interface. Since that's the connotation most people already have, you should probably use the struct keyword if you have a class that has very few methods and has public data (such things do exist in well designed systems!), but otherwise you should probably use the class keyword.


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.


by anonymous   2019-07-21

There is hardly a way without reading anything.

Language reference:


I like this one a lot but it's probably not the first step:

This is the unbelievable book but its content borders with insanity at some point :)

by anonymous   2017-08-20

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).

by anonymous   2017-08-20

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="" 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="", 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".)


(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.)

by crashmstr   2017-08-20

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

by anonymous   2017-08-20

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> {
    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
by cero   2017-08-20

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!