@mr_darker,
I suppose you already recognize you've asked so many questions on several levels, some general topics, like the comparison of C and C++, to the notion of design. Answers could produce a book.
C was purpose built as an assembler independent of CPU architecture, initially for the purpose of writing the UNIX operating system to be portable, and almost immediately thereafter for writing applications for that operating system that inherit that portability. Many C statements and constructs translate to individual machine language instructions. C's ability to address application level targets makes it usable above the assembler level.
C++ was created based on knowledge gained from a number of experimental languages, largely SmallTalk (which eventually exceeded it's experimental status). There is leverage for object oriented development in C++ which doesn't exist in C.
However, fundamentally the notions of object oriented design and programming are related to the way humans think. There is a strong association with any particular thing or theoretical construct and the processes and attributes of that object. You don't drive a bicycle the way you drive a car. Even our use of the English language differs, where you likely noticed people ride bicycles, not drive them. Even that word choice, to drive a bicycle, may strike one as odd, because it isn't usually associated that way. Certainly the techniques for operating a bicycle differ from operating a car, and thus our base of knowledge of each have different specific techniques and attributes.
You've no doubt heard, "If you have a hammer, all your problems look like nails". Consider if the problem is a screw. Can the hammer be of use? Not to satisfactory effect. However, who hasn't turned a screwdriver the wrong way around to drive a small nail in a pinch?
A compiler should generate a warning or error attempting to use a hammer to drive a screw. The type and the objective don't match. This is fundamental to how we think. It should be no surprise a programming language would acquire techniques to avail our organization of thought and code in kind.
I submit, for example, that in C, the int and the double exhibit the behavior of objects, if you're willing to relax the definitions. The CPU is rather literal, and writing in assembler one must be careful to select deliberately the integer instructions for the standard operations upon integers, and to select the floating point operations upon doubles and floats. In assembler, for the most part, this is a burden upon the programmer, for the difference between integers and floats may be only the format of the bits. To C, however, these are types. One usually thinks the compiler "knows" what they are, and selects automatically those instructions appropriate to those types without our manual intervention. Even when mixing these types in operations, where the burden for doing so in assembler may be perplexingly bug prone, the C compiler has rules for the relationships between these types. I submit this behavior, of the selection of process based on type, is at the heart of what objects are, and have been exhibited by the C compiler all this time where ints and floats are used.
In C, the family of file functions fopen/fclose/fread/fwrite all required a FILE * structure to operate. There isn't much use of the last 3 without a valid FILE *, obtained by fopen. The compiler is particularly verbose if these calls don't get a FILE *, but are fed some other type instead. I submit this is loosely the organization of an object, but one without leverage in the language to implement it as an object.
The selection of a process based on type, or that of the relationships established between types, or the association of processes and the information they act upon is central to object oriented design. Object oriented programming is merely the extension of this thought process through language features which give leverage to this natural, human means of thinking.
In math, for example, I may have a point. In C I can describe this point as a structure comprised of two floats or doubles, X and Y. I may create a family of functions which can operate upon them, performing addition or subtraction in the fashion of vector math, or multiplying them by scalers (floats) to shrink or expand them. In C, these are named functions I select from a list appropriate to vector or point manipulation.
In C++ those functions would be a member of that structure, and some of those functions representing standard operations like addition and subtraction can respond to the use of operators, to simply writing and clarify what they do.
For example, in C such vector2d's might be used:
Code:
vector2d a;
vector2d b;
vector2d r;
vect_init( &a, 1, 2 );
vect_init( &b, 2, 3 );
vect_init( &r, 0, 0 );
vect_add( a, b, &r );
vect_scale( &a, 0.5 );
While in C++:
Code:
vector2d a{ 1, 2 };
vector2d b{ 2, 3 };
vector2d r;
r = a + b;
a *= 0.5;
These are effectively identical. The types created in C++ for vector2d would "know" how to perform addition with another vector, and know how to efficiently assign that result to a vector2d, as well as scale the vector's X and Y by a scalar factor.
When you then expand these notions to 3D vectors, matrices and quaternions, most of the important operations of linear algebra used to write 3D graphics (like games) become nearly as trivial as expressions like a = v * q, where v is a 3D vector, q is a quaternion (a rotation in 3D space), and "a" becomes the result vector of the rotated point.
This "knowledge" of operations, associated with the types of information that knowledge operates upon, allows C++ to extend leverage to the more manual counterparts in C like memory management, GUI application development, sorting, searching...virtually everything we write.
Such is the nature of the comparison of C and C++. Before the era of C's creation, the CPU's and computers of the 50's and 60's were so primitive that the main language notion of that era was assembler, and thus C by 1970.
Now that computers are more complex and more powerful, language has evolved to accommodate the human mental effort required to create applications of significant ambition.
I'll close with one specific question you asked. The subject is inter-process communication. You have several choices. Each task can open a TCP/IP connection and communicate as if over the Internet, even locally within one computer. Alternatively, they can communicate through files.
However, the highest performance is achieved through memory mapping and operating system signals, where processes can share blocks of RAM, and coordinate access to that RAM. In C++ there are libraries in BOOST that make this nearly trivial, portable from Linux/UNIX to Windows.