473,729 Members | 2,376 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Use Class Definition From Different File


hi,

I'm working on a project spanning five .cpp files. each file was used
to define a class. the first has my Main and an #include for each of
the other files.

problem is my third file needs to access the class defined in my second
file and I can't figure out how to work this right. if I use an
#include in my third file, my Main gives me a compile-time class
redefinition error. if I don't, the third file can't "see" the second
file.

anyone tell me what I'm doing wrong?

Sep 26 '05 #1
7 12965
Classes should be declared in .h files; And
In each .h files, those two following statements:
#ifndef _XXXX_H // XXXX is the name of your .h file
#define _XXXX_H
should occured in the most beginning of .h files, and meanwile,
the following statement:
#endif
shoud occured in the most end/
<A_*********@ho tmail.com> ????
news:11******** **************@ o13g2000cwo.goo glegroups.com.. .

hi,

I'm working on a project spanning five .cpp files. each file was used
to define a class. the first has my Main and an #include for each of
the other files.

problem is my third file needs to access the class defined in my second
file and I can't figure out how to work this right. if I use an
#include in my third file, my Main gives me a compile-time class
redefinition error. if I don't, the third file can't "see" the second
file.

anyone tell me what I'm doing wrong?

Sep 26 '05 #2

Jeff Chen wrote:
Classes should be declared in .h files; And
In each .h files, those two following statements:
#ifndef _XXXX_H // XXXX is the name of your .h file
#define _XXXX_H
should occured in the most beginning of .h files, and meanwile,
the following statement:
#endif
shoud occured in the most end/

tried but doesn't appear to be working. I'll fiddle around with it...

Sep 26 '05 #3
A_*********@hot mail.com wrote:
hi,

I'm working on a project spanning five .cpp files. each file was used
to define a class. the first has my Main and an #include for each of
the other files.
This is wrong. Never include one cpp file in another cpp file.

problem is my third file needs to access the class defined in my second
file and I can't figure out how to work this right. if I use an
#include in my third file, my Main gives me a compile-time class
redefinition error. if I don't, the third file can't "see" the second
file.

anyone tell me what I'm doing wrong?


You don't know about header files. Split each of you files, except the
main one, into two, a header file (.h) and a source file (.cpp). The
header file contains the class declaration, the source file contains
definitions for the class constructors, methods, etc.

E.g.

file: xyz.h

#ifndef XYZ_H
#define XYZ_H

class XYZ
{
public:
XYZ();
void func();
...
};

#endif

file: xyz.cpp

#include "xyz.h"

XYZ::XYZ()
{
...
}

void XYZ::func()
{
...
}

....

Now in cpp file that needs to know about the other class, include the
header file for that other class. And in the main file include all the
header files.

Now learn how to compile and link all the cpp files using your compiler.
If you are using a command line based compiler like g++ then that means
something like this

g++ main.cpp xyz.cpp other.cpp other2.cpp abc.cpp

or something, obviously adjust for what your cpp files are really called.

If you are using an IDE like Visual C++ then you probably have to do
something like 'Add File to Project...' and do that for all of your cpp
files.

And now your done. Follow this model for every program you write, and
don't ever include one cpp file in another.

I bet that you were only ever compiling your main cpp file, and were
relying on #include to compile your other cpp files. What book are you
learning C++ from that doesn't explain this? Time to get a new book.

john
Sep 26 '05 #4

John Harrison wrote:
And now your done. Follow this model for every program you write, and
don't ever include one cpp file in another.

thx John. that solved my problem - and I learned something new. very
much appreciate your help.

I bet that you were only ever compiling your main cpp file, and were
relying on #include to compile your other cpp files. What book are you
learning C++ from that doesn't explain this? Time to get a new book.

john

I'm mainly reading "The C++ Standard Library" by Josuttis at the
moment. put Stroustrup's "The C++ Programming Language" aside when I
noticed I couldn't comprehend a word of it.

got another question though. what is the benefit of header files?
they seem somewhat redundant to me. I don't see why I shouldn't be
able to just link up five .cpp files as I'd tried to. as long as
there's only one Main, know what I mean? the proper way now has me
handling twice the number of files and making twice the number of
adjustments whenever I need to add or remove a function.

Sep 26 '05 #5
A_*********@hot mail.com wrote:
got another question though. what is the benefit of header files?
they seem somewhat redundant to me. I don't see why I shouldn't be
able to just link up five .cpp files as I'd tried to. as long as
there's only one Main, know what I mean? the proper way now has me
handling twice the number of files and making twice the number of
adjustments whenever I need to add or remove a function.


Some time ago, I wrote a reply to a slightly
different topic which also turned around header files and their
usage. I think it applies also to your problem even if it is
not directly addressed to you.

*************** *************

Your question and the way it is formulated show a deap
misunderstandin g about how the whole process of building
an executable from the source file works.

First of all let me introduce a few terms and clearify
their meaning:

source code file The files which contains C or C++
code in the form of functions and/or
class definitions

header file Another form of source file. Header files
usually are used to seperate the 'interface'
description from the actual implementation
which resides in the source code files.

