473,396 Members | 2,011 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

seperating definition and declaration files

18
It's been about 4 years since I did much in C++. To see if I remembered anything, I made a new project, made a header file containing a class, included the header file from my main file, used pointers to dynamically allocate memory for a user-indicated number of class instances, and it was great!

Now... I used to always be sure to seperate my definition and declaration files. What I have is below and it works, BUT I would like to have three files: main.cpp, animal.h, and animal.cpp. I remember how to code everything. It's the preprocessor directives I cannot seem to get right. However In case a compiler issue arrises, I use Bloodshed's Dev-C++. :-)

main.cpp:
Expand|Select|Wrap|Line Numbers
  1. #include <animal.h>
  2. ...
  3.  
animal.h:
Expand|Select|Wrap|Line Numbers
  1. #ifndef ANIMAL_H
  2. #define ANIMAL_H
  3. ...
  4. #endif
  5.  
Once I create animal.cpp (already have, but cannot seem to include correctly), do I add a directive to the header file? To the new file?
Oct 17 '07 #1
10 2028
I'm not sure what you're asking, but if you want to know if you put a #include"animal.h" in your animal.cpp file, you do...
Oct 17 '07 #2
Danigan
18
That's basically what I'm asking, but is seems I must be missing something because I get an error like this for about every member function: "36 C:\Dev-Cpp\practice\multifile classes\animal.h `int animal::animalCount' previously defined here".

My header file just has the function prototypes:
Expand|Select|Wrap|Line Numbers
  1. //animal.h
  2. //Class header for the animal class.
  3.  
  4. //Prevent multiple includes:
  5. #ifndef ANIMAL_H
  6. #define ANIMAL_H
  7.  
  8. //Include dependencies:
  9. #include <string>
  10. #include <iostream>
  11.  
  12. using namespace std;
  13.  
  14. class animal
  15. {
  16. private:    
  17.     static int animalCount; //Total number of animals; Initialized to 0.
  18.     string animalType;
  19.     int animalId;
  20.  
  21. public:
  22.     animal();
  23.     int getNumberOfAnimals();
  24. };
  25.  
  26. #endif
  27.  
My animal.cpp is as follows:
Expand|Select|Wrap|Line Numbers
  1. //animal.cpp
  2.  
  3. #ifndef ANIMAL_CPP
  4. #define ANIMAL_CPP
  5.  
  6. #include <animal.h>
  7.  
  8. using namespace std;
  9.  
  10. int animal::animalCount = 0;
  11.  
  12. animal::animal()
  13. {
  14.     cout << "What is the type of this animal? ";
  15.     cin >> animalType;   
  16.     animalCount++;
  17.     animalId = animalCount;
  18. }
  19.  
  20. int animal::getNumberOfAnimals()
  21. {
  22.     return animalCount;
  23. }    
  24.  
  25. #endif
  26.  
My main.cpp is as follows:
Expand|Select|Wrap|Line Numbers
  1. #include <iostream>
  2. #include <animal.h>
  3.  
  4. using namespace std;
  5.  
  6. int main()
  7. {
  8.     //Initialize a variable to 0 that represents how many animals will be created:
  9.     int totalAnimalsToCreate = 0;
  10.     //Ask the user how many animals are desired:
  11.     cout << "How many animals should we create? " <<endl;
  12.     cin >> totalAnimalsToCreate;
  13.     //Create the user's desired number of animals:
  14.     animal * ptrAnimals = new animal[totalAnimalsToCreate];
  15.  
  16.     cout << ptrAnimals[1].getNumberOfAnimals()
  17.          << " animal(s) created successfully!" << endl;
  18.     system("PAUSE");
  19.  
  20.     delete [] ptrAnimals;
  21.  
  22.     return 0;
  23. }
  24.  
