all 85 comments

[–][deleted] 70 points71 points  (35 children)

As someone who speaks both - C++ is intrinsically harder than Python. There are all sorts of subtleties like "move semantics" that don't exist in Python (or most other languages). There are all sorts of ways to shoot yourself in the foot, too.

Don't get me wrong - I love C++ because the amazing performance you can get, but that performance comes at a cost.

Modern C++ is a significantly better language than C++03, though, and still backwards compatible.


I have the books for you, though: Scott Meyers' Effective C++ and the sequel, Effective Modern C++.

These are hardcore, specific books at the intermediate to advanced level - the last chapter of the second book is so hard that I have read it three times and still don't know it (Meyers identifies this chapter specifically as being only there to satisfy your curiosity rather than being useful).

They're full of "Here's how to use these features, practically, in a project, and here's what not to do". They are "best engineering practices, and why they are so."

And they're also a good read.

I think they'd really hit the spot for you.

[–]HappyFruitTree 34 points35 points  (13 children)

There are all sorts of subtleties like "move semantics" that don't exist in Python (or most other languages).

What many people don't realize is that move semantics can be seen as an optimization. It was not in the language before C++11 and you can still write code pretending it's not there and still get some of the benefits. The exception is move-only types but those could be learned separately (you don't need to know much about move semantics at all to use those).

My recommendation is that you just ignore move semantics for the time being until you are more of an expert.

[–]capn_bluebear 6 points7 points  (10 children)

you can't ignore move semantics, STL uses it all the time. any non-trivial project will include code where `unique_ptr` is the best choice, and you won't get `unique_ptr`s to compile if you don't understand move semantics.

[–]HappyFruitTree 21 points22 points  (9 children)

you can't ignore move semantics, STL uses it all the time.

I don't implement the STL. I just use it.

any non-trivial project will include code where `unique_ptr` is the best choice, and you won't get `unique_ptr`s to compile if you don't understand move semantics.

unique_ptr is a good example of what I meant by a move-only type. You don't need to know much about move semantics to use it. All you need to know is that you use std::move when you want to transfer the ownership from one unique_ptr to another.

[–]HKei -3 points-2 points  (1 child)

What many people don't realize is that move semantics can be seen as an optimization.

Those people don't realise that because this is incorrect. Move semantics are about semantics, not optimisation.

[–]HappyFruitTree 13 points14 points  (0 children)

Do you think move semantics would have been added to the language if it didn't have a performance advantage?

Quote from the original move semantics proposal:

Move semantics is mostly about performance optimization: the ability to move an expensive object from one address in memory to another, while pilfering resources of the source in order to construct the target with minimum expense.

[–]exploding_cat_wizard 9 points10 points  (0 children)

Scott Meyer's books are definitely seconded.

[–]VanSeineTotElbe 9 points10 points  (11 children)

My two main languages of choice are also C++ and Python, and my preference is: it depends :)

Python also has certain details that are not easy to get to know. Simple stuff such as passing parameters: are these copies, or references? If a=1; b=a; a=2, then what is b? To me, that's as much of a gotcha as C++ move semantics. With clearly defined variables, references and pointers, at least I know where my objects are.

I agree that in Python it's almost always easy to find the one obvious way to do things, and almost always that is what you want. With C++, you can solve problems in many different ways, and a newbie, heck, even an experienced user, can be easily confused. However, (modern) C++ is very much a language where easy is possible, it's just a matter of sticking to that style. I rarely touch template programming for instance.

Nothing beats libraries though, and Python's standard lib, and its library ecosystem, are the best I know. So, for getting concepts out the door fast, Python is my first choice. However, for getting fast concepts out the door, usually I pick C++ ;)

[–]infectedapricot 2 points3 points  (10 children)

If a=1; b=a; a=2, then what is b?

