Visual Studio doesn't do magic. It still runs a compiler when you want to compile (msvc). Said compiler can be called independently from command line as well.
If you installed Visual Studio, you already have it, but it isn't added globally to the console. That's to make sure your console isn't cluttered with billion commands. In order to use it, you must open the developer command prompt, which sets up the variables needed to use the compiler. It's in your Visual Studio installation folder, look for "developer command prompt for VS *version*"
Alternatively you can download Microsoft's development tools, which include compilation stuff without the IDE. Look for "Build Tools for Visual Studio 2019" in this page https://visualstudio.microsoft.com/downloads/
:)
There's a ton of support. I would first learn a basic editor like Vim, to edit text/source code, and then learn how to invoke a compiler (e.g. gcc) via command line. Learning to compile via command line more important than learning the CLI IDE environment at your point. I won't add too much more than that, because the compiler in itself is a lot to learn.
Last thing I will say is that you can set up VSCode to edit code over ssh if you want a fallback: https://code.visualstudio.com/docs/remote/ssh
Just remember in your quest to "learn all about C++" that Bjarne Stroustrup gave himself a 7/10 in C++ knowledge, and this was before C++ 2017. https://www.slideshare.net/olvemaudal/deep-c/255
As for real advice, find out which is the latest version you'll be able to use, and get a recent book that discusses how to use the features of that version from the beginning. Too many books put out a new edition with discussion of new features tacked onto the end, even though you should be using some of the features from day one.
> So first of I'm talking about running program from your terminal, so no Visual Studio
You can call the MSVC compiler from the terminal just fine, it's called cl.exe
(well you need to use the dev prompt or call the according stuff in your powershell (easiest way is a custom profile in Windows Terminal)). Just install VS or if you really really really don't want to use that (there's no real reason to not do that if you're on Windows but w/e) then install the build tools (scroll down) which gives you the compiler but no VS.
If for some reason you do not want to use the MS compiler (again not really a reason to do that on Windows) then use the WSL and install GCC there. I wouldn't bother with all those systems trying to install half a linux and a bunch of other tools you're never going to use just to get a compiler working if you can simply get a full Linux with apt update capabilities etc.
C++ is a worthwhile language to learn whether you want to get into game dev or not, and you should learn it.
But while you're doing that, why not get a jump on the game dev part and try out a game engine like Godot. It's free, open-source, and cross platform. You'll primarily be programming with GDScript.
GDScript should be pretty familiar if you have some python experience. That means you could be creating games faster. Godot also supports C++ for when you really need the performance.
Why don't you test it yourself and see if it works?
But in general, yes, you can do that if you get the syntax right. You need double quotes around your strings, and also need to account for null termination (those strings are actually 7 characters long, not 6).
Set up an SSH server in the VM, forward port 22 of the VM to your host in the Virtualbox network settings. Create an SSH configuration file and keys on Windows, so you can login over SSH without entering your password every time.
Then install Visual Studio Code on Windows, and also install the Remote SSH extension. Connect to CentOS. This will install VSCode server on there. Once this is done, also install the C/C++ extension on the "remote".
You now have the VSCode server running in Linux on the VM with your files, build process, debugger, terminal etc. The VSCode client is just the GUI running on Windows.
On windows Visual Studio (NOT VSCode, it merely shares the name and icon) is the most complete package you can get. You need to click the correct two things during installation and another 2 things when setting up a project but thats it. Cant really go wrong.
CodeBlocks supposedly is fairly easy to use/install as well (assuming you install the version that comes with a compiler).
The new versions of DevC++ offered by embarcadero probably also works pretty well. Dont use any other version of DevC++ though, they are all abanonded and out of date.
On mac you would probably go with XCode or Eclipse.
On linux you cant go wrong with CLion (if you can get a license). Eclipse is also availible. I used to use KDevelop, which rather liked (though i have no idea how easy it is to use without CMake)
See also: https://www.learncpp.com/cpp-tutorial/installing-an-integrated-development-environment-ide/
> I'm learning c++ using dev c++ as compiler.
Dev-C++ is an IDE. It's usually set up to use some variety of the MinGW compiler, which is a Windows port of the GCC compiler. Hopefully you're using the Embarcadero release of the compiler, because the Orwell and Bloodshed releases are rather old.
What you're seeing is the expected behavior. Windows opens a command prompt, runs the program, and closes the prompt when the program execution ends. For a simple program like you're probably writing early on, I'd either start cmd
and run the program from there (so the window doesn't disappear), or add something like std::cin.get();
before the end of your main
, so that you have to press enter to make the program exit.
NodeJS has an API for c++. C++ Modules
After you make one, you can import it in NodeJS by using import
NodeJS also has an FFI, where you can build a shared library (not limited to c++) and import it. Node-ffi-addon
Performance wise, the NodeJS API is what I recommend you use. However, there is a little to learn. If you don't mind the performance drop, I recommend you use the FFI. You don't have to learn the NodeJS API, so it's a little easier
I think you solved your problem but didn't learn anything.
You should have switched out
using namespace std;
for this:
using std::cout; using std::endl;
gnu multiprecision library is one option. The boost multiprecision library is another.
Clang modernize does a few things.
But keep in mind that they tried very, very hard to make C++11 backwards compatible. With only a few obscure exceptions everything should just compile. There's few good reasons to go back and rewrite (presumably working) code just to make it more C++11-style.
std::for_each
is an algorithm written in a time where range-based for loops did not exist. You should be using those instead, especially if the range you are iterating through is the entire container:
for (auto& item : items) item.action(); items.clear();
Removal of elements in the midst of iteration will not be very nice regardless of what method you use. It is better to do the iteration, then the removal, instead of attempting to do both at the same time. However, if the range of interest is a subrange of the container, it may interest you to partition the elements you are interested in before doing the iteration. In this manner, the elements you wish to consume will be all packed together at the end of the vector.
I learned C++ after I had known C and I kinda regret that. The way of thinking and designing solutions shouldn't be related, the commonalities are just basic syntax stuff, other than that I highly advice that you just start your C++ learning path.
On the other hand, some helpful materials are:
Sorry my comment might not be perfect, but we're all learning. Cheers and Good Luck.
> Dev c++
Hopefully the up to date version: https://www.embarcadero.com/free-tools/dev-cpp ?
> Zebra *z[10];
This declares an array of pointers to zebras This array is on the stack. This array must not be deleted.
What you have to delete are its elements:
for ( auto ptr : z ) { delete ptr; }
The exact same applies to the c
array.
> new
You really dont need to use this.
use a std::vector<Zebra> z
and then do
z.emplace_back( name, age, ns )
No new
, no delete
, no problems.
> low-level language like C++
If you want to become proficient in C++, the first thing you need to do is discard this idea.
>A tour of C++
I would start here. It's a super cheap book and covers everything you need to know to get up to speed in C++ quickly. Be sure to pay careful attention to the chapters on the STL containers, algorithms, and iterators. Knowing how to use these three elements of the language gives you the ability to quickly and simply solve and enormous array of problems.
>Programming: Principles and Practices Using C++
Be sure to get the latest edition with C++11 coverage. Reading this book front-to-back is of little use to learning the language, but it is the reference text for C++. Bjarne put lots of little practice programs throughout, so you can practice syntax and concepts using those.
>Jumping into C++
Don't even bother with this book. There is a reason it's not on the Definitive List.
>C++ Primer, Accelerated C++
You already know how to program, so these are going to be too basic for you.
>Thinking in C++ (+V2)
I'm not a fan of these texts given that they are intended as introductions to the language, but are quite dated. YMMV.
>VoidRealm's QT videos, C++ GUI programming with QT 4.
I don't do GUI programming, so I will leave others who are more knowledgeable to comment.. Note that Qt5 is the latest and has many interface changes over Qt4.
Books aside, I strongly encourage you to learn the STL containers, algorithms, and iterators as soon and as thoroughly as you can. As I noted above, just using these built-in features of the language allows you to be a good C++ programmer. Extending the functionality of these language components to build more sophisticated programs is how you will spend the rest of your life as a C++ programmer.
Since your actual problem appears to be solved, please look into the following points:
void main()
is wrong. Some stupid people may teach it, but the ISO-standard is quite clear in that regard. main()
always returns int
.scanf
and printf
. Don't use them. While most people will agree that they aren't great either, always prefer the C++-streams (int your case std::cin
and std::cout
)system("pause")
is usually regarded as a terrible idea. Please read this and this.using namespace std
might work with small programs, but usually it is a very good idea to not use it and instead just get over it and write the std::
-prefixes out.<stdio.h>
and <stdlib.h>
: Those headers really shouldn't be used at all. If you really need them (which should rarely ever be the case for stdio), use the C++-versions: <cstdio>
and <cstdlib>
So, for a better version consider the following:
#include <iostream>
int main() { double val1; double val2; char operation; double result;
if (std::cin >> val1 >> operation >> val2) { switch(operation) { case '+': result = val1 + val2; break; // ... case '/': if (val2 == 0) { std::cerr << "Error: division by zero!\n"; return 2; } result = val1 / val2; break; default: std::cerr << "Error: unknown operation!\n"; return 3; // sneak-edit } std::cout << val1 << " " << operation << " " << val2 << " = " << result << "\n"; } else { std::cerr << "Error: Failed to read input!\n"; return 1; }
}
One big use case is portability across different compilers. Consider this example from Boost's <code>config.hpp</code>
// BOOST_FORCEINLINE ---------------------------------------------// // Macro to use in place of 'inline' to force a function to be inline #if !defined(BOOST_FORCEINLINE) # if defined(MSC_VER) # define BOOST_FORCEINLINE __forceinline # elif defined(GNUC) && __GNUC_ > 3 // Clang also defines GNUC (as 4) # define BOOST_FORCEINLINE inline attribute ((always_inline)) # else # define BOOST_FORCEINLINE inline # endif #endif
Standard inline
is just a hint to the compiler that you think a function should be inlined, however the compiler is free to ignore you. On the other-hand a number of compilers include non-standard extensions to allow you the force the compiler to inline a function. If you want to write code which works with multiple compilers then you need to use a trick like BOOST_FORCEINLINE
.
A second usage is so library users can enable or disable certain behaviours through a compile time #defines
. Consider this example from GLEW
/* * GLEW_STATIC needs to be set when using the static version. * GLEW_BUILD is set when building the DLL version. */ #ifdef GLEW_STATIC # define GLEWAPI extern #else # ifdef GLEW_BUILD # define GLEWAPI extern __declspec(dllexport) # else # define GLEWAPI extern __declspec(dllimport) # endif #endif
If you are building the library as a dynamic library then some functions will need the non-standard dllexport/import
attributes. However if you are building a static library then these can be ignored. The user can specify which behaviour they want by #define
ing GLEW_STATIC
.
If you're on Windows, consider using Visual Studio Community Edition instead of Visual Studio Code. Visual Studio is a full IDE (with compilers and other tools). Visual Studio code is an editor.
I presume you are running MinGW?
MinGW has a bug where random_device isn't non-deterministic, see: https://stackoverflow.com/questions/18880654/why-do-i-get-same-sequence-for-everyrun-with-stdrandom-device-with-mingw-gcc4
A project Im having an eye on is nanapro
Its a very simple GUI framework for C++ and quite the opposite of Qt. But I havent found the time yet and I never did contribute to something, so I dont know how to start :/
First, the speed of bit operations is quite likely simply not be an issue at all in your program. You should always write the clearest, most obviously correct code using algorithms whose overall O()
running time is good - and then profile your application to see which areas are consuming most of the CPU time so you know where to optimize.
I'm not sure why your bosses are using <code>boost::dynamic_bitset</code> instead of <code>std::bitset</code> - it's very rare indeed you need to change the size of a bitset, which is the only advantage that the Boost version offers.
std::bitset
should be faster than boost::dynamic_bitset
in many cases as it one less level of indirection and doesn't have to carry the size of the bitset around at runtime.
Overall, if I were you, I'd not worry about this issue unless you are seeing performance issues, you have profiled them, and the bit operations are in the top ten consumers of CPU cycles. I'll bet you any amount this will never happen...
Well, it sounds like you have an interest in making games. As you said, making text-based games is a great way to master the basics of control flow, I/O, variables, functions, classes etc, so keep doing that for a while.
When you feel ready, the jump up to proper 2D games doesn't have to be huge. Check out SFML, it's one framework which is easily installed, but can handle all components of a 2D game like graphics, audio etc. It's also modern and clean object-oriented code. e.g. this is an arkanoid clone in only 160 lines of code.
Obligatory talk about why you should never use rand().
Watch this first. After you have done that: Reconsider parts of your algorithm:
You want to select a random, but unoccupied field. So just create a vector of the free fields and erase the used ones from it:
// create and seed a mersenne-twister std::mt19937_64 gen{std::random_device{}()};
std::vector<std::size_t> free_fields(9); // create vector of nine elements std::iota(free_fields.begin(), free_fields.end(), 0); // fill it with 0,1,…,8
for(unsigned i = 0; i < 9; ++i) { std::uniform_int_distribution<std::size_t> dist{0, free_fields.size() - 1}; auto field_it = free_fields.begin() + dist(gen); auto field = *field_it; free_fields.erase(field_it);
use(field); }
Visual Studio Code for Mac supports C++ via Clang. The IDE is svelte, and doesn’t bring my poor 2012 MBP to its knees like XCode does.
It’s free and the download is small, so you lose nothing by giving it a whirl: https://code.visualstudio.com/docs/cpp/config-clang-mac
> Blender was made using python and in fact I have already wrote some some plug-ins for blender.
I do not think Blender is only written in Python. If they wrote their rendering engine in Python, it would be incredibly slow - there just has to be C/C++ code in there, somewhere.
In fact, from their <u>Get Involved</u> page, they explicitly state:
> Blender is an open source project licensed under the GNU GPL. All code is written in C, C++ and Python.
> Firefox sounds interesting though. What kind of things can you do in it?
Depends what you want to do, and how advanced your skills are. I suggest that you read this page.
you can use NtQuerySystemInformation
to acquire the cycle time of each process
if you are comfortable reading c code, check out process hacker's source code
https://processhacker.sourceforge.io/doc/procprv_8c_source.html
After a super quick google search,
in general just look up "programming challenges". just because a prompt is for python or some other language doesn't mean you can't program it in c++
See here in the advanced-section.
Personally I've only read “Modern C++ Design”, which is good, but has to be taken with quite a bit of salt today, since we are two language-standards ahead and some of the techniques are basically workarounds for language-features that didn't exist back then but do today.
Yes, you can use boost::thread - this has the added advantage of being cross-platform too (e.g. works on Windows with native Windows threads).
If you can avoid this construct, it would be better to do so. If you must do it like this, it's best to use an existing library, like Boost.Any.
Not really an equivalent but strictly superior:
#include <iostream> #include <string> #include <random>
int main() { std::mt19937_64 gen{std::random_device{}()}; std::uniform_int_distribution<short> dist{'a', 'z'};
unsigned length; std::cin >> length;
std::string str(length, '\0'); for(auto& c: str) { c = dist(gen); }
std::cout << str; }
You should also watch this talk: <code>rand()</code> considered harmfull
Edit: fixed missing semicolon and invalid ctor
Edit 2: fixed use of char in uniform_int_distribution. See my reply to Malazin.
What do you want to know about arrays?
int myArray[10];
creates an array called myArray
with 10 spaces for integers.
myArray[0] = 4224;
sets the first element of said array, aka the first location in memory where the array has been allocated, to 4224.
myArray[9] = 424;
Sets the last element of the array to 424.
for(int i = 0; i < sizeof(myArray) / sizeof(myArray[0]); i++) { std::cout << myArray[i] << "\n"; }
Prints the elements of said array.
sizeof(myArray) / sizeof(myArray[0])
sizeof(something)
basically returns the size in bytes of "something".
sizeof(myArray) / sizeof(myArray[0])
is just saying "Divide the size of the whole array by the size of one element of the array"
Naturally, this returns how many elements are in the array.
Learn more here: http://www.tutorialspoint.com/cprogramming/c_arrays.htm
I know it says C but arrays are pretty much the same in C and C++ :P
Another resource: http://www.cprogramming.com/tutorial/lesson8.html
I see.
Couple of things I would critique about your approach:
> generates all possible combinations
Every design that includes a sentence like this almost always is slow (due to the exponential growth of "all possible combinations"), I'd strictly advise to only generate combinations that you actually need.
> generates functions based on it
How are these functions generated? Do you write actual c++ code to a file, compile it, link it in on the fly? If I had to guess you probably use std::bind
to fix certain parameters or something similar. In that case just storing those bound parameters in a sequence would be enough to quickly recreate those functions.
Lastly: 99.8312% (real statistic, btw) of all games use some kind of scripting language to resolve ingame logic. Specifically for things like weapon mods that usually require a lot of adaption/balancing hard coding them in C++ is often cumbersome. Have a look at lua. It's a lightweight, fast language that is fairly easy to embed in C++ programs.
Now I know of it; I will see how it fairs in my workflow. I will compare it to how I would use cppreference itself.
Just to note; it seems that devdocs.io/cpp is just using the cppreference archive data; with a different stylesheet.
Even the links are the same:
https://en.cppreference.com/w/cpp/container/vector/vector
https://devdocs.io/cpp/container/vector/vector
just switch out en.cppreference.com/w
with devdocs.io
I must say, the interface is fairly nice.
But the information is identical; thus use the interface you prefer.
You can do this in CPP, but it is highly inadvisable, wrong tool for such a simple job. If you are on Windows look into AutoHotkey, but even that is a fairly fancy solution. Lots of simple to use Macro recording software exists.
A common pattern is to prefix the warning flag with a "no-" to disable it. The output indicates that -Winconsistent-missing-override
is the flag that for your warning, so you would have to add -Wno-inconsistent-missing-override
to your compiler flags.
This SO post seems to illustrate how to add compiler flags.
Also, you seem to have -Werror
passed, which turns all warnings into errors.
Maybe just follow this official guide by Microsoft that can be found in < 1 sec by typing in sensible keywords into google: https://code.visualstudio.com/docs/cpp/config-msvc. This is exactly for configuring Visual Code to use MSVC as compiler. Everything is right there in the documentation - you just need the patience and focus to actually read it!
If you are looking to write your first program in C++ codeblocks is one of the better tools to use when first learning. But if you really want to use VS Code, follow this guild to get g++ to work in VS Code (you will need to download mingw, or other compiler, ahead of time).
Get Started with C++ and Mingw-w64 in Visual Studio Code
​
Make sure to open the folder / directory the .cpp file is in into VS Code, you can do that by right clicking the explorer window if you have it set up in the default way on Windows. If you're on mac make sure you have XCode downloaded from the app store.
You can't have template implementations in the .cpp file like that, you'll need to them in the header. Relevant StackOverflow.
MinGW just brings some GNU tools (such as GCC, which is the compiler) to Windows.
It's GCC, and it's standard library implementation(s) that allow for the "compatibility" benefits you are referring.
Most (good) IDEs will allow you to just change the toolchain you are using. If they don't, frankly they aren't worth using IMO.
VS Code (https://code.visualstudio.com/docs/cpp/config-mingw)
VS (https://devblogs.microsoft.com/cppblog/using-mingw-and-cygwin-with-visual-cpp-and-open-folder/)
so I do not know why you think you need to "drop" the IDE you prefer.
Welcome to floating point numbers! No, this is not a bug, it is the result of how floating point numbers are designed.
Check out https://stackoverflow.com/questions/21895756/why-are-floating-point-numbers-inaccurate
Using doubles increases your precision, but will also succumb to the issue.
Unfortunately, C++ does not allow you to (un?)pack a tuple-like type in-situ into a parameter pack, which (AFAIK) is what you would need to do in order to make this work. There have been some proposals to allow for this, which would be awesome if any of them actually went anywhere; nobody can seem to agree on the precise rules or the syntax that should be used for it.
There is, however, std::apply
, which has been voted into C++17; that will allow you to say std::apply(myfn, mytuple);
, where mytuple
contains the arguments to myfn
-- that isn't as nice as Python's myfn(*mytuple)
, but it'll do. Until C++17 drops, you could use std::experimental::apply
, you could roll your own helper function (see this StackOverflow question for details on how to implement it), or, if you have control over the function signature, you could always just replace the parameter list with a std::tuple<int,int,std::string&>
or other POD type, which would allow you to pass in a tuple directly (and you would still be able to pass in arguments the old-fashioned way, you'd just have to call std::make_tuple
(in C++17, or with libc++ right now, you will be able to just wrap your arguments in {braces}).
The sad story is that there aren't even good online-tutorials in English, so you basically have no chance finding something in Spanish or German. I would recommend getting a translated version of one of the recommended books.
I asked Bjarne this question personally years ago; his answer was: don't make memory leaks.
I found this answer kind of putting your hand in the sand at the time. However now in retrospect I completely agree with it.
Not making memory leaks requires lifetime consideration of objects and data structures. For many data an std::vector is an excellent default container for values.
Also I find the 'everything belongs somewhere' mantra extremely helpful.
When introducing a new object, value or structure, consider who owns it, or who it should at least outlife and how that will be accomplished.
For single objects and native resources an std::unique_ptr<> is very handy. They can have custom destructors to, for example, close a filehandle or release a GDI handle, close a network socket, name it. Anything OS native can be wrapped in raii objects to manage it like that.
This will for the most part eliminate creating leaks in the first place. Some for that thanks to the raii wrappers, smartpointer or containers , but mostly due to the thought that you put into putting things in the right place.
However, in an existing application where years of thought did not go into this and people that did think of it already left, this can be problematic.
In such cases tools can help, such as doctor memory which is free https://drmemory.org/ or Check out https://www.deleaker.com/ which is very user friendly and integrates well with visual studio.
Another option that I use to track memory leaks is to create a counter object, this is a class that contains a static counter that logs the instance number and goes up everytime the class instantiated, and every thing that it leaves scope, logs the instance number and decreases the counter.
If you add such a class as a member of the objects you want to tracks, you can at least see exactly when they are created and destroyed and in what order.
Gr,
Jan
Sure you can. When you built boost, it should have produced a version of each library for debug mode, with a name containing -g or -dg in the tag. You might need to enable that with runtime-debugging=on
.
Boost.Config defines a set of macros for all kinds of features, which you might find useful rather than basing things on compiler version.
For example:
#if BOOST_NO_CXX11_CONSTEXPR // old way #else // constexpr way #endif
If you are using Visual Studio 2015, it already includes an implementation of the filesystem library in std::experimental::filesystem
. It's probably a bit easier to use than raw WinAPI.
If you want the code to be portable or are worried about the "experimental" nature of the library, you can use boost::filesystem.
http://en.cppreference.com/w/cpp/numeric/random/discrete_distribution
edit: in case you can't use c++11: see the second example (Generating integers with different probabilities): http://www.boost.org/doc/libs/1_59_0/doc/html/boost_random/tutorial.html
also, if you want to know how to do this from scratch, I can answer questions.
Rather then source code itself, look up the info in documentations when available.
In this case, look here: https://liballeg.org/a5docs/trunk/display.html#al_create_display, where it is described pretty nicely, the 2 parameters are width and height of the window you create.
Before you decide on a directory layout, you'll want to decide on your build system. I strongly recommend cmake. It's very popular, so you'll be able to find lots of examples of how to use it, and it's cross-platform, so you don't need to worry about platform incompatibility.
If you decide to use cmake, you'll be able to Google examples of how different people layout their directories. There are lots of different choices out there, so you'll just have to pick one that feels good to you.
Edit: Additionally, some people might say it's okay to start out with just manually writing a Makefile instead of using a build system. Personally, I don't recommend this, because I find that manually writing Makefiles offers nothing but needless suffering. Different people are going to have different opinions about the matter. My opinion is that a good build system will always save you an immeasurable amount of time and frustration over using raw Makefiles.
If you’re comfortable with the command line then you could use Vagrant. If you have Homebrew installed on your Mac then getting a Ubuntu 16.04 VM up and running with Vagrant is as easy as...
$ brew cask install vagrant $ vagrant init ubuntu/xenial64 $ vagrant up $ vagrant ssh
All being well, you should now be at the shell of a Ubuntu 16.04 host. From here you can then apt-get install gcc-c++
and whatever else you need. The folder you ran the above commands from on your Mac is mapped to /vagrant
in the guest
Maybe take a look at this:
https://www.amazon.com/C-20-Details-Rainer-Grimm/dp/B09328NKXK
I haven't had a chance to read it myself but I've been following a series of articles about C++20 written by Rainer Grimm and I found them to be an outstanding source of information. Also a decent guy as well, had a few questions about the articles and he kept responding each and every single time elaborating on details.
The one from 2002? The book's material will be based on the C++98 standard, or perhaps a draft of C++03. The language had a huge shift in culture based around the C++11 standard, and I wouldn't recommend learning the language for the first time from material older than that.
C++20 is bleeding edge, and I don't think it's even completely implemented in the compilers yet. I think I'd find material for C++17 and work from there, for the time being.
You're asking a very good question which can be distilled down to "What are the best design practices that will give me loosely coupled moduler code?"
This is not an easy question to answer and it highly depends on the system requirements as to how code should be broken up.
When starting a bigger project like you are talking about, if you really care about designing this way, don't try to solve this problem at the compiler/IDE.
You need to start doing UML class and sequence diagrams for your system. Try to design at a high level first. Create UML classes and interfaces to them. It is not important at first how exactly these classes will work. What is important is that you have a good idea of everything the system is supposed to do and how each of those classes will help cross off those "things" When you start to see one class solving lots of problems, it might make sense to look at it and break it up into smaller classes.
The next thing you do is connect these classes together. Show the dependancies between them. Does your drawing show your database class needing to use an Employee? Draw that dependancy line. Does the Employee class use the Database class? Draw that dependancy line. Do you have circular dependencies at the end of this task? It might be time to create an interface class for your Database and/or your Employee class. Do this, make the changes to the bigger drawing and continue.
The cool thing about this approach is that you can do it all on a whiteboard, or use a UML tool, or even just do it in a notebook. The better job you do of organizing at this point, the better your chances for having good modular code will be once you get into the trenches developing code.
If you're looking for a book to get you thinking about these topics, I recommend "The Pragmatic Programmer"
/u/aegagros already gave the correct answer, but I want to explain you why that is.
When you are using external code, that code has most likely been precompiled as a library. There are some exceptions, such as Header-only Libraries.
However, when you use a "normal" library, the compiled code is compiled into a collection of Symbols. So when the compiler runs over the header of your used library, it assumes you have the symbols. Then the linker runs and can't find them, because you didn't tell the linker to use that file. That is why you are getting this error message. Because the compiler validated the definitions of the foreign code, but the linker cannot find "the book" to copy it from into your program (or make a link to it, if you are using a shared library).
https://stackoverflow.com/questions/69112/what-is-a-symbol-table
Certainly. I borrowed this from a StackOverflow reply to the same question.
Namespaces separate and organize functionality. You can have a xander333::sort() function and it won't conflict with std::sort() or boost::sort() or any other sort(). Without namespaces there can be only one sort().
Now let's say you've put "using namespace std;" in all your source files and you've implemented a simple templated function called fill() in the global namespace of one of your files. This file also depends on a header from libFoo -- foo.hpp. Version 2.1 of libFoo comes out and all of a sudden your program no longer compiles. You version of fill() suddenly conflicts with another fill()! What happened?
It turns out that the folks implementing libFoo included in the new version of foo.hpp when they didn't before. Now you have all of the standard algorithms being included in your source file, and your using namespace std; has pulled them all into the global namespace. std::fill() now directly conflicts with your fill().
More insidious, you've gotten your code to compile by renaming your fill() to xander333_fill(), but something's not working right -- your report numbers are off. It turns out that your custom divides() function, which does fixed precision math, is no longer being called because the templated function from (also newly included by foo.hpp) makes for a better match because you're calling types did not exactly match the declared types.
First, you need to redirect the compiler away from main, as you've already caught on. Note that main
is actually called from a method called _start
inside crt1.o, which prepares the command line arguments for main
. With GCC you can do this:
g++ test.o -Wl,-emystart -o runme
This removes the call to _start
, so you don't get command line arguments:
char mystart() {}
And done, no i's.
Credit: this StackOverflow post
if a vector runs out of size it will allocate more than just 1 more space so in actual code the resize-allocation overhead is pretty small https://repl.it/repls/PitifulUnhappySpecialist
and even so, the cache on your PC is so goddamn fast, you will hardly get any performance with a structure that need to jump twice to reach its destination, crossing every cache on your PC. Im writing on a Stackmachine+Parser as hobby project with heavy insert/delete operations and used to use a deque until someone here pointed out I should test with vector and well... vector for the win
That's not too hard if you've done some programming before. It'd be a lot easier in a higher-level language, though.
You need to find some online source for the prices. Your program can't just get the prices out of thin air. I found an API offered by Yahoo. You can get the price of MSFT like this:
http://finance.yahoo.com/d/quotes.csv?s=MSFT&f=l
More info on this API:
http://www.gummy-stuff.org/Yahoo-data.htm
So you need to put the ticker symbol into the URL, fetch the data at that URL, and pick out the price from the returned string. The C++ standard library doesn't have built-in networking, so that'll be the hard part. You'll need to use a library like libcurl or boost::asio.
There are lots of good resources comparing casting functions in C++ that a quick google search will give. I'd recommend the cplusplus.com Type Conversions tutorial.
In oversimplified terms, when casting a pointer, you want to use reinterpret_cast. When casting a primitive type, use static_cast. In general, try to avoid dynamic_cast, as it requires RTTI.
Lots of C++ is "header only" and that's a perfectly viable technique. If you're going to do that, you might want to go for a unity build where there's only one .cpp that's compiled.
What I think you're objecting to is not that - I think it's having separate declarations and definitions is what bothers you.
I think that would bother you even if the definition were in a separate _inl.h, or even if it were in the same .h, but further down.
Unfortunately, you won't be able to get away entirely without it. "Circular references" are fairly often necessary and you can only break those with a declaration "near the top" and a definition "near the bottom".
But, you know, you could avoid most of them, and just put in a few when the compiler forced you to.
I wouldn't do it myself - even though I'm using a Unity build in the current project - but you could definitely write an elegant, performative C++ program using only header files, and if you want to go that route because you write clearer, simpler code that way, then it's definitely your decision, and it's a viable one.
May i introduce to Windows Subsystem for Linux? Targeting WSL with visual studio.
It lets you "natively" run linux applications directly on Windows, no need for virtual machines or anything like that. Linux software can normally interact with Windows file system. You simply open bash on Windows, and you can apt-get gcc's linux version, then run linux's gcc with some cpp files you made with windows software, that you can normally access because linux software is running in kind of the same environment.
Man this feature is so underrated, feels like people don't even know it exists. You can use any linux development and debugging tool directly under Windows in your system (linux gui application aren't officially supported, although you can find workarounds to enable that as well; but all the console ones i used work as intended)
I'm going to recommend the up and coming Meson build system. In general, it's been replacing autotools/autoconf in quite a few projects.
The other thing to look at is git submodules. In languages like Javascript, we use npm
, and in PHP we use composer
. Those both pull in the entire library to the project folder. C++ does not have an equivalent.* The main suggested method is to use a Package manager. However, if the library is not one commonly used, Git provides a solution in via submodules.
* This is, arguably, a good thing since you don't want to include then compile the same library fifty million times, and anything other than static compilation will rely on the system's libraries anyways.
Factorio. It's proof that an indie game can do something large-scale and still run fast and well, that you don't need multi-million budgets for performance, only the right tools and approach.
> If it makes a difference, I'm running Windows 10
The way the Windows console is implemented means that printing to it requires inter-procedural calls, and the way iostreams are implemented means that every single byte is sent separately. You can test the overhead of the console by seeing how fast you can print to it versus how fast you can print when the output is redirected to a file.
Some things you can do to get better performance are to use different different print functions, or to use a different console, such as msys2's. (The msys2 console can be gotten easily by installing Git for Windows.)
Msys 2 (http://www.msys2.org/) is a port of many Linux tools directly to Windows. It ports Arch Linux's package manager, and, in its repositores it contains many libraries and many development tools (ie. make, cmake, g++, probably clang). It also supports compiling exes that can be run on Windows without Msys. It is based on cygwin and mingw, but is a separate project from each of these and ensures that all of your C++ tools are as well integrated as they are in an actual Linux environment.
Although, really, the best way to develop C++ is to just do it on Linux and only worry about Windows come distribution time. This is practical if you use only libraries that work on both systems (ie. SFML, OpenGl, Vulkan, GTK, Qt, Boost). Conan can also help with this, although, IMO, Linux and its amazing library system to develop with and msys 2 to port to Window is superior to conan, mainly due to the vastly larger number of libraries available.
No! C++ is here and it's here to stay. The reason it's not high level is because... Well... It's low level, which gives us more control over where the data goes! The first language I learned was C++, and for some reason I didn't find it hard to learn (although, I am rubbish at it), I don't think it's going to die because I don't think it has any reason to die.
The only real "replacement" (alternative) language is Rust but I'm just rambling by now, so I'll leave you to it...
I'd recommend GLFW which is a much smaller library than SFML and SDL because it only does 2 things - give you a rendering context, and let you access input from mouse/keyboard/controller. SFML and SDL are full 'media' libraries and give you windowing and input, but also audio, multithreading, timing, file I/O, networking (SFML) and more. GLFW is just the bare bones that you need.
Visual Assist X is really fantastic for C++ dev. It adds really great refactoring tools as well as better intellisense. It does cost money, but the individual license isn't too expensive. If you can afford it, it's worth every penny imo.
Oh look there's documentation. And the third argument, an allocator, is defaulted. You don't need, or should not need, to supply that.
For your concrete problem please provide a complete but minimal example, and quote the error message verbatim.
volatile
is easy: it was not designed for threading, and will bite you in a very inconvenient place if you use it. So don't. Re learning, check out the C++ book list referred to in the box on the right of this page, then use your browser's find functionality (Ctrl+F in FireFox), search for “thread”, and voilà! :)
Oh, additional resource: the standard library's thread support was mostly adopted from Boost threads, where you'll find a tutorial and examples. But I recommend using cppreference.com for technical documentation. I'm not sure how the standard library differs from the original Boost threads.
Presently all major standard library implementations of regex
are half-baked, broken crap. Some very simple regexes may work; or not.
Boost.Regex is thoroughly complete and thoroughly tested; it's the sane choice for now.
A couple things:
targetFile
as a parameter to your clearFile
function. This allows the caller of the function to control where the filename comes from, instead of only from std::cin
.std::remove
is not a filesystem function- it does not delete files. std::remove
is an algorithm that reorders the elements in an array into a keep part followed by a remove part. For example, if you had an array [1 4 7 9 2 3]
, and your removal predicate was "remove all even numbers", std::remove
would partition the array into [1 7 9 3 4 2]
. It is kind of a poorly named function, but it is useful for deleting a subset of a vector since it is very easy to delete the tail elements of a vector.If you are looking for ways to delete a file in C++, check out boost.filesystem, or the unlink
function in unistd.h
.
(Edit: I didn't know about the std::remove(const char *)
overload. Personally, I think its an even worse named function than the one above, but it is much simpler than using boost or unistd. You are using it correctly, just make sure you check its return value for error conditions!)
Writing your own busy-wait loop is a bad idea. If you are using C++11 (and you should be), then you can simply write
#include <chrono> #include <thread>
void wait(int seconds) { std::this_thread::sleep_for(std::chrono::seconds(seconds)); }
If you must use C++98, then you will need to use something like Boost.ThreadManagement or a platform-specific function like Linux's usleep.
Your code is a bit dubious anyway, never minding the reference to a local. For example what if the data stored at a node is -1, how can the caller tell then that they have a valid node.
I see three more appropriate solutions to handling the error case:
Throw an exception (this would be my preference).
Do like <code>std::map</code> does and insert a new node if there wasn't an existing one.
Return an optional type like <code>boost::optional</code>.
Whatever you eventually choose to do, you can't keep what you have now.
Have a look at Boost.program_options.
There is also cpp-argparse. Their README gives some other options.
As for standard in CPP, I can't really speak to that. I am new-ish as well.
GCC has a C++ specific extension that they borrow from C99 that allows for the declaration of arrays whose lengths are specified at runtime. Standard C++ did not borrow this feature from C99, although it is expected to add it at some point in the future, possibly in 2017. Therefore as things stand, in general C++ does not allow such arrays to be declared as you have done.
Basically in clang or any other C++ compiler, you can not use this technique.
To use a multidimensional runtime length array in C++, the simplest option is to this:
static const int var1 = 100;
int main() { for (int i = 1; i < 5 ; i++) { const int var2 = i * 100; std::vector<std::vector<double>> my(var1, std::vector<double>(var2)); my[5][12] = 3.1415; my[2][8] = 2.7182; } return 0; }
Or if you have boost, you can use boost::multiarray:
http://www.boost.org/doc/libs/1_55_0/libs/multi_array/doc/user.html
printf
is a C function and doesn't understand anything about the type of it's arguments until runtime when it parses the format string. And even at that the passed in types might not match the format string.
Since C++ templates can't really manipulate strings, without resorting to some extremely hacky tricks, it doesn't really meld with printf
That said there are plenty of C++ alternatives, one example is Boost.Format.
Allegro is a 2D game engine. I'd suggest taking a look, get familiar so you can build your own engine.
In school we made 2D games using grids in Swing, but I'm sure you can find a toolkit library in C++ with support for a grid layout (or canvas), and mouse/keyboard event handling.
If you want to build a 3D engine, I'd suggest OpenGL game programming by Kevin Hawkins. The book is a bit outdated but it should serve you as a primer into building a 3D game engine.
Another resource for 3D game programming using OpenGL is http://www.videotutorialsrock.com/
Note that you can create 2D games using OpenGL but OpenGL is not a game engine.
As /u/Ilyps says, you'll need a better resource than that to learn C++ properly. The problem with good real life examples is that they tend to be too big and messy; what you usually want is a reduced version that shows some key concepts, but leaves out the mess of special cases that crop up in a particular case of a problem. You can find some such examples in various Going Native talks; you can also try hanging around /r/dailyprogrammer and see if you can pick up ideas there.
I realise what you're doing with the seed might look like it'll give better randomness results, but it really, really won't.
If you want true randomness, pass rd
to std::shuffle
. It will not be particularly fast, but it'll make sure you get something random.
Alternatively, take one of the recommended random engines (the whole video is worth watching), seed it once, and then keep using it. A mersenne twister has significantly more state than just its seed; by constantly reseeding it you are reducing the number of possibilities you'll get, rather than increasing it.
Try Address Sanitizer (available in Clang and GCC) and Valgrind. These are not exactly what are you asking for, but these are extremely useful tools to detect memory errors.
I really hope that you aren't using the original Dev-C++, that thing is almost 10 years old and is completely obsolete. As an alternative use Code::Blocks or at least use the Dev-c++ fork
If you are using the original one then you are SOL (no current library will work on it). Else you can take a look to SDL or Cairo to draw stuff.
I use Geany and it's incredibly fast and simple. It's also open source. Maybe it's not as advanced and well suited for giant projects I'm not sure. There is a new project being worked on that's making good promises and seems like it will include everything you can possibly want: Builder. It's also open source.
> but it doesn't help
You are not doing it correctly then. Try rebuilding all, and test your executable with the dependency walker. There should be no mfc140.dll in there, if there is you are doing something wrong.
If you haven't tried hackerrank it might be worth a go. It gamifies solving challenges and enjoying overcoming difficult problems and being able to persist when you're stuck is core to programming. Also absolutely make sure you're taking 5-10 minute breaks every 45-60 minutes whatever your learning strategy ends up being.
Pidetemp(double(&temp)[10])
This is very wrong. See here http://www.tutorialspoint.com/cplusplus/cpp_passing_arrays_to_functions.htm
Look at your prom temp function and work through the algorithm as you have written it... You will find a logic error.
Promtemp proto and definition have different signatures.
And why is it nobody ever seems to use art names in function protos anymore?
Vagrant is a really easy way to automate setting up a VM. You might find it convenient:
https://www.vagrantup.com/intro/getting-started/index.html
If you use an Ubuntu image, installing g++ is pretty much just sudo apt install g++
I would more so recommend using Visual Studio Community 2013.
But if you want to use Dev-C++ you should get the Orwell version
I'm guessing you mean Visual Studio Code. Which is not an IDE it is a text editor. If you are on windows I recommend downloading and installing Visual Studio Community 2019 which is an actual IDE. You can find it here: https://visualstudio.microsoft.com/downloads/
Using Visual Studio Community 2019 you can create projects and add files and run the code with the push of a run button similar to the arduino IDE.
​
(make sure when installing visual studio you select that you want to install the "Desktop development with C++" package)
To add to this, you could download the vim plugin c-support (used to be called c-vim) and do the compilation within vim. They have hotkeys and etc that should make your life easier :)
If you're set on using an IDE, then visual studio 2015 community is probably your best bet (assuming you're on windows).
Personally, I think beginners are better off using the command line for their first basic programs. The focus should be on the code at first. A massive IDE like VS could be intimidating and confusing, with the multitude of features and settings that you won't need for months.
If I were just starting I'd get a free basic programmer's text editor like notepad++, install the GCC compiler, and compile from the command line. LMK if you need help.
Also, I suggest not getting stuck on tutorials and move forward to reading a good book on Qt, for better understanding of concepts like MVC. "Mastering Qt" is a good one https://www.amazon.com/Mastering-Qt-stunning-cross-platform-applications-ebook/dp/B07DH9YK9Q
Documentation is good for solving particular problem, like finding specific class or method. I can't imagine why just to "read documentation" for the purpose of studying, it's completely impractical.
Well a book like "C++ Primer" goes through the most common STL features: IO, data structures, algorithms, shared pointers, random numbers, regular expressions and exceptions.
You could also get Scott Meyers book "Effective STL" and while not related to STL I'd definitely recommend you to read his books "Effective C++" and "Effective Modern C++" for learning about best practices and a lot of very valuable lessons on how to use C++ in the best way.
But honestly, when you know the basics it's all about doing something and having a need for something, e.g. a map, and then searching for "c++ map" and read up when necessary.
The code
void f(App a){ a.init(); }
should use the name of your class (not the concept name),
void f(Myapp a){ a.init(); }
Note that using an init
method instead of a constructor, is generally an ungood idea.
As long as you don't use very low level features of the language C++ gives you an all-or-nothing guarantee for allocation+initialization, a kind of atomic object creation guarantee. When you use an init
method instead of a constructor you forsake that. It's then easy to end up with an unusable zombie object: allocated, but not successfully initialized, or perhaps not even any attempted initialization, ripe for Undefined Behavior.
Bjarne Stroustrup gave a partial discussion of the ungoodness of init
methods in appendix E to “The C++ Programming Language” 3rd ed., called “Standard-Library Exception Safety”.
Missing from that discussion: other main reasons why init
method are used, in particular being able to override things in a derived class, and type safe solutions to that dynamic binding during initialization problem e.g. as discussed in the FAQ.