Passing objects around

G

Garma

According to what I have learnt so far, instantiating global objects should
be the last resort. Is there any reasons why so?

Sometimes some objects or their pointers have to be shared among several
other objects, I'd like to know how this is handled commonly. Could someone
elaborate on this?

Another situation is some objects could be shared among several threads.
How to handle it commonly?

Thanks for your comments!
 
V

Victor Bazarov

Garma said:
According to what I have learnt so far, instantiating global objects should
be the last resort. Is there any reasons why so?

Usually because they are accessible to anyone at any time. Dangerous.
Sometimes some objects or their pointers have to be shared among several
other objects, I'd like to know how this is handled commonly. Could someone
elaborate on this?

It depends on what you mean by "shared".

The usual way is 'association' which is done by storing a pointer to
a shared object in an instance of another class. But it can be different
according to requirements.
Another situation is some objects could be shared among several threads.
How to handle it commonly?

If your threads are represented by objects, see above. If not, you should
probably ask in comp.programming.threads since threading is not something
C++ defines and as such tends to be OT here.

Victor
 
C

Cy Edmunds

Garma said:
According to what I have learnt so far, instantiating global objects should
be the last resort. Is there any reasons why so?

Sometimes some objects or their pointers have to be shared among several
other objects, I'd like to know how this is handled commonly. Could someone
elaborate on this?

Another situation is some objects could be shared among several threads.
How to handle it commonly?

Thanks for your comments!

Consider:

int yadda; // global variable

void foo() // set the global
{
yadda = 1;
}

void bar(); // defined elsewhere

int main()
{
foo(); // set yadda to 1
bar(); // does bar change yadda? maybe!
}

All the function bar has to do is declare

extern int yadda;

and it has full read/write access to your global variable. Ouch. Let us
refactor:

void foo(int &yadda) // set the given variable (no globals)
{
yadda = 1;
}

void bar(); // defined elsewhere

int main()
{
int yadda; // local variable rather than global
foo(yadda); // set yadda to 1
bar(); // yadda is still 1 -- bar cannot access it
}

This particular maintainability nightmare can be avoided other ways such as
declaring yadda global in an unnamed namespace, but you can have similar
problems with globals all within the same translation unit -- e.g. another
programmer on your team takes a liking to your global variable and starts
writing values to it, thus introducing bugs into your (not his) code. :p The
advice you have heard about avoiding global variables is quite sound.

I do use them in some cases, however. For instance when writing DLL's I
sometimes find no reasonable alternative for certain operations. I console
myself that my DLL is really just a great big class and the globals within
are analogous to private variables in a real class -- not so terrible when
you think of it that way.
 
E

E. Robert Tisdale

Garma said:
According to what I have learned so far,
instantiating global objects should be the last resort.

No.
Global *constants* are just fine and their use is *encouraged*.
Is there any reasons why so?

Global variables are evil.
Any function can modify a global variable
and you may be obliged to inspect *every* function
to find the one that sets it to an incorrect value.
Sometimes some objects or their pointers
must to be shared among several other objects.
I'd like to know how this is handled commonly.

They must be passed through a function argument list
by value, reference or a pointer to the object.
Pass a const reference or a const pointer
unless the object must be modified "in place".
Otherwise, return an object by value so that
it can be used in an expression or a definition.

class X { /* . . . */ };

X f(void);

const X x = f();
 
M

Martijn Lievaart

According to what I have learnt so far, instantiating global objects should
be the last resort. Is there any reasons why so?

Another reason, apart from what was already mentioned, is order of
initialisation. Globals in one source file are initialised in the order
they are declared, but in what order the source files are initialised is
undefined.

For small projects, you probably could'nt care less, but for larger
programs, this quickly becomes a nightmare.
Sometimes some objects or their pointers have to be shared among several
other objects, I'd like to know how this is handled commonly. Could
someone elaborate on this?

There are many ways, depending on your situation.

1) Redesign. Do you really need it? Is it not just bad design?

2) Ask yourself, what concept does this global represent? Create a class
that represents the concept, never use raw pointers or other values as
globals. Often you'll find you can cluster groups of former globals behind
one interface, using only one global of this new class (also see point 4).