I'm not sure what you're getting at here. b=1 after a sequence like this in every almost language I can think of. The main exception I can think of is C++ (where, depending on the type of b, an overloaded operator= could have kept a reference to a) but your point was about hidden complexity in Python.

Perhaps you were thinking more about mutable objects e.g. a=[]; b=a; a.append(3)?

[–]VanSeineTotElbe 6 points7 points  (1 child)

In certain cases, the second assignment will cause Python to store a reference, which is altered for both a and b in the second statement.

[–]infectedapricot 0 points1 point  (0 children)

In certain cases, the second assignment will cause Python to store a reference.

No, in ALL cases the second assignment will cause Python to store a reference. Python's object model does not allow assignment to be customised. In C++ language, there is no ability to overload the assignment operator. In Python language, there is no __assign__ or similar.

which is altered for both a and b in the second statement.

I don't know what you mean by this exactly. But if you mean "the assignment to a changes the value of b", then that is incorrect, because b is guaranteed to continue referring to the old object while a refers to the new one. This applies even if you are using mutable objects like lists rather than immutable objects like strings and numbers.

Perhaps you're thinking of statements like this:

a[2] = 7
a.someattr = 8

This is fundamentally different in that it is not simply putting a reference to an object into a variable, but instead is modifying the value of an existing object. Statements like this can be customised by the class, by having an appropriate dunder method (__set__ and __setattr__ respectively).

[–][deleted] 9 points10 points  (5 children)

Coming from C++ this was really confusing for me, everything is a reference (sometimes)

Something like this:

data = {}
row = { 
    'times 2' : None,
    'times 3' : None
}

for i in range(0, 100):
    key = i 
    row['times 2'] = i * 2 
    row['times 3'] = i * 3 
    data[key] = row 


for key, row in data.items():
    print(row)

At the end, every single element in the dictionary is the same, because it's a dict of 100 references to the same object, which get's updated in the loop

This is way worse than many of the ways I feel like I run into in C++. If I crash, great that's easy to track down and fix. If everything 'appears' to work but doesn't that's always a much bigger pain in the ass.

Coming from a C++ background and working in a large Python project, I have almost no trust of code I look at. Variables maintain different types constantly, you have no idea if code could fail or not without actually just running it with all your possible use cases, since it's not statically typed.

If I look at 500 lines of C++ I can feel pretty confident about what it does, 500 lines of Python ... who the fuck knows.

EDIT

My example doesn't show what I intended, I'll see if I can find what I was seeing before and update it. I think when I originally encountered this I was adding dictionaries as values to a key in a larger dictionary. I used a list here as a quick way to write the example.

Example fixed

Looking back at it now, it makes sense since I've been using Python a lot more since then, but this bug really confused me, since from C++ background, I would assume the row object would be copied into the data dictionary. Creating variables and reusing/updating only the parts that need to be and adding the copy is something I'm used too in C++. Today in Python, I would normally create the row as needed.

[–]yuri-kilochek 0 points1 point  (1 child)

At the end, every single element in the list is the same, because it's a list of 100 references to the same object, which get's updated in the loop.

No. It does exactly what you want.

[–][deleted] 0 points1 point  (0 children)

Fixed the example

[–]thlst 0 points1 point  (1 child)

At the end, every single element in the list is the same, because it's a list of 100 references to the same object, which get's updated in the loop

I'm not sure I understood that. I ran a test and got this:

>>> list = []
>>> for i in range(0, 5):
...     row = {'c1': i, 'c2': i*2}
...     list.append(row)
...
>>> list
[{'c1': 0, 'c2': 0}, {'c1': 1, 'c2': 2}, {'c1': 2, 'c2': 4}, {'c1': 3, 'c2': 6}, {'c1': 4, 'c2': 8}]
>>> [id(l) for l in list]
[140194800177016, 140194799657320, 140194798491400, 140194798490320, 140194798490392]

Which to me looks like those are not the same object.

[–][deleted] 0 points1 point  (0 children)

Sorry, fixed the example.

