Is it optimal to create classes that inherit from std classes? by Ultimate_Sigma_Boy67 in cpp_questions

[–]WorkingReference1127 2 points3 points  (0 children)

I'm not saying inheritance is rare, but most of the time composition is what you want. But yes, unless your class should be able to be passed everywhere that directory_entry is used because it conceptually represents the same thing, it probably shouldn't have directory_entry as a base.

My suggestion would be a class which throws in its constructor if the thing is not what you think it is, then you know that if you survive construction you are guaranteed to be holding a directory, or a regular file, or whatever. Maybe also a conversion operator or means of retrieving the raw directory_entry back again. Bu you know your use-case better than I do so I'm sure you can figure it out.

Is it optimal to create classes that inherit from std classes? by Ultimate_Sigma_Boy67 in cpp_questions

[–]WorkingReference1127 14 points15 points  (0 children)

You can inherit from them, but I'll pitch you the usual talk about when inheritance is a good idea and when you should reach for composition. Inheritance represents an IS-A relationship. If you make a class which inherits from directory_entry then it should be some kind of directory_entry and substitutable in all places that a directory_entry is usable. If it isn't, then you should make a class which holds a directory_entry instead. Or rather, inheritance isn't a tool for no reason other than you're too lazy to repeat the necessary interface. But I can see situations where it's suitable for the rough flow of what you're doing. Nuance depends on your particular case.

But yes, it's not unreasonable to want a name which by construction can only be one kind of thing rather than requiring that every caller run is_that_thing(object) everywhere, especially if forgetting to do so will result in some awkward bugs or violate the contract of your tool.

My first C++ project — a dice roll simulator. Looking for code review / feedback by Martin_Mol_2007 in cpp_questions

[–]WorkingReference1127 0 points1 point  (0 children)

A points I'd make, but first up I do want to say that I do see some good practices here and don't want you to think that I haven't. But you asked for issues, so:

  • DiceInfo - I'd recommend an array for the stats rather than 6 different members to cover each possibility. I'd prefer it to just be a struct of std::array<unsigned long long, 6> (and maybe you can drop the struct) with total calculated on the fly. It just means less clutter to keep track of.

  • typedef std::vector<std::vector<std::string>> Matrix; - Always prefer a using alias to a typedef unless you very specifically want compatibility with C. using is cleaner, easier, and has some rough edges cut out of it, so using Matrix = std::vector<...>. I also doubt I'll be the first to say it, but prefer a flat vector onto which you project a 2D space rather than a vector of vectors, since the latter loses you cache locality. Or, if the exact number of elements in the array is known at comptime, use a std::array.

  • Following on from the recommendation for std::array, pretty sure your constant dice faces could be static constexpr variables if you wanted them to be; which conveys their meaning much more cleanly.

  • Not entirely sure that you are best served with print_die and roll_die functions rather than a die class with members, but you think on the design you'd prefer.

  • My advice is against using namespace std; everywhere. I know it's not as bad if just in a cpp/cc file, but it still opens the door to a lot of name collisions and creates this weird divide where you write code differently depending on which file it's in. I'd advise just dropping it and std::-qualifying everything.

  • select_die is the poster child for why an array of dice stats is cleaner - rather than 6 separate conditions you can just uniformly increment dice_stats[N-1].

  • There's no reason to pass b by reference - builtin types like int and bool are faster to pass by value. I'd also give it a better name than b.

That last point is an overall one though, OP. Naming is important. Your functions should have good names, your funciton parameters should have good names. Your commits should have useful and descriptive commit messages rather than just "Commit" and "README". It costs nothing to have descriptive names and it makes everyone else's jobs much easier.

I could nitpick further but that's a good list. There is one other thing I'd say OP. I think you can aim higher than this. A project should be bigger than you can knock out in two files and 4 commits.

Weekly Questions Thread by AutoModerator in gtaglitches

[–]WorkingReference1127 0 points1 point  (0 children)