Maybe I've regressed more than I thought or have a rough compiler setting...
Oct 17 '07 #3
Danigan
18
This is so common that I can't imagine why I can't find a tutorial on it. Every tutorial does everything in one file for "simplicity". :-(
Oct 18 '07 #4
arunmib
104 100+
I think the problem is with this line 'int animal::animalCount = 0;' . It's a private variable and you are intializing it in file just like that......I don't think it's allowed....
Oct 18 '07 #5
Danigan
18
I think the problem is with this line 'int animal::animalCount = 0;' . It's a private variable and you are intializing it in file just like that......I don't think it's allowed....

I can't do that in the class because it's static. There can only be one instance of it. It only appears once in memory even if I have 50 instances of my class.

Note that if I copy all the code to the bottom of the header file, it works fine. That means (I think) the code is actually OK. It's my preprocessor directives that must be bad because the code in a separate cpp from the header causes problems.
Oct 18 '07 #6
Ganon11
3,652 Expert 2GB
First, you have your include statements saying

Expand|Select|Wrap|Line Numbers
  1. #include <animal.h>
when they should be

Expand|Select|Wrap|Line Numbers
  1. #include "animal.h"
I think the difference is, when you use <> around the file, you're telling the compiler to look in some standard place first, then anywhere else on the computer. When you use "" around the file, you're telling the compiler to look in the same folder as the current file (which is oftentimes much faster).

Now, in your main program, you #include animal.h. In your animal.cpp, you #include animal.h. In animal.h, you don't include anything. So your main program will pull this class definition, but where's the method definitions? I'm not entirely sure (because my compiler forces me to put all source code in the same file, so I never have an animal.cpp), but I think you need to #include animal.cpp in the header file.
Oct 18 '07 #7
Laharl
849 Expert 512MB
You don't need to include "animal.cpp" because the linker takes care of that for you, as long as the two files have the same name.

Other than that, this compiles fine for me on g++ 4.1.3...
Oct 18 '07 #8
Danigan
18
First, you have your include statements saying

Expand|Select|Wrap|Line Numbers
  1. #include <animal.h>
when they should be

Expand|Select|Wrap|Line Numbers
  1. #include "animal.h"
I think the difference is, when you use <> around the file, you're telling the compiler to look in some standard place first, then anywhere else on the computer. When you use "" around the file, you're telling the compiler to look in the same folder as the current file (which is oftentimes much faster).

Now, in your main program, you #include animal.h. In your animal.cpp, you #include animal.h. In animal.h, you don't include anything. So your main program will pull this class definition, but where's the method definitions? I'm not entirely sure (because my compiler forces me to put all source code in the same file, so I never have an animal.cpp), but I think you need to #include animal.cpp in the header file.
I'm not sure what I'm doing is correct, but I manhandled the quotes and brackets in my compiler settings to look in the proper places, haha. It should be unimportant... I think.

I completely agree with you that it doesn't seem like I'm pullin in the definitions but there has two opposing considerations:
  1. If I include the animal.cpp in animal.h, it seems like the compiler would see the declarations before the definitions, causing problems.
  2. The compiler might not be generating the rediffinition errors unless it indeed can get to the animal.cpp. I imagine it looks there after the animal.h because of the same file name. I thought I remembered that a compiler would look for a file with the same name for the deffinition when you included a header file.
Oct 18 '07 #9
Danigan
18
Uereeeeeka!!

I got it!

Dev-C++ seems to absolutely require that the deffinitions file for a header have the extension hpp instead of cpp... I'm a little disappointed that Bloodshed would do something so compiler specific, but I suppose it eliminates some ambiguity in file naming.

Case closed... (pleased smile)
Oct 18 '07 #10
oler1s
671 Expert 512MB
I do not like what I have seen in this thread so far. The case is not closed as far as I am concerned.

Dev-C++ seems to absolutely require that the deffinitions file for a header have the extension hpp instead of cpp.
What do you mean by this? I don't like the terminology used. A header file is used for declarations, so are you referring to the header file or the source file that is the companion to the header file? (A source file would contain definitions). Either way, a .h / .cpp scheme works just fine. Dev-C++ is an IDE for MinGW, which in turn is the windows port of gcc. Believe me when I say that it's very, very, very unlikely gcc requires .hpp, as heh, tell that to the entire linux world. And me.

I'd like to see the the compiler version. Open up command prompt, go to the directory where Dev-C++ installed all the MinGW executables. Type in g++ -V and post the output here.

There also seems to be confusion on the part of what the relationship between include directives, .cpp, and .h files are. And Ganon, I'm very curious as to what compiler you have that requires single files for source code.

Question for you people. Why do we have header files, and why do we include them? Well, including them is the rough act of copy and pasting, so here's the big question. Why does the material in header files get copy and pasted at the beginning of source files? What's the reason we need to do so?

Take an example:
Expand|Select|Wrap|Line Numbers
  1. //Also declared in someFunc.h as int someFunc();
  2. int someFunc()
  3. {
  4.     ....
  5. }
  6.  
Expand|Select|Wrap|Line Numbers
  1. //main.cpp
  2. int someFunc(); //from an include someFunc.h
  3.  
  4. int main()
  5. {
  6.     ...
  7.     someFunc();
  8.     ...
  9. }
  10.  
Why do we have a forward declaration in main.cpp? After all, we have the function defined in somefunc.cpp. It's because the compiler deals with source files independently. It will never know about the existence of other source files, even if you tell it to compile multiple files at once. Yet, to compile, you must have valid syntax, which requires knowledge of what you have created in other source files. So the solution are declarations, which do not seek to define what the functions and classes and variables in other source files. Just their existence, so the compiler can compile a source file properly.

It is only in the linking stage, that everything gets put together. You leave this up to the linker. It will take all the compiled translation units and create the appropriate binary file from them.
Oct 18 '07 #11

Sign in to post your reply or Sign up for a free account.

Similar topics

2
by: AMT2K5 | last post by:
Hello. When I compile my program I recieve lots and lots of the following message which I am trying to decipher. "xxx was declared deprecated". What exactly does that mean?
19
by: J. J. Farrell | last post by:
After many years of dealing with definition and linkage issues in ways that I know to be safe, I've decided it's time to try to understand this area properly. Consider a header file with the file...
12
by: J. J. Farrell | last post by:
After many years of dealing with definition and linkage issues in ways that I know to be safe, I've decided it's time to try to understand this area properly. Consider a header file with the file...
0
by: AnkitAsDeveloper [Ankit] | last post by:
As all we know, in order to remove cyclic includes in C++ we seperate the declarations and definitions of classs and it's member in two files Header (*.h) and source files (*.cpp). This is not a...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.