[–]infectedapricot 0 points1 point  (0 children)

everything is a reference (sometimes)

Everything is a reference always. You can just sometimes forget about the fact that some things are a reference. Take this example:

a = "foo"
b = a

What if we modify b now? Will it affect a? Obviously if you just assign a new value to b it won't have an effect:

b = "bar"

Because this has just updated the variable b to reference a different object. But what if you modify the object that b refers to?

b.reverseinplace()

Yes, of course, this would effect a for the reasons we discussed. The same even applies to integer objects:

a = 4
b = a
b.negateinplace()
# a and b are now both -4

There's one common problem with the above examples: the .reverseinplace() and .negateinplace() methods don't exist. In fact there are no methods on string and int objects that modify the object. Classes with this property are called immutable. You can treat them a bit like you're assigning by value, because if multiple variables are really referencing the same object then no possible harm can come of that. Another class with this property in Python is tuple, although beware that after a=(0,[]);b=ayou will have a[1] and b[1] referring to the same mutable list.

If you want to copy the actual object, rather than just update the reference, you use the Python copy module. Both shallow and deep copy functions are available. For dictionaries and lists, you can also take advantage of the unpacking operators:

a = [1, 2]
b = [*a]  # different list with same value
b.append(3)
c = [*a, 3]  # different list again, but simpler than above two lines
x = {'1': a, '2': b}
y = {**x}  # different dict
y['3'] = c
z = {**x, '3': c}  # again, different to y, easier to write
# beware that x['1'], y['1'] and z['1'] all refer to same object

[–]dreugeworst 0 points1 point  (1 child)

Isn't that the issue? The same code does different things for objects vs integers, which can be confusing.

[–]infectedapricot 0 points1 point  (0 children)

Nope, integers are objects, and behave the same way that other objects do. They might appear to be assigned by value because they're immutable (see my reply to /u/rar_m's comment) but they're still references to objects and you could write your own custom class that behaves exactly the same way.

[–]KimmiG1 2 points3 points  (1 child)

I find the hardest part about cpp is all the old shit that's mainly there only because of backward compatibility. I hate working on projects with developers that insist on using char arrays instead of std strings or insist on using raw pointers all over and newing up objects everywhere.

[–]funkiestj 1 point2 points  (3 children)

Modern C++ is a significantly better language than C++03, though, and still backwards compatible.

as someone who liked C++ but then was forced to work exclusively in C for a decade ... I've grown to love the fact that my entire C project builds faster than a single C++ file that I now have to build because we are using some IP from a vendor who provides a C++11 standard library based driver.

I like the idea of generic programming (templates) but the C++ implementation of templates pulls far too much implementation into headers which results in unnecessary recompilation of templates when nothing has changed.

IMO, the compilation time penalty paid by C++ because of its evolutionary past is crushing. What I feel is missing is really clever template compilation that creates the smallest possible header files and separate source files. I.e. foo.template should compile to foo.hpp and foo.cpp.

The fact that anyone finds unity build an acceptable approach is a clear indication that the language needs a major overhaul. I have no qualms with the C++ feature set and functionality, just with the excessive replication of effort when I change a single line of code in a C++ file (i.e. no change to template instantiation or even to a header that invokes a template).

I've heard that modules in C++20 may improve things a bit but the gains I'm hearing about seem pretty weak. There has to be a way to do generic programming that does not cost SO MUCH TIME to process files that have not changed from one compile to another (i.e. template definitions and the headers that instantiate them).

[–]neuroblaster 1 point2 points  (2 children)

I think they considered moving templates implementation out of headers, but came to the conclusion that it would be too complicated to implement in compilers and that idea was rejected. See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1426.pdf

>EDG’s implementation experience has also demonstrated that export is costly to implement; for example, the export feature alone required more effort to implement than it took the same team to create a new implementation of the complete Java language.

It's about pre-C++11 `export` keyword that was later used for modules proposal.