3) Use a singleton. Search google for more info, there are litterally
hunderds of ways how toimplement this in C++.

One way would be:

template<typename T>
class Singleton {
static T& instance() {
static T inst;
return instance;
}
};

Use as follows:

//instantiate as a global:

Singleton<myclass> mysingleton;

// use the object:

void f() {
mysingleton::instance().doSomething();
}

4) Pass around as parameters. Often some (former) globals can be grouped
into one class and a pointer to an object of this class can be passed
around. Obviously these objects should be related and should have been
grouped in a class anyhow. This strongly relates to point 2.

5) If it has to be shared between similar objects, does a common baseclass
help? Maybe containing a static? Or containing a pointer to whatever they
all need access to? Again, think in concepts, not in implementations. A
good concept will (often, not always) spell out the (correct)
implementation.

6) Create one 'god' class that contains all the globals, and only make
that global, or make it a singleton. This is often a sign of bad design,
but...

7) ... call that god class Application and you have a very common
framework setup.

Something I sometimes do (using another form of singleton):

class MyApp {
public:
MyApp();
int run(int argc, char **argv);
static MyApp& instance() { return *inst_; }
// Other member functions here
private:
MyApp *inst_;
// other data members here
};

MyApp::MyApp()
{
assert(!inst_);
inst_ = this;
}

int main(int argc, char **argv)
{
try {
return MyApp().run(argc, argv);
} catch (const ....) {
// lots of error handling here for runaway exceptions
}
}

// somehwere else

void DeepDown::somewhereintheprogram()
{
// how we warn depends on how the program is invoked.
MyApp::instance().emitWarning(...);
...
}
Another situation is some objects could be shared among several threads.
How to handle it commonly?

Use any of the ways given above, but with threads it is even more
important to limit the use of globals. I most often use stack based
objects created somewhere in main or quickly after that, so they stay in
scope for the lifetime of the program. By passing the right arguments to
the threads the threads have pointers to these objects. Obviously these
objects should have ways to synchronize access to them. Also obviously,
you should make sure all subthreads have exited before these objects pass
out of scope.

Whatever you do, in the face of threads you want your accesses to be
tightly controlled. This means wrapping everything in classes that govern
the synchronization for access. Wether this is a global, a singleton or
whatever does not matter. Multi-threaded programming can be hard, but
mainly because programmers don't follow the above advice. If you do it the
way I say here, thread based programming suddenly ceases to be the big
problem it is often said to be! (But note that this is OT for this group!)

HTH,
M4
 
J

jeffc

Garma said:
According to what I have learnt so far, instantiating global objects should
be the last resort. Is there any reasons why so?

I wouldn't say that exactly. In small programs, it's often a first resort.
Sometimes some objects or their pointers have to be shared among several
other objects, I'd like to know how this is handled commonly. Could someone
elaborate on this?

It could be global, if that's appropriate. Other solutions include putting
them in some other object, putting them in a namespace, adding public
functions to access them, or specifying friends to access them.
Another situation is some objects could be shared among several threads.
How to handle it commonly?

That is more likely going to be a problem related to your specific
environment, and you should ask on the specific newsgroup.
 
J

Jorge Rivera

Martijn said:
3) Use a singleton. Search google for more info, there are litterally
hunderds of ways how toimplement this in C++.

One way would be:

template<typename T>
class Singleton {
static T& instance() {
static T inst;
return instance;
}
};

Use as follows:

//instantiate as a global:

Singleton<myclass> mysingleton;

I have a problem with this singleton approach, in that anybdy can still
create other instances of myclass. If he really needs the existance of
exactly one element of a particular class, then it is better for him to
design his class a singleton, not use the template collaboration.

NOTE: If all he wants is a global instance, ignore the design comments,
the template will work...
 
M

Martijn Lievaart

I have a problem with this singleton approach, in that anybdy can still
create other instances of myclass. If he really needs the existance of
exactly one element of a particular class, then it is better for him to
design his class a singleton, not use the template collaboration.

Absolutely, yet all singleton designs I've seen in C++ have
drawbacks/problems. Not that this is the best design, I choose it on
simplicity.

Creating a singleton in C++, one could write a thesis on the subject.
There is no one solution.

M4
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top