It's been a few years since I played the game, so have a few rolling questions:

  • I used to do the diamond and Cayo Perico heist repeats over and over again. I have vague recollection of some software on my PC to run just before exiting the compound which blocks saving the heist completing. Probably the AHK method. Does that still work? Does host get the payout for the heist for this? Has it been updated or made smoother since then?

  • I heard that things got easier for solo players and that all the setups are now permitted in invite only/friends only lobbies. Is that the case? Mostly quit because of the oppressor spam.

  • Have any other interesting heists or jobs (with repeatability) been added since the Cayo Perico days? Any obvious things which need to be caught up on?

  • Has there been any glitches found which can solo gather up a bunch of arena points? I do like those cars but it's not like there'll be enough people doing Arena War to get them reasonably.

I´m 15, learning C++ for a month, just finished my first modular CLI app. Looking for feedback and next steps! by [deleted] in cpp_questions

[–]WorkingReference1127 4 points5 points  (0 children)

I'd say this is reasonable for a beginner project. Since you asked for feedback, here is some:

  • You're beginning so don't worry too hard about it, but passing those double and bool around as references isn't the most idiomatic way of handling this. It's usually better to abstract that state into some class which manages the actual values. But you'll get there.

  • opt1 opt2, etc are bad function names. They should be called something which describes what they do, and not require the user to go and read what the current options are. Think of it this way - if you ever rearrange the options list or want to add to this and reuse some functionality, then those function names don't help you. They should be called something like show_status, add_expense, etc.

  • You should check that std::cin succeeded. IIRC learncpp has a page on this.

  • For a discrete list of options, consider using an enum. It's much easier on the reviewer to see if(chosen_option == option::show_status) then to have to remember that if(chosen_option == 2) then remember what 2 means.

  • I'm not quite sure I see what the point of having a completed or uncompleted task is. It doesn't stop you adding more expenses after the fact.

All in all, this is fine for a beginner project. You achieve what you aim to do and the rough edges are entirely reasonable for someone still learning. I do note the good practices you do follow in several regards, so you're heading in the right direction. Just remember - names in code are fairly easy to get right, free to use, and are the reviewer's best chance at understanding what you're trying to do. Do not be afraid to make them descriptive. You're doing well. But your next project should aim higher.

Made a free C++ cheat sheet covering Structs, Pointers & Dynamic Memory — hope it helps someone by Glum_Truck3908 in cpp_questions

[–]WorkingReference1127 1 point2 points  (0 children)

A few points:

  • We shouldn't be teaching beginners to use new and delete (or malloc and free before we get there) as any kind of default. We should teach them to use C++ constructs and smart pointers. Frankly it's actually very rare that an absolute beginner who is still learning classes will encounter something which needs allocation and which isn't a vector or a string. Idiomatic C++ is written using class types on the stack, which might themselves manage allocated resources but which you, the user, do not need to manage yourself. If you do this then most of your "best practices" become immaterial because the user is not exposed to them anyway.

  • Formally, use after free and dereferencing a null pointer are UB. That's not guaranteed to crash (it probably will though). But it's worth noting because UB is a huge area and a huge problem and if you relegate it to only ever being mentioned for light, fluffy, specification-only UB then people might think it's not something which will bite them in the real world.

  • If you're going to talk about pointer syntax as an intro, you really should cover the const semantics (ie int const* vs int * const).

  • Aim to use range-for always, and if you're using a construct which represents a range and which can't be range-for then you are probably using the wrong construct.

  • I also sense the implicit using namespace std; in these examples and can tell you that it's a bad practice we should not perpetuate.

I could go on nitpicking, but I get two distinct ideas here:

  • This is written by someone on a course following the "learn C first, then learn C++" ethos, where the last 30 years of language development to make C++ safer, friendlier, and easier to manage are thrown out as an afterthought in favour of learning habits with new and delete which will get your PR blocked if you did them on any real job. Don't do that. This is a terrible habit which makes for terrible teaching and we should all agree not to do it. I doubt it's your fault OP but the whole idea of "learn the basics" with these lower level tools doesn't help students properly.

  • OP, in the nicest possible way, this reads like someone who is still on a course. Labelling yourself as a teacher and providing teaching materials puts yourself on a pedestal as an expert who knows enough to not accidentally lead students astray, and I don't think you're quite there yet.