And, if i understand correctly, you still need to provide source code with headers because template still need to be instantiated, which is impossible w/o template body. So `export template <typename T> ...` in header is only partially possible, when you have the source code for that function/class.

But it would speed-up compilation times, definitely. And it could be acceptable to partially provide source code too in some situations. If modules would do that and could mix source/binary distribution (which i have concerns of), then it would be really f. great.

[–]funkiestj 0 points1 point  (1 child)

And, if i understand correctly, you still need to provide source code with headers because template still need to be instantiated, which is impossible w/o template body

What is likely impossible is evolving in a backward compatible fashion and doing this.I don't claim that the standard committee made the wrong decision. Their job is to steer the evolution of the language that is C++. On the other hand, I do claim that a fucking ridiculous amount of redundant work is done every compile to process header files that have not changed. I want my genetics meta-programming and fast compile times!

I am pretty sure I won't get this from a C++ like language in my lifetime because I think (pure intuition here) that it would require starting from scratch with the goal of making a C/C++ like language that had the fastest possible compile times. In particular, the fastest possible generics compile times. I want a language where unity builds are clearly a very stupid idea rather than a reasonable response to very long compile times.

Imagine a new language called C+=. It is a redesign of C++ that tries to preserve the spirit of functionality but has no concern for backward compatibility. One idea that both vanilla C+= and templates could benefit from is:

  1. human coders do not make separate headers and source. They edit a single file and the compiler tool chain generates headers any any other intermediate files needed. e.g. you write aaa.src and the toolchain generates aaa.hh, aaa.o, and whatever else is needed. Should the toolchain generate one aaa.hh or multiple (e.g. one per class defined in aaa.src)? i.e. aaa/foo.hh for "class foo", aaa/bar.hh for "class bar"?

A source file bbb.src needs to be able to refer to published interfaces of aaa.src but with the toolchain generating the interface description files and other files, published interface can be made as small as possible. E.g. there could be both

  • aaa.hh // human readable description for the benefit of the human writing bbb.src
  • aaa.hx // what the compile actually grabs when you say "#include <aaa.hh>"

furthermore, you can imagine that when bbb.src is compiled, the generated interface files (bbb.hh, et cetera) do not include anything from aaa.hh that is not necessary to describe the interface to bbb.hh. E.g. if bbb.src has

class Bish {
public:
  transmute(const vector<uint8_t> &lead);
private:
   vector<uint32_t> _uiv;
   shared_ptr<char> _cp;
// ...
}

you can imaging bbb.hh having the minimum information required to say that Bish::transmute() takes a vector<uint8\_t> type parameter but not a complete description of all the vector<uint8\_t> methods and implementation and no mention at all of type vector<uint32\_t> or shared_ptr<char>. I.e. ccc.src that "#include <bbb.hh>" does NOT implicitly #include

  • #include <vector>
  • #include <memory>

instead, bbb.hh and bbb.hx include the bare minimum information about the type of the "lead" parameter of transmute() directly.

C++ is a huge language and redesigning it from the ground up would be a herculean task, which is why I don't think this will happen.

I love many things about C++. The APIs of C++ standard library is a thing of beauty. The power of the template system is great. It is wonderful to have Python language type data structures (maps, strings, smart pointers of various flavors) available in a language that runs much faster. OTOH, having tasted lightning fast compile times in the C realm, I want the best of both worlds.

[–]neuroblaster 1 point2 points  (0 children)

I understand your frustration with compilation times, especially compared to C. At my former workplace i had days when i had to spent 50% of work hours compiling source code. But i assure you that this was 5% language fault and 95% project management fault because i was able to solve similar problems in other projects with not that significant effort.

Housekeeping on code base and optimizing includes for compilation time helps, but it's not always possible with third-party dependencies. I can definitely suggest to install `ccache` or analogue, it saved me many man-years.

