|
|
|||||||||
|
|||||||||
| |||||||||
|
|
|
| |||||||||
![]() |
|
|
«
Previous Thread
|
Next Thread
»
|
Thread Tools | Search this Thread | Rate Thread | Display Modes |
|
#1
|
||||
|
||||
|
Borland C++ header files
Hi. I just joined up because it seems like you guys really know what you're talking about. So, maybe I'll be able to finally get some answers that google searches can't provide.
Anyway, I have spent a year or so studying visual C++, and have just recently switched over to Borland Builder (not my choice). While I can see it is a very powerful piece of software, I found that there certainly was a learning curve involved, and not much help online to speak of. My specific troube thus far is this: while making a graphing program to plot simple to complicated graphs(using TPaintBox) using a txt file as a data source, it occurred to me that, while the program may be simple enough to do stand alone, I might as well make a header file for some practice. The header file should initialize the graph, and plot the axis and tick marks to user defined specs. I know how to do this from withing the program, but is it possible to manipulate the form objects froma header? I would assume the argument would look something like GraphUtil::SomeFunction(TPaintBox &Pbox){} But, then again I could be wrong alltogether. And then how would you be able to manipulate functions/properties of the object from the header? Thanks ahead of time. I would really appreciate some comments to help me out with this. |
|
#2
|
||||
|
||||
|
Honestly, imho, you shouldn't do anything more than store definitions in a header, everything else should be held in the c/cpp/cxx files themselves.
|
|
#3
|
||||
|
||||
|
What Onslaught says is quite true in general: only declarations (eg, #defines, typedefs, externs, class declarations, and function prototypes) should go into the header files and the actual definitions (eg, actual variable declarations, functions with function bodies) go into the .c/.cpp source files.
The only allowable exception to this general rule are inline methods in C++. Those would need to go into the header file as part of the class declaration. The reason for that is that the code of an inline method gets inserted directly into the calling function, rather than have the calling function actually jump to the method being called. However, inline methods are almost always very short, usually only one or two lines at most. The most common use for them that I have seen is as access methods to read a private/protected property of an object or to set a property; eg: Code:
class Klasse public
{
private:
int x;
public:
Klasse(void);
~Klasse(void);
int GetX(void){ return x; }
};
Note that the inlining is implicit in this case and does not need to be declared explicitly with the keyword inline: Quote:
|
|
#4
|
||||
|
||||
|
Hmm, college board programs sure do have a way of pulling the wool over your eyses... If all that is true, then I hardly know how to write a class. The curriculum as outlined by the college board demonstrates a completely different use for header files http://www.cplusplus.com/doc/tutorial/tut4-1.html. Not college board, but those examples are in gerneral what I have used classes for thus far. Well, thanks for the help though, I guess I will have to write out quite a bit of code then
![]() Last edited by AGibel : June 10th, 2003 at 01:00 PM. |
|
#5
|
|||
|
|||
|
Can you post some examples? The link you gave us doesn't even mention header files so I don't quite see its relevance. Please elaborate.
|
|
#6
|
||||
|
||||
|
Well, like these for instance..http://voyager.deanza.fhda.edu/~bentley/ex3-5_cpp.htm and http://voyager.deanza.fhda.edu/~bentley/ex3-1_cpp.htm . Both have classes that actually do something (i. e. are useable functions). According to those examples, I could write a class such as:
#ifndef _CLASS_H #define _CLASS_H class Class { int privVar; //since private is default public: Class(int integer); ~Class(); int DoSomething(int, int) }; //skipping constructer.... int Class::DoSomething(int Var1, int Var2){ //Bunch of stuff manipulating Var1 and 2 that were passed in by a .cpp file. } Then call from the .cpp { Class variable; variable.DoSomething(int var, int var2); } This is what we would always put in a .h file so it could be used by other programs as well.... So none of that should be done? |
|
#7
|
|||||
|
|||||
|
Quote:
Both of those examples are not header files, but rather cpp source files. In case this is the point of confusion, you can have a class declaration in the .cpp source file instead of in a header. The main (and perhaps only) reason you would put something in a header file would be to make it available to more than one source file. Quote:
I would need to experiment to see if such a project would even make. I would think that having multiple instances of the same methods in several different module would cause name collisions when you tried to link. Unless linkers are a lot smarter than I give them credit for and eliminate the duplicate methods -- or you've got error-checking set to the loosest sloppiest setting -- I'd be surprised if it worked. Quote:
It took me a while to shift paradigms here, but I finally realized that they probably taught you to do that in school because all they were having you do was to write single-module programs. But out here we big dogs write programs consisting of several modules; eg, my current project uses of 54 modules which consist of a total of 45,317 lines (raw count which includes comments and blank lines) -- and that's modest-sized project! With a single-module program, you can get away with that code-in-the-header malarky, but not in a real-world programming project. BTW, you are not the first person to post messages here about putting code in header files. I don't know why schools are teaching that, unless they all used the same book and the author thought that it would be a good idea (hint: could you tell us the name of your textbook so we could check that out?). Here's how it really works. When you make/build a project, each source module is compiled separately without any knowledge of how the other sources compiled. The header files are used to provide the compiler with the types, defines, variables, and functions declarations that it needs, most of which are located elsewhere. Actually, the header file itself gets included into the source file as if it had been written there in the first place. If the compiler doesn't have an address for a variable (eg, an extern) or function, then it marks that location as needing an address "fix up" by the linker. The output of the compiler is an object file, one for each source module. The linker then goes through and puts all the object files together, uses the addresses in them to fix the other modules' external references (AKA "address fixing"), and wraps them all up into an executable file. So, it is the linker that really makes stuff available to the other modules. The job of the header file is to tell those other modules what variables and functions are available to them and what data types and parameter lists they use and return. The information in the header files allow the compiler to do its job and then the linker does its job by making all the connections. You might think of it as having the header files tell you what the hooks are, but it's the linker that actually attaches all those hooks where they need to go. To reuse a class, what you do is to add its source file to the new project as yet another module and include its header file in the other modules that need it. Then your reusable class code will get compiled and linked in. An alternative would be to convert your reusable class into a library file (possibly/probably with other reusable classes as well). Then add that library to the new project's library list and include the header file to the modules as before. Most IDEs make project management very simple, so that it's real easy to add and remove modules to and from the project. If you don't use an IDE, then use a makefile to control the project. If you don't use an IDE and don't know how to use make, then it's time to learn. Welcome to the real world. Last edited by dwise1_aol : June 10th, 2003 at 03:24 PM. |
|
#8
|
||||
|
||||
|
Geesh I had no idea that classes could be written right withing the .cpp. Makes sense though. I'm only asking these questions becuase im currently making that transition into the real world. I'm a high school grad and im interning at NASA this summer. Part of what I'm doing is taking some old FORTRAN code and converting it to C++. However, as I mentioned before, I had never used Builder before, but rather the visual C++ console style. So now I'm really learning all over again.
What I was taught in high school was not from a book. It was an AP class and therefore it followed with the college board's AP curriculum. Rather than books, we literally received packets upon packets of chapters printed directly off the college board. Whether there is a CD, or some book, I don't know. All I know is, I feel almost cheated that I took that class, and now I have to "unlearn" many of the syntaxes that I became very use to. Anyway, thanks for your comments. Now I have to go figure out how to apply classes to builder ![]() |
|
#9
|
|||
|
|||
|
Quote:
|
|
#10
|
||||
|
||||
|
I don't really get what you mean here BigBadBob. dwise1_aol's explanation was pretty well done.
1) You declare functions, extern variables, etc... in a header file. 2) In the source file you define the functions, declare actual variables, etc... That is what dwise1_aol stated, or am I misunderstanding what you are meaning? |
|
#11
|
|||
|
|||
|
I agree, his reply was well done, I don't mean any disrespect. I guess I'm being nitpicky. It's just that a post yesterday confused definition and declaration, and he appeared to have done so again today when he listed under definitions "actual variable declarations". Of course, those are declarations.
|
|
#12
|
||||
|
||||
|
I am not a C++ / OOP guru, but I think there might be some confusion between AGibel's initial question and some of the answers he's gotten. He is writing a bunch of forms that have graphs on them. There are some routines that need to be run in order to initialize the graph and set its properties, etc. Instead of putting these routines in every single form, he wants to put these routines in a single .h file and include that file in each of his forms. Then he would take a reference / pointer to the graph and pass it to the function in the header file making it "possible to manipulate the form objects from a header".
Basically he's asking how to create a library of routines to manipulate graphs objects/controls that can be shared by all his forms to eliminate code duplication. The header doesn't actually manipulate the object, it just holds the routines that are called by each form. Instead of using individual routines, AGibel was talking about using a class that would declare (or is it define?) an object that could be instantiated and used to manipulate the graphs. The class would have a single .h file that would include code to manipulate the graphs (the methods of the class). If you look at the CoreLinux coding standard, Standard 177 is "A class shall have a single header file." This is what they taught him in school. If he wants to create an object to manipulate his graphs, that class and all its methods that "manipulate the form objects from a header" should be declared in a single header file. This was the principal he was trying to illustrate with his example. AGibel, did I understand your question correctly? Have I done a better job of stating your goal? Or am I confused as well? |
|
#13
|
|||
|
|||
|
And the answer he is getting here from several sources is that it is a bad idea. The code implementing the class should live in one place. The header file that describes how to use the class should be included in each of the places that it is needed. The snippet you quoted about the class having a single header file doesn't imply that the code should be in that file.
|
|
#14
|
||||
|