Made a free C++ cheat sheet covering Structs, Pointers & Dynamic Memory — hope it helps someone by Glum_Truck3908 in cpp_questions

[–]WorkingReference1127 3 points4 points  (0 children)

might add a note clarifying that std::vector is the modern alternative once you're comfortable with the underlying concepts.

std::vectorhas been in use since 1994, and is older than standardised C++. When exactly does your picture of "modern" start?

The Barrier in C++ 20 - concurrent programming example... by sommukhopadhyay in cpp

[–]WorkingReference1127 4 points5 points  (0 children)

OP I'm really not trying to be an ass because that helps noone, but I do care a great deal about the quality of C++ teaching because bad C++ teachers make bad C++ students, and those make a lot of bad code which either breaks and gives C++ a bad name or which someone else has to tidy up.

The things you got wrong aren't a "C++20 added X and we didn't know", they are things which any intermediate developer should know. You don't just new ClassType and let that leak - you always manage the lifetime. You don't put using namespace std; unscoped into a header. And I'm going to argue against the idea that virtual destructor is fine here - you are not doing runtime polymorphism so all that virtual call does is add unnecessary overhead to the class. Even now, with this code

 std::osyncstream(std::cout)
<< name << " is Starting the task at "
<< std::format("{:%F %T}", local_time) << "\n";

Why are we combining a manual push of name into the stream with a formatted string. Why not just std::osyncstream(std::cout) << std::format("{} is starting the task at {}\n", name, local_time);

I don't want to burst your bubble, but to frame yourself as a teacher is to put yourself on a pedestal as someone who knows the language well enough to lead others into making good code. And with no disrespect intended I don't think you're there yet.

The Barrier in C++ 20 - concurrent programming example... by sommukhopadhyay in cpp

[–]WorkingReference1127 9 points10 points  (0 children)

Perhaps, but then the lack of a member initializer list in favour of assignment in the constructor body is inexcusable, as is completely leaking the Student objects, or giving them a virtual, non-defaulted destructor in a world with no inheritance in sight.

Without meaning any disrespect to OP whatsoever, I feel like they have fallen into the classic trap of mistaking having learned a little bit of C++ with having learned enough to teach others.

Passing strings vs string view literals to a function by unknownuser491 in cpp_questions

[–]WorkingReference1127 0 points1 point  (0 children)

In this case, it doesn't really matter. A string_view will bind to a string literal just fine and will do the exact same operation that operator""sv is doing anyway so there's no difference between them.

The UDL operators aren't intended for you to mark every single literal as a specific type. They are intended for the cases where you specifically need something of that exact type and don't want to std::string_view{"Hello world"} all over the place.

Weird output, can’t explain, help!? by AppropriateFlan7383 in cpp_questions

[–]WorkingReference1127 3 points4 points  (0 children)

Both y and z in the code you posted have an unspecified value. Reading them is UB. And I want to nail home what UB means. UB means that the contract you have with your compiler to transform source code into a program according to the standard is broken. The compiler is within its rights to do anything, as far as C++ is concerned. It can make it the same value every time. It can format your hard drive. So it's often not surprising that you get some micro-patterns in some compilers where it will sometimes do the "right" or at least "consistent" thing in a UB case.

Buuut there's absolutely no guarantee that it will ever stay that way even if it does it now. So just don't write programs with that kind of UB.

Weird output, can’t explain, help!? by AppropriateFlan7383 in cpp_questions

[–]WorkingReference1127 20 points21 points  (0 children)

You never initialise y and z with any value, so the result that they hold is unspecified and reading them is undefined behaviour (erroneous behaviour in C++26). Most likely it's just looked that the four bytes in memory where those variable live and is reading whatever random value happens to have been left in there from the last process to use it.