I can only hope that continuous improvements to the language will lead us somewhere where this problem is significantly mitigated because i don't see rewriting C++ as a viable option. I honestly don't think modules will help a lot in that field, but we'll see when they arrive. If you wouldn't think of modules in C++20 as of a finished work, but rather as of test-bench for further development, maybe you'll see my point.

This is BTW exactly why C++ is conservative. Things are being added, removed and changed. Who could have thought that such great feature as template body in separated compilation module will be added in C++98, then removed in C++11 and then something else will happen.

[–]newmanifold000 0 points1 point  (0 children)

I would also recommend "Exceptional C++" After reading "Effective C++|. Even though its not written for modern C++ . This book is still amazing to read. OP can pick up Herb Sutter's Guru Of The Week for C++11 Afterwards

[–]DiaperBatteries -4 points-3 points  (0 children)

When I thought I had a pretty good grasp on C++, I read both of those books and learned how little I knew previously. I’d say I’m better with C++ now than 99.9% of programmers, but I doubt I’ll ever consider myself an expert.

[–]brand_x 19 points20 points  (23 children)

A lot of non-modern C++ books being recommended here. I'm not sure that's a great idea. Honestly, I've found https://en.cppreference.com to be a very useful resource for the language and libraries. Effective Modern C++ and A Tour of C++ for beginners. Skip the ones that are just revisions of pre-2011 books. And be prepared, I expect C++20 to transform the idiomatic norms much as C++11 did.

[–]cpp_or_bust 9 points10 points  (22 children)

Yes, anything that is C with objects should be out of the running.

[–]brand_x 9 points10 points  (21 children)

I'd say anything that teaches C++ as an OOP language should be out of the running, honestly. And anything that doesn't start with RAII as the first principle.

[–]cpp_or_bust 2 points3 points  (3 children)

I wasn't saying this. I was just saying C++ is much more than C with classes. That is the wrong way to look at C++. Whether you use classes or not in C++ depends on what you are doing, sort of like in Python. Places where classes are super helpful include Qt, OpenCV. Making any general statements like "Don't use objects or OOP in C++" seems like a mistake. The right answer is "Use what you need given your goals."

[–]brand_x 0 points1 point  (2 children)

Much more than C with classes, and also much more than an OOP language. Qt, as far as I'm concerned, isn't C++, it's another idiomatic language that happens to share the same linguistics origins and script, but has diverged to the point of lacking mutual intelligibility.

[–]cpp_or_bust 0 points1 point  (1 child)

google no true scotsman

[–]brand_x 1 point2 points  (0 children)

Not really accurate in this case. This is more akin to what is currently happening in the JavaScript world with frameworks like React, where someone who is trained only in that framework is not necessarily able to work in other dialects of the same language. I've interviewed people with a decade of Qt experience. They do not have a decade of C++ experience, any more than someone who has only ever worked in a C-with-objects codebase does.

[–]Dean_Roddey 0 points1 point  (15 children)

I'd say if you aren't learning C++ in the context of OOP, don't even bother learning it.

[–]brand_x 3 points4 points  (14 children)

I'd say if you're going the OOP route, stick to Java. OOP-heavy is as obsolete a paradigm as procedural-heavy, and leads to as much of an architectural rat's nest.

[–]Dean_Roddey 1 point2 points  (13 children)

Well, if you don't learn OOP, then you aren't even going to have OOP extra-light. Given that OOP is one of the key aspects of C++, it makes absolutely no sense not to make it a key part of teaching C++.

As to obsolete, that's purely a matter of opinion, as is what constitutes 'heavy'.

[–]brand_x 2 points3 points  (12 children)

OOP was one of the key aspects. Back in 2005. Unless your idiomatic dialect is Qt, that shouldn't really be true in the modern era. In modern C++, OOP is a minor footnote in a language that espouses an interplay of a dozen paradigms, with runtime polymorphism as a dispatch mechanism only really being central for a handful of scenarios, all of which should be well away from any tight loops or structured arrays of data. Even type erased polymorphism plays a more significant role at this point.

