I apologise for what I'm pretty sure is a fairly stupid question, but I can't get it to work!
I'm also not sure what information is too much information so I probably won't give enough info so sorry for that too - just ask.
I began writing a class within main.cpp, and it got large so I decided to shift it to a different source file. I'm not too sure on how to do this, and can't figure anything to help fix this specific problem from internet resources (hence the asking).
I started off with the class definition including all of the function definitions above the main program function. This runs fine. I then split this up into two separate pieces. The class declaration (I think that's the correct term) above the main function and the function definitions below the main function.
This also runs perfectly well. I proceeded to cut the class declaration out into a header file. This header file is of the form
#ifndef INC_MATRIX_H
#define INC_MATRIX_H
class matrix{
//ETC
};
#endif
Which I have read somewhere is useful but I'm not entirely sure why, I think it's to stop redeclaration of the functions if the header is included more than once.
So currently we have this header file included along with the other includes. Then the main function and then the function definitions beneath the main function. This also compiles and runs perfectly well.
The next step I took was to cut the function definitions into their own separate .cpp file. The only addition that was made to this .cpp file was that some extra includes had to be added to the top (specifically iostream and cstdlib). ALSO the matrix.h file was included.
In this configuration Dev-C++ brings up linker errors when I try to compile and run the code. Specifically they are of the form
[Linker Error] undefined reference to matrix <bool>::matrix(int, int)
And the code doesn't run (obviously).
how can I fix this? Thanks in advance.
Edit: It's been discovered that this is due to the fact that it's a templated class and in the scope of the matrix.cpp file the template isn't introduced to the bool type. I now want to figure out how to fix this without adding lots of lines of code to individually make each function accept each given type.
Oh, and I appreciate that I can define the functions in the header. But I thought that we weren't meant to do that? I thought the idea was that you simply include the declaration.
The error suggests that your matrix class is a templated class. Is it? Perhaps posting the code would help.
If it is a templated class then see this FAQ for a description of the general problem with separating templated classes into header/implementation, and solutions to this problem.
I think you probably didn't add matrix.cpp to your project. It has to build that to matrix.o and link it to main.o to create your .exe.
Related
Background:
I'm working on a legacy project in C++. While extending the functionality of a base class(specifically I'm adding multi-threading support), I had to modify a header file. Let's call the base class header fooBuilder.h . fooBuilder.h defines a builder object that is used heavily later in the code. To implement multi-threading, I included a bunch of windows specific headers.
Problem:
In the other source files that include fooBuilder.h(among other header files), I get "error C2371: '[windows variable name]' : redefinition; " errors during compilation. Obviously, if I could change EVERY source file in my project to include fooBuilder.h as the first header file I'm good, but there are a 101 files which include fooBuilder.h! Abstracting out the windows specific headers into stdafx.h is not an option. What is the best way to overcome this situation? I'm open to any and all suggestions. I really don't want to change the "#include fooBuilder.h" position for every file!
Seeing fooBuilder.h + the exact change you did in it would help figuring out what the best way to fix this is.
Here are two possible solutions, hoping one will fit your needs:
1- Move the windows include from fooBuilder.h to fooBuilder.cpp. In almost every case it is doable. Whatever attribute you added to the class can be moved to a pointer (then use forward declaration), whatever parameter you added to a method can be passed by pointer or const reference (then use forward declaration too), whatever type you used can be redefined (like if you are using PVOID, just declare it yourself typedef void *LPVOID;). This is definitely the best and nicest way to fix your problem.
2- A windows header most likely ends up being included twice (one by the .cpp file causing the problem when you compile and one by fooBuilder.h). You can maybe prevent this from fooBuilder.h. Check where the variable is declared and check if you can prevent it's declaration through a pre-processing variable (or, even better, prevent the whole file from being included). Note that changing the order of the includes won't fix that.
I just started on a few C++ tutorials, and I have run into something that I just can't seem to make much sense of.
In C++ it seems people are using a code file and a header file, for me this just seem inconvinient. Why would I want to swap around between two files just to write a simple getter method.
Is it considered the "correct" way to use headers in C++? Or is it just the tutorial I have picked up that uses this?
I get the idea of splitting code to make it look more clean, but is it good for anything else other than that?
Thanks in advance.
There are some reasons for using hpp(header)- and cpp(code)-files. One of them is the following: A library (dll- or so-file) cannot be "used" like a jar-file in java. If you write a library, you have to provide declarations of the classes, methos,... in form of a hpp-file.
Think about using the class you wrote in other files. If you had the class definition in a separate file, you could help the compiler to figure out how to use the class by including the header file in places where you are planning to use this code.
The compiler only needs to know whether you are using the classes right(it does not care about how to run it, until linking), therefore all you need to give the compiler is the declaration of the class(header file), to do the error checking. When you say "include", the preprocessor just copies and pastes the header file contents into the new file, so that the new file now knows how to use the class you wrote.
A header file in c++ stores alot of information, if c++ have been made using every single "header" file in c++ in each program you make, when you then write a function from iostream for example, the program will go through every single header file just to find the right header file. so instead they made the #inlcude function in c++, so you could specify where your functions are from.
And when you create a program you could make own header files, so the code is more nicely set up. and then instead of having to make alot of lines of code in one main source file, you could import others. like if you are making a game, one header file for Animals and in that header file you have a Class for Cats, and one for dogs. having a more clean code.
In C/C++, headers are used to share the class structure (among other things) between classes.
so one can use
include "classFOO.h"
in classBAR.h (or classBAR.cpp) and use classFOO.
I started writing a simple interpreter in C++ with a class structure that I will describe below, but I quit and rewrote the thing in Java because headers were giving me a hard time. Here's the basic structure that is apparently not allowed in C++:
main.cpp contains the main function and includes a header for a class we can call printer.h (whose single void method is implemented in printer.cpp). Now imagine two other classes which are identical. Both want to call Printer::write_something();, so I included printer.h in each. So here's my first question: Why can I #include <iostream> a million times, even one after the other, but I can only include my header once? (Well, I think I could probably do the same thing with mine, as long as it's in the same file. But I may be wrong.) I understand the difference between a declaration and an implementation/definition, but that code gives me a class redefinition error. I don't see why. And here's the thing that blows my mind (and probably shows you why I don't understand any of this): I can't just include printer.h at the top of main.cpp and use the class from my other two classes. I know I can include printer.h in one of the two classes (headers) with no trouble, but I don't see why this is any different than just including it before I include the class in main.cpp (as doing so gives me a class not found error).
When I got fed up, I thought about moving to C since the OOP I was using was quite forced anyway, but I would run into the same problem unless I wrote everything in one file. It's frustrating to know C++ but be unable to use it correctly because of compilation issues.
I would really appreciate it if you could clear this up for me. Thanks!
Why can I #include a million times, even one after the other, but I can only include my header once?
It is probably because your header doesn't have an include guard.
// printer.h file
#ifndef PRINTER_H_
#define PRINTER_H_
// printer.h code goes here
#endif
Note that it is best practice to chose longer names for the include guard defines, to minimise the chance that two different headers might have the same one.
Most header files should be wrapped in an include guard:
#ifndef MY_UNIQUE_INCLUDE_NAME_H
#define MY_UNIQUE_INCLUDE_NAME_H
// All content here.
#endif
This way, the compiler will only see the header's contents once per translation unit.
C/C++ compilation is divided in compilation/translation units to generate object files. (.o, .obj)
see here the definition of translation unit
An #include directive in a C/C++ file results in the direct equivalent of a simple recursive copy-paste in the same file. You can try it as an experiment.
So if the same translation unit includes the same header twice the compiler sees that some entities are being defined multiple times, as it would happen if you write them in the same file. The error output would be exactly the same.
There is no built-in protection in the language that prevents you to do multiple inclusions, so you have to resort to write the include guard or specific #pragma boilerplate for each C/C++ header.
I have a program were I was given the compiled .o file but I do not have the original .cc file and also I only have a half-way finished header file. The header file has all the method signatures but is lacking the private variable declarations. I am trying to get this .o file to work with the project but get a segmentation fault at the constructor of the class defined by the .o file. The program compiles. How do I get this to work? The program is a homework assignment and the teacher does not want us to see the .cc file. Also my teacher knows about the issue. I am just trying to figure it out on my own (and hopefully with the help of you guys :) ). I thought I had done this before a while ago with another teacher but did not have any problems. There is a makefile that is used to compile the program.
If you are using a C++ program, and the header file includes class definitions, the class definitions must exactly match those that were used to originally build the file. This is the One Definition Rule. If your professor has removed private variable declarations from the class definitions, you will likely end up with crashes; this is because your different .o files will disagree about the size of the objects defined by those classes.
If your professor wants to hide the implementation of the class, they should use the p/impl pattern. If you want to use the header file, you must remove the mangled class definitions entirely and not attempt to use them (you can use a forward definition as in class Foo; to satisfy any functions which take/return the class as a pointer parameter, however).
During my searches through the Geant4 source code, I have noticed several times that there are methods which are declared in the header but are never defined with any associated code (pardon any falsities in my lingo (I'm an engineer)).
An example would be a method defined like:
G4TrackVector* GetfSecondary();
which has no implementation in the header or the source file, is not virtual, and yet it is used on various occasions by the program and the program runs from this compiled code. At first I thought it was just some cool code hiding trick with doxygen, but I now see it is not! This is a common occurrence in the code.
Could someone explain what's going on?
Thanks
The GetSecondary() function is a member of the G4Step class (defined in G4Step.hh) and is implemented inline in G4Step.icc. G4Step.icc is included at the end of G4Step.hh.
I'm guessing you were looking in the source directory instead of the include directory for the implementation, but the include dir is the propper place for inline implementation.
In the future if you are on *nix, you can try a grep -r <FunctionName> . from the top of the project directory to find all mentions of a function, which should include the implementation.
The code would fail to compile if this were the case. You just aren't looking in the right place for it's definition. Or just not noticing it. Calling a declared function with no definition is an error.