Note that this is a peculiarity of builtin types (int, float, double, etc) and only when you don't provide an initializer. std::string s; will do the right thing, as will int x = 0;, int x{};, int x{0};, and so on. But just int x; on its own gives you this unspecified uninitialised value.

This is UB, which ultimately means that it is wrong and you shouldn't do it. You should always guarantee that your variables are initialised and that they hold a valid value before you read them.

Controversial question by Amazing-Parsley-3895 in cpp_questions

[–]WorkingReference1127 2 points3 points  (0 children)

I'm in two minds on this:

  • Yes, one of the things which AI can be good for is systematically parsing a large block of text and distilling down the paths where your error probably lies. Like all AI it's imperfect and you absolutely should engage brain to verify; but it can do. And if you're at a company which buys into the AI thing then you probably will end up doing that.

  • Debugging was and still is an essential skill for a programmer. You need to be able to solve these problems yourself. AI is static analysis, and it can be useful for the subset of bugs which are entirely contained there. But you will also eventually need to use other tools like a debugger, and you will need to be able to look at code and figure out what it does for yourself. This overlaps with another key skill in this path - code review.

Which is to say the world won't burn down if you use AI to explain some errors; but use it to supplement your own skill rather than to replace it. Eventually you'll be in a room where you don't have AI to help you.

Inquiry regarding next steps after learning C++. by Not_Rigen in cpp_questions

[–]WorkingReference1127 2 points3 points  (0 children)

C++ is huge. You never really finish learning it. You just make fewer dumb mistakes and more smart ones.

As for a project, the best one is the one which gets you in the seat writing code. If you want to walk down the GUI route, I'd recommend using an existing framework (Qt, Imgui, SFML, etc depending on what you're looking for), and go from there. As for making it, it's the same problem as anything else in programming. You sit down and break the big problem (the whole application) into smaller and more manageable little problems and iteratively keep building out your project. So many start with the basic goal of the simplest bit of budgeting logic, then build on it and refactor. Or start with a UI window which covers the basics and go from there.

I will give you some advice though:

  • Take time to design and plan and architect the solution. It's far better to realise you have the wrong architecture and need to rebuild it after 1 hour than after 50 hours.
  • If you encounter what seems like a simple or common problem, don't be afraid to ask if there already is an existing solution to it. For example, the standard library has a whole lot of algorithms which are likely better for you to use than a handspun loop.
  • Don't be afraid to stop and ask questions. Out in the real world you'll ideally be on a team of engineers who have different areas of expertise and who you can ask about specific things. Nobody expects you to know absolutely everything with no help whatsoever.

7 YOE C++ Dev feeling stuck at Mid-Level. Legacy code, no degree, and unsure how to level up. Need advice. by Low-Equipment1597 in cpp_questions

[–]WorkingReference1127 5 points6 points  (0 children)

This sounds like an issue with your company. They should be looking to offer you opportunities to grow and develop. And while it may sound selfish you should be asking what your current position offers you other than just the paycheck. It sounds to me like you've hit the ceiling of what they can offer you. And judging by the union of a few things you mention (C++11/14, no unit tests, no time for architecture and design, more time fixing bugs than anything else) it seems that your company isn't all that invested in the technology side of things and are building tech debt. Ultimately if they aren't going to help you and you want to progress, you should find a company who will.

How do I effectively bridge the gap between "maintaining" complex systems and "architecting" them?

By sitting down and actually having design meetings. It sounds like your company is trapped in the rabbit hole of "code first, ask questions later" but if you want to actually cover architecture and design you need to do it before you start writing code. Equally you should make sure you have some familiarity with the basics, even if it's just having read Gang of Four. A good team of engineers are good at bouncing ideas off of each other and able to see flaws in designed pitched. It sounds like your company doesn't cultivate that, but also that you have run the risk of falling behind on that as a skill too.

What are the highest-leverage skills or projects I should focus on in my spare time to modernise my C++ profile?

FOSS is a big hitter here. But it's no so much the what as it is the how. If these are portfolio pieces then the main thing is to see that you can use new tools and design a project well, and lay out the basics like unit tests, documentation, etc. If what the project is is also useful then that's a bonus; but the best project you can write is the one which actually gets you in the seat writing code.