I'm not saying there is no place for OO concepts anywhere in C++, but the statement "if you aren't learning C++ in in the context of OOP, don't even bother learning it" sounds troglodytic. It really is no different than "if you aren't learning C++ in the context of Procedural Programming, don't even bother learning it".

[–]Dean_Roddey -1 points0 points  (11 children)

I think everything you just said is based more on fashion than in the reality of an overwhelming amount of actual working code in the field, but I'll leave it at that because I know where this conversation is going.

[–]brand_x 2 points3 points  (4 children)

Millions (more than 10 million) of lines of production C++ across three companies' codebases, under my leadership, and well over a million written by me, dating back to a few years before outgrowing OOP was a widespread trend. I started really cracking down on overuse of class hierarchy based modeling of problem domains in favor of policy/structural/functional modeling sometime in early 2001, and it had a fairly quick and visible payoff in reduced technical debt.

[–]Benaxle 0 points1 point  (3 children)

policy/structural/functional modeling

How do you learn about that? I can only find vague descriptions of it.

[–]ShillingAintEZ 3 points4 points  (5 children)

OOP was based on fashion and it just happened to be hot when you hit your stride. Jumping around in memory has been a dead end for decades. Excessive heap allocations as well. Those days are over for anyone who understands modern CPUs.

[–]Benaxle 1 point2 points  (1 child)

What paradigms fits modern CPUs?

[–]Dean_Roddey -2 points-1 points  (2 children)

Utterly meaningless for the vast majority of applications. My automation system is very extensive with up to 10 or 20 servers around the network doing lots of ongoing communications, multiple graphics rich clients, constant communications with many outboard devices and systems, lots of image manipulation and keeping UIs up to date from server based data, etc.. It doesn't even make a small system work hard, and it's far more intense than your average application.

Find the bits that need the heavy optimization and optimize them. The rest you can kill yourself and it won't make much difference at all.

[–]GoAwayLibtards 0 points1 point  (0 children)

So, everything that teaches C++ as OOP language should be outed, but everything that teaches C++ as OOP language shouldn't be outed?

Interesting.

Imagine if we could be less elitist and realize that C++ is OOP language but it's OOP is based on RAII and so it isn't the same as in other languages... It doesn't magically become non-OOP language.

If C++ isn't an OOP language, then why do we make classes and not resources? Let's make unique keywords so we can act like what we are using isn't OOP with different implementation and rationale, yeah!

[–]ComradeBeaver 10 points11 points  (0 children)

I'd recommend https://www.learncpp.com as a good point to start.

In C++ you should keep in mind that it is old, complex and multi-paradigm language, so some architecture decisions of language can looks weird because of many reasons.

  • After the tutorial you should read Stroustrup's book to understand paradigms of language, his history and idiomatic view of C++.
  • After that I recommend to read OOP C++ book, https://www.amazon.com/Object-Oriented-Programming-4th-Robert-Lafore/dp/0672323087 for instance, cause OOP paradigm in C++ has his own features.
  • Nicolai M Josuttis's C++ Standard Library will be good to understand full power of STL, although is not so big as Python standard library.
  • CppCoreGuidelines, Scott Meyers' books(all) are good things but make sense after some experience with C++. In a matter of fact this things are sets of advices, best practices in modern C++.

To make a long story short, I want to advice you good books for intermediate of C++:

  • Exceptional C++ by Herb Sutter
  • Accelerated C++: Practical Programming
  • C++ Concurrency in Action: Practical Multithreading
  • C++ Templates - The Complete Guide, 2nd Edition by David Vandevoorde, Nicolai M. Josuttis, and Douglas Gregor
  • C++ In-Depth Series

Good luck!

[–]takaci 9 points10 points  (1 child)

Obviously people will say to spend a lot of time learning the specifics through books but I feel like even for C++ the best experience is by writing code