object code file The result of feeding a source code file through
the compiler. Object code files already contain
machine code, the one and only language your computer
understands. Nevertheless object code at this stage
is not executable. One object code file is the direct
translation of one source code file und thus usually
lacks external references, eg. the actual implementation
of functions which are defined in other source code files.

library file a collection of object code files. It happens frequently that
a set of object code files is always used together. Instead
of always listing all those object code files during the
link process it is often possible to build a library from
them and use the library instead. But there is no magic
with a library. A library can be seen as some repository
where one can deposit object code files such that the library
forms a collection of them.

compiling the process of transforming the source code files into
object code file. C and C++ define the concept of 'translation
unit'. Each translation unit (normally: one single source code
file) is translated independently of all other translation units.

linking the process of combining multiple object code files and libraries
into an executable. During the linking process all external references
of one object code file are examined and the linker tries to find
modules which satisfy those external references.

In practice the whole process works as follows:
Say you have 2 source files (with errors, we will return to them later)

main.c
******

int main()
{
foo();

}

test.c
******

void foo()
{
printf( "test\n" );

}

and you want to create an executable. The steps are
as in the graphics:

main.c test.c
+----------------+ +-----------------------+
| | | |
| int main() | | void foo() |
| { | | { |
| foo(); | | printf( "test\n" ); |
| } | | } |
+----------------+ +-----------------------+
| |
| |
v v
********** **********
* Compiler * * Compiler *
********** **********
| |
| |
| |
main.obj v test.obj v
+--------------+ +--------------+
| machine code | | machine code |
+--------------+ +--------------+
| |
| |
+------------------+ +--------------------+
| |
v v
************* Standard Library
* Linker *<----------+--------------------+
************* | eg. implementation |
| | of printf or the |
| | math functions |
| | |
| +--------------------+
main.exe v
+-------------------------+
| Executable which can |
| be run on a particluar |
| operating system |
+-------------------------+

So the steps are: compile each translation unit (each source file) independently
and then link the resulting object code files to form the executable. To do that
misssing functions (like printf or sqrt) are added by linking in a prebuilt library
which contains the object modules for them.

The important part is:
Each translation unit is compiled independently! So when the compiler compiles
test.c it has no knowledge about what happend in main.c and vice versa. When the
compiler tries to compile main.c it eventually reaches the line
foo();
where main.c tries to call function foo(). But the compiler has never heared about
a function foo! Even if you have compiled test.c prior to it, when main.c is
compiled this knowledge is already lost. Thus you have to inform the compiler
thar foo() is not a typing error and that there indeed is somewhere a function
called foo. You do this with an function prototype:

main.c
+----------------+
| void foo(); |
| |
| int main() |
| { |
| foo(); |
| } |
+----------------+
|
|
v
**********
* Compiler *
**********
|

Now the compiler knows about this function and can do its job. In very much the same way
the compiler has never heared about a function called printf(). printf is not part of
the 'core' language. In a conforming C implementation it has to exist somewhere, but
printf() is not on the same level as 'int' is. The compiler knows about 'int' and
what it means, but printf is just a function call and the compiler has to know its
parameters and return type in order to compile a call to it. Thus you have to inform
the compiler of its existence. You could do this in very much the same way as you
did it in main.c, by writing a prototype. But since this is needed so often and
there are so many other functions available, this very fast gets boring and error prone.
Thus somebody else has already provided all those protoypes in a seperate file, called
a header file, and instead of writing the protoypes by yourself, you simply 'pull in'
this header file and have them all available:

test.c
+-----------------------+
| #include <stdio.h> |<-+
| | |
| void foo() | |
| { | |
| printf( "test\n" ); | |
| } | |
+-----------------------+ |
| |
| |
v |
********** stdio.h v
* Compiler * +-------------------------------------+
********** | ... |
| | int printf( const char* fmt, ... ); |
| ... |
+-------------------------------------+

And now the compiler has everything it needs to know to compile test.c
Since main.c and test.c could have been compiled successfully they can be linked
to the final executable which can be run. During the process of linking the linked
figures out that there is a call to foo() in main.obj. Thus the linker tries to find
a function called foo. It finds this function by searching through the object
module test.obj. The linker thus inserts the correct memory address for foo
into main.obj and also includes foo from test.obj into the final executable. But
in doing so, the linker also figures out, that in function foo() there is a call
to printf. The linker thus searches for a function printf. It finds it in the
standard library, which is always searched when linking a C program. There the
linker finds a function printf and this function thus is included into the
final executable too. printf() by itself may use other functions to do its
work but the linker will find all of them in the standard library and include
them into the final executable.

There is one thing left to talk about. While main.c is correct from a technical
point of view it is still unsatisfying. Imagine that our function foo() has
a much more complicated argument list. Also imagine that your program does not
consist of just those 2 translation units but instead has 100-dreds of them and
that foo() needs to be called in 87 of them. Thus you would have write a prototype
in every single one of them. I think I don't have to tell you what that means: All those
prototypes need to be correct and just in case function foo() changes (things like
that happen), all those 87 prototypes need to be updated. So how can you do that?
You already know the solution, you have used it already. You do pretty much
the same as you did in the case of stdio.h. You write a header file and
include this instead of the prototype:

main.c
+-------------------+ test.h
| #include "test.h" |<---------+-------------+
| | | void foo(); |
| int main() | | |
| { | +-------------+
| foo(); |
| } |
+-------------------+
|
|
v
**********
* Compiler *
**********
|

Now you can include that header file in all the 87 translation units which
need to know about foo(). And if the prototype for foo() needs some update
you do it in one central place: by editing file test.h. All 87 translation
units will pull in this updated protype when they are recompiled.

HTH
--
Karl Heinz Buchegger
kb******@gascad .at
Sep 26 '05 #6
A_*********@hot mail.com wrote:

[snip]
got another question though. what is the benefit of header files?
You can use them to do separate compilation. That reduces build times in
larger projects.

Some people also might argue that header files should just contain
declarations so that human readers are not confused by all those
implementation details. I think, that is confusing header files with
documentation.

they seem somewhat redundant to me.
Same here, I never use them. [My code is usually templated and as compilers
still have to catch up on "export", I cannot benefit from separate
compilation anyway.]

I don't see why I shouldn't be able to just link up five .cpp files as
I'd tried to.
There is no problem with that. I do that all the time.

as long as there's only one Main, know what I mean?
Well, also you have to make sure that they are included only once and in
proper order. Inclusion guards are your friends. Also, every file needs to
include all the files it relies upon.

Example:

// file: logger.cc

#ifndef LOGGER_CC
#define LOGGER_CC

#include <iostream>

.....

#endif // LOGGER_CC
// file: worker.cc

#ifndef WORKER_CC
#define WORKER_CC

#include "logger.cc"

....

#endif // WORKER_CC
Works for me.

the proper way now has me handling twice the number of files and making
twice the number of adjustments whenever I need to add or remove a
function.


Yeah, header files are inconvenient that way.
Best

Kai-Uwe Bux
Sep 26 '05 #7

thx for the detailed replies, all. boy am I glad you guys are here.

Sep 27 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
1564
by: daishi | last post by:
Hi, I am wondering if someone could help me understand some of the details of using metaclasses. I am trying to use metaclasses to auto-generate some attributes and methods in a class definition. I am attaching a simplified example of the kind of code I am considering below, and I have the following questions:
3
2131
by: serge calderara | last post by:
Dear all, I have define a configuration file for my application with different section groups and settings belonging to each individual group like as follow : ===================================================== <?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections>
3
3604
by: DanielBradley | last post by:
Hello all, I have recently been porting code from Linux to cygwin and came across a problem with static const class members (discussed below). I am seeking to determine whether I am programming non-standard C++ or if the problem lies elsewhere. To summarize static const class members are not being accessed properly when accessed from a DLL by another external object file (not within the DLL). It only occurs when the static const...
16
2646
by: pawel.pabich | last post by:
Hajo, I would like to have 2 my own partial classes. For example: Default.aspx.cs Default2.aspx.cs and they both will relate to Default.aspx page.
10
2679
by: Ognen Duzlevski | last post by:
Hi, I have a "language definition" file, something along the lines of: page :: name : simple caption : simple function : complex function :: name : simple code : simple
2
1683
by: tony | last post by:
Hello! I'm trying to build a class library which has a class called AvestaPlantFunc. In this project building a class libray exist a class called AvestaPlantFunc. In this class is there a method called IsBottomMixValid. Code not relevant for the question has been removed. This method IsBottomMixValid has one parameter and the type for this parameter is MeltPracDataGmix meaning passing class reference MeltPracDataGmix.
2
1835
by: jordanp | last post by:
Hello, I'm having a little trouble here and I'm hoping that somebody might be able to help me out (win32 console program). First off, I know that I can use class function inside of my struct as a struct object...but my issue that I'm having is that my class function is set up so that it sets 3 variables... Example of my class object (has the getter(), and setter() functions below this, but I won't display that here):
8
7627
by: nishit.gupta | last post by:
I was having a problem with template class memer function definition , so i serched the net and find that template class member fuction definition should be in header file else compilation will be successful but not linking. Can somebody help me in telling the exact reason why compiler cannot find the reference of template class member function definition defined in cpp file?? following problem is not linking (undefined reference of...
9
8891
by: Jess | last post by:
Hello, I was told that if I declare a static class constant like this: class A{ static const int x = 10; }; then the above statement is a declaration rather than a definition. As I've *defined* "x"'s value to be 10, isn't above statement a
2
7110
by: joe t. | last post by:
My apologies, i'm not sure how to ask this question correctly, so i'll give the examples as i go. First, i *think* my problem is described here, but i may be misunderstanding: http://bugs.php.net/bug.php?id=15233&edit=1 Second, here's my problem: i have a class defined. Inside that class are several LONG functions
0
9426
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9281
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
8148
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6722
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6022
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4525
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4795
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3238
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2163
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.