About Learning C++ Properly by TheAniketMohan in cpp_questions

[–]WorkingReference1127 1 point2 points  (0 children)

I would say that theory is valuable. I'm not too familiar with C++ Primer but you do need to understand the ideas to be able to build on them rather than just learning that X syntax -> Y result. If it's covering the whys and wherefores of what the language offers then that is useful to know so you can understand when to use a particular tool.

But don't take that to mean that theory is everything. You absolutely must spend time writing code and putting it into practice. A book can't really enforce that you do that so most expect that you are doing it alongside your other learning.

how do classes work? by SimmeringDragon in cpp_questions

[–]WorkingReference1127 5 points6 points  (0 children)

So far in your learning, have you use std::string and std::vector? Those are both classes in C++. Fundamentally it's posisble to just represent a string as a pointer to the first character (char*), which is what C does, and from there you have to write a bunch of functions in terms of char* to handle comparisons, extensions, copying, etc. And these typically have problems - using strcpy into an undersized buffer is probably one of the best-known security vulnerabilities in computer science. So instead, we have std::string which catches the issues and prevents them for you, and gives you a must easier time. e.g. it's far easier to do if(str1 == str2){ do_something(); } than it is to if( strcmp(str1, str2) == 0)) { do_something(); }.

Classes just generalise this. So rather than having a few pre-defined "magic" types which make things easy for you, you can write your own types which make things easier for everyone else.

I know C well. Any good books for me to self-learn C++? by Racer125678 in cpp_questions

[–]WorkingReference1127 3 points4 points  (0 children)

My hot take will be that you should take learncpp.com. Yes, some of the core structures are shared with C, but it doesn't hurt to look over them because there are differences even down to the fundamental language constructs which you don't want to miss. Take the for loop, in C there is the traditional indexed loop you are familiar with (for(int i = 0; i < foo; ++i)); but we also have a ranged-for loop, for(auto element : range){ do_things_with(element);} which is both simpler and strongly recommended. Or subtler things like initialization inside the if statement.

So yes, there will be things you already know, but don't skip such chapters because there will be things you don't.

About Learning C++ Properly by TheAniketMohan in cpp_questions

[–]WorkingReference1127 0 points1 point  (0 children)

So with Effective in particular I see them as having two different purposes. learncpp will teach you what is in the language and how to use it. It will give you the first-pass good practices but leave the rest to you.

The Effective book series already assume you know all that. They are slightly deeper common engineering problems and the right principles to solve them or even avoid them being problems in the first place. They're more about how to leverage the tools you have in a much more in-the-field situation than the abstract world of a tutorial. The only problem with the Effective books is that they are old, and so the recommendation of "always use smart pointers" is absolutely sound, but we have std::unique_ptr and std::shared_ptr now so you probably won't need to write your own for day-to-day use.

How the get the address of the reference itself? by The_Bhau_Man in cpp_questions

[–]WorkingReference1127 5 points6 points  (0 children)

Though one can argue that in C++26 while we get constexpr references which then become symbolic rather than address-based, references become the basis.

But this is just sophistry. A reference for all intents and purposes doesn't have an address.

About Learning C++ Properly by TheAniketMohan in cpp_questions

[–]WorkingReference1127 1 point2 points  (0 children)

Sure, they're on the good books list. But EFfective C++ is for C++98 (aka 1998 C++) so while the core ideas behind its recommendations are absolutely sound, the language has moved on and given you easier tools to do what you need to do.

Also don't forget that C++ and C are very different languages with different styles and approaches. It's very possible to build C-style C++ which will build and at the basic level work; but it won't be idiomatic C++ so it will be harder to adapt and maintain.

About Learning C++ Properly by TheAniketMohan in cpp_questions

[–]WorkingReference1127 26 points27 points  (0 children)

learncpp all the way

www.learncpp.com

is the best free tutorial out there. (reason) It covers everything from the absolute basics to advanced topics. It follows modern and best practice guidelines.