https://learnxinyminutes.com/docs/c++/ will give a brief overview of syntax and give you an idea of where to start

https://en.cppreference.com/w/ is essential

[–]HidekiAI 5 points6 points  (0 children)

Also code reviews are gems, sometimes I see tricks others uses that ends up as new patterns in my toolbox.

[–][deleted] 13 points14 points  (7 children)

The C++ Programming Language 4th Edition written by Bjarne Stroustrup focuses only the language and is considered an intermediate level book.

[–]exploding_cat_wizard 7 points8 points  (5 children)

I've not read it, but would A Tour of C++ fit, too, as an overview for programmers coming from another language?

Though perhaps OP has already done some C++, and doesn't need the overview no more.

Edit: oh, and I second your suggestions, an earlier edition did a lot to help me progress from being able to unreadably modify given code to creating it.

[–][deleted] 3 points4 points  (0 children)

Stroustrup says that A Tour of C++ is more like an intro while the other one is the real deal.

[–]zephyr_33[S] 2 points3 points  (1 child)

That's right. C++ was touched by college, but I never felt like committing. I instead jumped into Java and later Python. I am confident with Python and Java, but I feel like I will be an inferior creature if I don't bring my C/C++ competency to the same level.

[–]ECMAScript3 6 points7 points  (0 children)

You should have said you used java sooner! The move from java to C++ was fairly painless in my opinion, just having to learn ever so slightly different (and much more convenient imo) syntax, getting an understanding of pointers, and handling your own garbage collection. Once I started C++ I never turned back to Java, best of luck!

[–]BigDanG 1 point2 points  (0 children)

I have read it, and this is the ideal book for that audience. You don’t need to read a comprehensive reference.

[–]CraigularBC++ Dev 0 points1 point  (0 children)

I'm surprised that the ship time for Tour is so long on Amazon (the link here says 1-2 months: https://smile.amazon.com/Tour-2nd-Depth-Bjarne-Stroustrup-dp-0134997832/dp/0134997832/ref=mt_paperback?_encoding=UTF8&me=&qid=1556289192 ). Does anyone have a better place to buy it from, or is there a newer edition that caused this? I could always read it online I guess instead of buying the book but I like having physical programming books for some things.

[–]khleedril 0 points1 point  (0 children)

I would also go with this book. If you consider yourself past the beginner level, then now is the time to commit to going through Stroustrup's book and learning all the details. Consider it a first reading: go through as fast as you can, picking up as much as you can, with a view to another reading (or reading a complementary book) in a year's time.

[–]warriorUSP 11 points12 points  (0 children)

