PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Autres forums > Forum Programmation & Conception > comp.lang.cplus > How to instantiate objects in a public include file
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
How to instantiate objects in a public include file

Réponse
 
LinkBack Outils de la discussion
Vieux 25/02/2008, 21h32   #1
Ed J
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut How to instantiate objects in a public include file

In a public include file, how can I declare an object and instantiate an
object all in one line, avoid seemingly duplicate information? I am
typically used to doing something like the following, but I've never liked
having to provide two lines related to the same object:

extern MyClass obj1;
extern MyClass obj2;
#if defined( INSTANTIATE_OBJECTS )
MyClass obj1( 111 );
MyClass obj2( 222 );
#endif

In one and only one C++ file, I would define INSTATIATE_OBJECTS to force the
instantiate.

I'm hoping to find a C-preprocessor trick that would let me use a single
line to both declare and instantiate an object, depending on the value of a
preprocessor macro. For example, I could use something like this (if I
could embed a "//" comment into a macro definition):

#if defined( INSTANTIATE_OBJECTS)
#define DECLARE_VS_DEFINE
#else
#define DECLARE_VS_DEFINE ; //
#endif
extern MyClass obj1 DECLARE_VS_DEFINE ( 111 );
extern MyClass obj2 DECLARE_VS_DEFINE ( 222 );

Does such a preprocessor macro trick exist? Is there another way to do it?
It would have to work with the Visual C compiler and GNU GCC.

Thanks,

Ed Jubenville


  Réponse avec citation
Vieux 25/02/2008, 21h46   #2
Victor Bazarov
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: How to instantiate objects in a public include file

Ed J wrote:
> In a public include file, how can I declare an object and instantiate
> an object all in one line, avoid seemingly duplicate information?[..]


Never instantiate an object in a header. As soon as the header is
included in more than one translation unit (and if it isn't why it
is a header, right?), you get the object defined more than once.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


  Réponse avec citation
Vieux 26/02/2008, 01h50   #3
Jim Langston
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: How to instantiate objects in a public include file

Ed J wrote:
> In a public include file, how can I declare an object and instantiate
> an object all in one line, avoid seemingly duplicate information? I
> am typically used to doing something like the following, but I've
> never liked having to provide two lines related to the same object:
>
> extern MyClass obj1;
> extern MyClass obj2;
> #if defined( INSTANTIATE_OBJECTS )
> MyClass obj1( 111 );
> MyClass obj2( 222 );
> #endif
>
> In one and only one C++ file, I would define INSTATIATE_OBJECTS to
> force the instantiate.
>
> I'm hoping to find a C-preprocessor trick that would let me use a
> single line to both declare and instantiate an object, depending on
> the value of a preprocessor macro. For example, I could use
> something like this (if I could embed a "//" comment into a macro
> definition):
> #if defined( INSTANTIATE_OBJECTS)
> #define DECLARE_VS_DEFINE
> #else
> #define DECLARE_VS_DEFINE ; //
> #endif
> extern MyClass obj1 DECLARE_VS_DEFINE ( 111 );
> extern MyClass obj2 DECLARE_VS_DEFINE ( 222 );
>
> Does such a preprocessor macro trick exist? Is there another way to
> do it? It would have to work with the Visual C compiler and GNU GCC.


As V says, you don't. That's why we have header files and source files.
Why can't you just put

MyClass obj1( 111 );
MyClass obj2( 222 );

in a .c file and include it in your project? That's the way the language is
designed.


--
Jim Langston
tazmaster@rocketmail.com


  Réponse avec citation
Vieux 27/02/2008, 19h15   #4
Ed J
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: How to instantiate objects in a public include file

Victor Bazarov wrote:
> Never instantiate an object in a header. As soon as the header is
> included in more than one translation unit (and if it isn't why it
> is a header, right?), you get the object defined more than once.


The object doesn't get defined more than once if the programmer (me) follows
the rules:
1. In ordinary source (.c) files wishing access to the declarations, I
simply do:
#include "filename.h"
2. In one and only one source file, I define INSTANSTIATE_OBJECTS before
including the file, and it gives me the declaration and the instantiation:
#define INSTANTIATE_OBJECTS
#include "filename.h"

