Understanding C++ compilers from a Java / C# perspective

后端 未结 4 1956
有刺的猬
有刺的猬 2021-02-06 14:29

I\'m a moderately experienced Java / C# programmer, and I\'ve recently started learning C++. The problem is, I\'m having trouble understanding how to structure the various heade

4条回答
  •  温柔的废话
    2021-02-06 14:39

    The C++ FAQ is an excellent resource about all the idiosyncrasies of C++, but it's probably a little more advanced than you're looking for -- most of the questions (not just the answers) are mysteries even to fairly experienced C++ developers.

    I think if you google for C++ tutorials, you'll be able to find something. You may also want to try learning assembly language (or at least getting a quick introduction as to how things actually happen in a microprocessor), as both C and C++ are quite close to the hardware in the way they do things. This is where their speed and power comes from, but it comes at the price of some of the nicer abstractions Java offers.

    I can try to answer your specific questions asked above, but I don't know how well I'll do.

    One of the keys to understanding the relationship between header files and cpp files is understanding the idea of a "translation unit". A Java class file can be considered a translation unit as it is the basic unit that is compiled into a binary form. In C++, pretty much every cpp file is a translation unit (there are exceptions if you're doing weird stuff).

    A header file may be included in multiple translation units (and must be included everywhere that uses whatever is defined in the header). The #include directive literally just does a text substitution -- the contents of the included file are inserted verbatim where the #include directive is. You normally want your class interface to be defined in the header file, and the implementation in the cpp file. This is because you don't want to be exposing your implementation details to other translation units that may include the header. In C++, everything, including classes, aren't really rich objects, but just chunks of memory that the compiler assigns meaning to... by compiling the same header information into each translation unit, the compiler guarantees that all the translation units have the same understanding of what a chunk of memory represents. Because of the lack of rich data after compile time, things like reflection are impossible.

    The second step in the C++ build process is linking, which is where the linker takes all the compiled translation units and looks for symbols (usually function calls, but also variables) used in a translation unit but not defined there. It then looks for another translation unit that defines that symbol and "links" them together, so that all calls to a particular function are directed to the translation unit that defines it.

    In the case of class methods, they must be called through a class instance, which is behind the scenes just a pointer to a piece of memory. When the compiler sees these types of method calls, it outputs code that calls a function, implicitly passing the pointer, known as the this pointer, to the function as the first argument. You can have functions that do not belong to classes (not methods, as you said, because a method is properly a member function of a class and thus cannot exist without a class) because the linker has no concept of a class. It will see a translation unit that defines a function and another that calls a function and tie them together.

    That ended up being a lot longer than I expected, and of course is an oversimplification, but it is accurate to the best of my knowledge and the level of detail provided... hope it helps some. At least it should give you a starting point for some googling.

提交回复
热议问题