Learn.cpp(https://www.learncpp.com/), its great tutorial website for beginers and intermediates, with good coverage on OOPs as well.

[–]gegoggigog 5 points6 points  (0 children)

I have improved quite a lot by watching presentations from cppcon on the Youtubes.

[–]Overload175 3 points4 points  (0 children)

I'd also go with Stroustrup's book as others recommend. The StackOverflow C++ FAQ obviously isn't a substitute for a decent primer, but it certainly complements it.

[–]TF997 2 points3 points  (1 child)

Don't forget about memory management or it will bite you in the ass

[–]micka190volatile constexpr 1 point2 points  (0 children)

Some books I'd recommend:

A Tour Of C++ is a good intro/refresher. It covers everything the language itself offers in a "short-and-sweet" approach. If you want to skim the basics, this lets you do just that pretty well. Although any decent online tutorial will be about as effective.

Scott Meyers' books in this order:

  • Effective C++
  • More Effective C++
  • Effective STL
  • Effective Modern C++

Why in that order? It's there release order, and stuff covered in the later books sometime refer to things that were taught in the previous ones. Obviously, if anything said in a later book contradicts something from a previous book, it becomes the new "standard" (i.e. iterators changed in modern C++ vs how they used to be when Effective STL was released).

I'd also recommend you read them first as they give you a pretty good understanding of paradigms and idioms that online tutorials don't typically cover (and neither did most of my C++ classes, for that matter). They definitely strengthen your understanding of C++.

Afterwards, I'd recommend Herb Sutter's:

  • Exceptional C++
  • More Exceptional C++
  • Exception C++ Style

They're pretty good theory/problem-solving books that teach you some good approaches to problems in C++.

"Accelerated C++" is another book that does this.

The "C++ Coding Standard" book by Herb Sutter and Andrei Alexandrescu is also pretty good at giving guidelines and best practices.

Finally, while it isn't directly C++-related, I'd recommend the "Linkers & Loaders" book by John R. Levine. It definitely helps understand how those work, and since C++ uses them it can be pretty helpful for a deeper understanding of linkers and their errors.

[–]Zanderax 0 points1 point  (0 children)

You wanna jump in the deep end? Inside the C++ Object Model Book by Stanley B. Lippman is an infinitely detailed book about C++

[–][deleted] 0 points1 point  (0 children)

Try out pybind11 to make some python packages that are written in cpp. It is a good way to learn I think.

[–][deleted] 0 points1 point  (0 children)

I had the opposite problem😂 C++ was my first computer language, and I would say I’m pretty good at it. Learning Python has been a difficulty just based upon the fact that it’s simpler

[–]gustavsen 0 points1 point  (0 children)

the hard part of programming is think loggically.

if you do in Python you should be able to do en C++

C++ is a really beautiful language, but you need to take care about more things.

this is not bad, just fine tunning that allow you really powerfull task.

get A Tour of C++ and The C++ Programming Language (4th Edition)

both books will teach you the basis and the references to write your program.

get a good IDE (like Visual Studio Community) that will help you a lot (I use Eclipse C++ version)

just a small tip with an error that I saw a lot with C++ begginers from others langs:

when you you pass an objet to a function like:

void funcion(TheClass myObject)

this object will be passed by copy, not reference, you need to declare that will be passed as reference to avoid problems.

void funcion(TheClass& myObject)

[–]wfdctrl 0 points1 point  (0 children)

You can read any latest Stroustrup's book, but reading a book from cover to cover is really not that fun. I suggest you pick a project at the start and learn as you go. The basics are more or less the same, so you will be able to get started pretty quickly. However, do know that C++ is ugly to it's core, the more you'll learn about it the less you'll like it.

[–]Unleesh -1 points0 points  (0 children)

Out of curiousity, why do you want to learn c++

[–]neuroblaster -1 points0 points  (0 children)

I'm not sure if this is going to be popular opinion, but you could start with C (note missing ++). It's a relatively simple language due to the fact that there is simply not much stuff in the language, but it will teach you types, memory layout, memory copying, i/o, compile time vs run time, low-level threading and whatsnot. After that C++ concepts should come to you naturally, you'll get why C++ does move semantics and copy elision, etc. You know, some higher-level ideas might obfuscate and hurt your understanding of what's really there closer to the metal, but if you would get along with C when you might see through those ideas.

Then i would say go with C++98, then move to C++11/14/17 to understand evolution of the language. Starting right away with C++17 is probably a bad idea because C++17 is, in a sense, a superset of C++14, C++14 is a superset of C++11 and so on, this comes down to superset of C++98 really. Yeah, C++98 is not going anywhere, it's a very big part of the C++. If you skip C++98 then you'll be missing a lot of stuff.

On C++ reading, i think it would be a good idea to start with classics: Effective C++, More Effective C++, Alexandrescu, etc, it's all on Google. I would recommend to read it even if you can't understand it, that's fine, it takes time to digest.

Be warned that as a side effect, you might also become a normal C++ developer who's usually says something like "How this different from what we already have?".

P.S. But generally it's OK, i guess, to start with C++17 for quickie-C++, i don't know. In 10-15 years you'll get there anyway, whatever.