I've used this technique many times on simple uninitialized variables to
avoid the hassle of maintaining two different source files (the .h and .c)
with the same object names. A typical xyz.h file would contain something
like this:

#if defined( INSTANTIATE_XYZ_OBJECTS )
#define EXTERN
#else
#define EXTERN extern
#endif
EXTERN int xyz1;
EXTERN int xyz2;

That single block of source code serves both the purpose of declaration and
instantiation of xyz1 and xyz2, depending on whether the including .c file
first declares INSTANTIATE_XYZ_OBJECTS. But this technique only works for
uninitialized variables. I'm trying to find a similar technique for
initialized variables.

Editorial... It is a pet peeve of mine that the C and C++ languages require
me to create two source code lines (one in a .c file, and one in a .h file)
associated with the same object name. Simply put, one source code line is
easier to maintain than two source code lines, especially when those two
source code lines must, by edict of C/C++, reside in separate files. That's
edict is a maintenance hassle that I would gladly circumvent if I knew how.

Any ideas?


  Réponse avec citation
Vieux 27/02/2008, 20h50   #5
dp1978x@gmail.com
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: How to instantiate objects in a public include file

On Feb 27, 2:15 pm, "Ed J" <j...@privacy.net> wrote:
[snip]

Something along the lines of:

#ifdef INSTANTIATE_XYZ_OBJECTS
# define XYZ_EXTERN
# define XYZ_ARGS(args) args
#else
# define XYZ_EXTERN extern
# define XYZ_ARGS(args)
#endif

// no args
XYZ_EXTERN MyClass (obj0a);
XYZ_EXTERN MyClass (obj0b) XYZ_ARGS (());

// 1 arg
XYZ_EXTERN MyClass (obj1) XYZ_ARGS ((111));

// 2 args
XYZ_EXTERN MyClass (obj2) XYZ_ARGS ((111, 222));

