I have a question about h. file and .cpp file.
For example, I have three files, one head file(Chain_ChainNode.h) and two source file(Chain_ChainNode.cpp and main.cpp.
Chain_ChainNode.h declared the class Chain and ChainNode.
Chain_ChainNode.cpp implemented the functions in Class Chain.
Main.cpp has the main function.
This program can only be compiled when I include Chain_ChainNode.cpp in the Main.cpp as the following. But I don't think it's necessary to include the source file in main.cpp.
While technically possible, it goes against common practice to #include a .cpp file. Just put template definitions into the .h file, which is where they are supposed to be.
Thanks for your replay!
But Is it a good idea to put template definitions into the .h header file? I find it every book suggests that it's better to separate the declaration file and definition file.
=====================================================//Header file//
//: C06:Stash2.h
#ifndef STASH2_H
#define STASH2_H
class Stash {
int size; // Size of each space
int quantity; // Number of storage spaces
int next; // Next empty space
// Dynamically allocated array of bytes:
unsignedchar* storage;
void inflate(int increase);
public:
Stash(int size);
~Stash();
int add(void* element);
void* fetch(int index);
int count();
};
#endif // STASH2_H ///:~
=====================================================
//definition file//
//: C06:Stash2.cpp {O}
#include "Stash2.h"
#include "../require.h"
#include <iostream>
#include <cassert>
usingnamespace std;
constint increment = 100;
Stash::Stash(int sz) {
size = sz;
quantity = 0;
storage = 0;
next = 0;
}
int Stash::add(void* element) {
if(next >= quantity) // Enough space left?
inflate(increment);
// Copy element into storage,
// starting at next empty space:
int startBytes = next * size;
unsignedchar* e = (unsignedchar*)element;
for(int i = 0; i < size; i++)
storage[startBytes + i] = e[i];
next++;
return(next - 1); // Index number
}
void* Stash::fetch(int index) {
require(0 <= index, "Stash::fetch (-)index");
if(index >= next)
return 0; // To indicate the end
// Produce pointer to desired element:
return &(storage[index * size]);
}
int Stash::count() {
return next; // Number of elements in CStash
}
void Stash::inflate(int increase) {
require(increase > 0,
"Stash::inflate zero or negative increase");
int newQuantity = quantity + increase;
int newBytes = newQuantity * size;
int oldBytes = quantity * size;
unsignedchar* b = newunsignedchar[newBytes];
for(int i = 0; i < oldBytes; i++)
b[i] = storage[i]; // Copy old to new
delete [](storage); // Old storage
storage = b; // Point to new memory
quantity = newQuantity;
}
Stash::~Stash() {
if(storage != 0) {
cout << "freeing storage" << endl;
delete []storage;
}
} ///:~
=====================================================
//Main.cpp file//
//: C06:Stash2Test.cpp
//{L} Stash2
// Constructors & destructors
#include "Stash2.h"
#include "../require.h"
#include <fstream>
#include <iostream>
#include <string>
usingnamespace std;
int main() {
Stash intStash(sizeof(int));
for(int i = 0; i < 100; i++)
intStash.add(&i);
for(int j = 0; j < intStash.count(); j++)
cout << "intStash.fetch(" << j << ") = "
<< *(int*)intStash.fetch(j)
<< endl;
constint bufsize = 80;
Stash stringStash(sizeof(char) * bufsize);
ifstream in("Stash2Test.cpp");
assure(in, " Stash2Test.cpp");
string line;
while(getline(in, line))
stringStash.add((char*)line.c_str());
int k = 0;
char* cp;
while((cp = (char*)stringStash.fetch(k++))!=0)
cout << "stringStash.fetch(" << k << ") = "
<< cp << endl;
} ///:~
From this example, we can clearly see that the Stash2.cpp file which is the definition file was not included in the main file. So How can the compiler find the definition according to declaration in Stash.h?
@LowestOne
Er, no. If you are going to #include a .cpp file, do it in another .cpp file, never in a header.
@akluffy
The .cpp files get compiled to actual code. An individual .cpp file gets compiled to an "object file". Your object files are "linked" together to create an executable.
Header files do not get compiled. They just describe the stuff you will find in a .cpp file.
So, for example,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
// greeting.hpp
// This file is not compiled.
#pragma once
#ifndef GREETING_HPP
#define GREETING_HPP
#include <string>
namespace greeting
{
void hello( const std::string& name = "world" );
} // namespace greeting
#endif
If you are going to include the cpp, do it in the header file, not in main.cpp
Now, I am no expert with templates, but I thought the usual practice (and as Cubbi says) was not to include .cpp files.
I know you are saying if, but in your example, why wouldn't the code in class.cpp be part of the header file ?
Now I am not trying to be pedantic, and I am aware that you probably have much more knowledge & experience than me, but I am asking why you would promote such an idea?
I am asking this for my education as much as anyone else's, and am hoping it doesn't come across as overt criticism, rather a simple query.
But why? I thought include just included the file. These two examples would end the same
1 2 3 4 5
// my_header.h
int func(void);
int func(void) { return 0; }
1 2 3 4 5 6 7 8
// my_header.h
int func(void);
#include my_header.cpp
// my_header.cpp
int func(void) { return 0; }
I probably know less than you all do anyway :). Just spouting off what I read in a book. The only reason it gave for this was to just make things look a little more clean. The downside is that you have to remember that you could never compile the source into an object.