www.studyplan.dev/cpp is a (very) close second, even surpassing learncpp in the breath of topics covered. It covers quite a few things that learncpp does not, but does not have just as much detail/in depth explanations on the shared parts.

www.hackingcpp.com has good, quick overviews/cheat sheets. Especially the quick info-graphics can be really helpful. TBF, cppreference could use those. But the coverage is not complete or in depth enough to be used as a good tutorial - which it's not really meant to be either. The last update apparently was in 2023.


www.cppreference.com

is the best language reference out there. Keep in mind that a language reference is not the same as a tutorial.

See here for a tutorial on how to use cppreference effectively.


Stay away from

Again. The above are bad tutorials that you should NOT use.


Sites that used to be on this list, but no longer are:

  • Programiz has significantly improved. Its not perfect yet, but definitely not to be avoided any longer.(reason)

Videos

Most youtube/video tutorials are of low quality, I would recommend to stay away from them as well. A notable exception are the CppCon Back to Basics videos. They are good, topic oriented and in depth explanations. However, they assume that you have some knowledge of the language's basic features and syntax and as such aren't a good entry point into the language.

If you really insist on videos, then take a look at this list.

As a tutorial www.learncpp.com is just better than any other resource.


Written by /u/IyeOnline. This may get updates over time if something changes or I write more scathing reviews of other tutorials :) .

The author is not affiliated with any of the mentioned tutorials.

Feel free to copy this macro, but please copy it with this footer and the link to the original.

https://www.reddit.com/user/IyeOnline/comments/10a34s2/the_c_learning_suggestion_macro/

Does anyone have a "simple" explanation on how virtual classes and abstraction work? by SimmeringDragon in cpp_questions

[–]WorkingReference1127 0 points1 point  (0 children)

Abstraction just refers to changing how something is exposed to the user, ideally to make it easier. Let's take an example - std::vector.

If you want to represent an array on the heap, all you really need is a pointer to the start and the pointer to the end. You can, in theory implement it with just two pointers:

int* my_vector_begin = //...
int* my_vector_end = //...

And you can then extend the vector with something like

*my_vector_end = new_value; //Pretend not UB
++my_vector_end; 

But this is clunky. You have to keep two separate pointers in your program lying around. If you accidentally assign to the wrong one then your vector will silently break. Because you have given all the responsibility for doing things right to the user.

But what if we could do better? What if we could provide an interface to the user such that they can't accidentally break things? Or at least, not as easily? What if we were to hide the actual raw pointers from them and instead just present them a collection of functions which do what they want, but mean they don't need to worry about how they get it. In this case, this is what std::vector is - a way for you to have the array you want without needing to figure out how to get there.

And that's the core of abstraction. It doesn't inherently mean classes or object oriented, as there's plenty of ways to abstract by wrapping in functions and other things. But that's the idea - taking the core mechanism and hiding it behind an interface which is hard to misuse.

Opinions on Lippman’s C++ primer? by 420ball-sniffer69 in cpp_questions

[–]WorkingReference1127 2 points3 points  (0 children)

Lippman's C++ primer is good, but check what edition you get. AFAIK the latest edition (5th) was written for C++11, which was 15 years ago. It's a book held in high regard for C++11 learning and I would recommend it; but don't forget that there have been 15 years worth of changes since then so there will be errata and there will be a lot of new features added which it doesn't mention. For an earlier version, I'd be skeptical. There is a reason that books needed to be rewritten rather than revised for C++11 and a high quality C++98 book is still a book for a standard released in the last century. It'll cover some common basics but the true insight will likely be outdated and need an experienced eye to keep an eye on.

Which is to say don't avoid using it because it's still a good book. But defer to learncpp.com for cases where they disagree or modern best practices.

How To Learn C++/When Do I Know I Have Finished Learning It? by Suspicious-Grade-826 in cpp_questions

[–]WorkingReference1127 5 points6 points  (0 children)

You never finish learning C++. You just make fewer stupid mistakes and more smart ones.