But as others have pointed out it's a BAD IDEA. There are plenty of
ways you can abuse the preprocessor, why stop there? You could just as
well move all your source code into "headers" and conditionally
compile-out function bodies depending on some macro. Or "#define BEGIN
{" so it looks more like Pascal. Think of the sanity of the next guy
who will be maintaining this code. In your example trying to grep the
source files for these globals' definitions won't work anymore; the
meaning of these weird macros is not obvious, etc.

D.
  Réponse avec citation
Vieux 27/02/2008, 22h43   #6
jason.cipriani@gmail.com
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: How to instantiate objects in a public include file

On Feb 27, 2:15 pm, "Ed J" <j...@privacy.net> wrote:
> The object doesn't get defined more than once if the programmer (me) follows
> the rules:
> 1. In ordinary source (.c) files wishing access to the declarations, I
> simply do:
> #include "filename.h"
> 2. In one and only one source file, I define INSTANSTIATE_OBJECTS before
> including the file, and it gives me the declaration and the instantiation:
> #define INSTANTIATE_OBJECTS
> #include "filename.h"


This is -exactly- equivalent to just putting the object declarations
in the header and putting the definition in one of the source files
(the source file you #define INSTANTIATE_OBJECTS in). Except doing it
with precompiler macros is slightly more work than you need to be
doing, and also requires you to explain what you are doing to other
people reading your code (whereas declaring objects as extern,
possibly with a comment like "// defined in file.cpp", is clear and
concise).

> I've used this technique many times on simple uninitialized variables to
> avoid the hassle of maintaining two different source files (the .h and .c)
> with the same object names. A typical xyz.h file would contain something
> like this:


It depends on how you look at it I guess. If you are going by "number
of files" then I guess having a .h file is "better" than having both a
source and a header. If you are going by "lines of code", you are
probably typing more with your preprocessor stuff. Also in either
case, you still have the dependency on a given source file. With your
method, if you remove the source file that #defines
INSTANTIATE_OBJECTS, you have to put that #define somewhere else. With
the other method, you still have to compile the source file with the
definitions into the project -- but at least it's clear that
"globals.cpp" matches "globals.h", rather than you saying "well if
something_unrelated.cpp isn't compiled then the objects declared in
globals.h won't be defined unless you move such and such preprocessor
definition to another arbitrary source file".

Both C and C++ have constructs and mechanisms ("extern", and the
linker) to cleanly and clearly do -precisely- what you are doing with
precompiler macros.

> #if defined( INSTANTIATE_XYZ_OBJECTS )
> #define EXTERN
> #else
> #define EXTERN extern
> #endif
> EXTERN int xyz1;
> EXTERN int xyz2;
>
> That single block of source code serves both the purpose of declaration and
> instantiation of xyz1 and xyz2, depending on whether the including .c file
> first declares INSTANTIATE_XYZ_OBJECTS.


Until somebody sees that you only named it "EXTERN", and starts using
EXTERN as a substitution for the real extern, expecting it to behave
sanely. If you insist on doing it this way instead of just defining
the objects in another source file, at least pick a better macro name
than EXTERN.

> But this technique only works for
> uninitialized variables. I'm trying to find a similar technique for
> initialized variables.


You do it like this:

header.h:

extern int xyz1;
extern int xyz2;

one_source_file.cpp:

int xyz1 = 400;
int xyz2 = 234;

Again, if you insist on doing it with precompiler macros, you would do
this:

extern int xyz1;
extern int xyz2;
#ifdef INSTANTIATE_XYZ_OBJECTS
int xyz1 = 400;
int xyz2 = 234;
#endif

Having the declaration and definition in the same source file won't
cause any problems, there is no need to put the "extern int"
declarations in an #else block. But again, since you are only
#defining INSTANTIATE_XYZ_OBJECTS in a single source file before
#including that header, you don't have to bother with the preprocessor
at all -- just put the definitions right in that source file.

> Editorial... It is a pet peeve of mine that the C and C++ languages require
> me to create two source code lines (one in a .c file, and one in a .h file)
> associated with the same object name. Simply put, one source code line is
> easier to maintain than two source code lines, especially when those two
> source code lines must, by edict of C/C++, reside in separate files. That's
> edict is a maintenance hassle that I would gladly circumvent if I knew how.


The reason for this is that you need to have the declaration of an
object available so that the compiler knows it exists, and thus knows
the type of it and can compile your code. However, the object itself
is only defined in one translation unit. Declaration and definition
are two separate concepts. There is no other alternative. Let's say
that "declarations" didn't exist and you had to define everything
everywhere. What happens if you put:

int i = 3;

In a header, and that serves as both declaration and definition? Then
you compile multiple source files that use it. Then you change it to:

int i = 4;

And recompile only some of the source files. Or if it is a variable,
such as errno, that is defined in a library elsewhere (where you have
no control over the initialization of it -- yet you would still be
"initializing" it to a certain value in errno.h). A situation like
that would become a maintenance nightmare.

You are already running into a situation where you have to maintain a
separate declaration and definition for variables (you have to do this
with functions, too -- you have to have *some* way of saying "this
function exists" without repeating the code for it in every header you
use it in). As you can see, it actually *is* useful to have separate
declarations and definitions -- this completely solves your problem of
wanting to use initialized data in multiple source files. You may want
to consider removing that pet peeve from your list of pet peeves!

> Any ideas?


So what it comes down to is: use the language features that are
already in place for doing exactly what you are trying to do. Declare
variables, as extern, in headers, define them in a single source file,
and don't use the preprocessor to emulate a feature that the language
already has.

Jason
  Réponse avec citation
Réponse


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are oui
Pingbacks are oui
Refbacks are oui


Fuseau horaire GMT +1. Il est actuellement 06h34.


Édité par : vBulletin® version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5 Tous droits réservés.
Version française #16 par l'association vBulletin francophone
PHWinfo est un site Éducation Sans Frontières ©2000-2008
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,18851 seconds with 14 queries