1

I know that C++ also allows to create global objects of class and struct.

#include <iostream>
using std::cout;
class Test
{
    public:
        void fun()
        {
            cout<<"a= "<<a;
        }
    private:
        int a=9;
};
Test t;  // global object
int main()
{
    t.fun();
    return 0;
}

When & where should i use global objects? Is there any specific use of global objects? Please help me.

Martin Ba
  • 37,187
  • 33
  • 183
  • 337
Destructor
  • 14,123
  • 11
  • 61
  • 126

4 Answers4

6

The short answer is there is no need.


The long answer is that it can sometimes be convenient. Unfortunately convenience is subjective, and what one finds to convenient another might find to be too lenient.

Global objects have issues (among which muddying data flows in the code and access synchronization), but sometimes one might find it convenient nonetheless to use one because it makes something easier. It can indeed remain easier, or it can prove a maintenance burden, but that only the future can tell...

... If you can avoid global objects, in general you should be better off. In practice, though, you will rarely encounter issues before programming at scale; for toy examples and students' projects there is rarely an issue, which is why beginners fail to understand why more seasoned developers avoid them like the plague.

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
  • 3
    `std::cout` has certainly proved useful. – Lightness Races in Orbit Oct 19 '14 at 18:04
  • @LightnessRacesinOrbit I think, the idea is, it does not need to be a global, but could be a singleton class. Although I do not see much difference, tbh. – luk32 Oct 19 '14 at 18:10
  • @luk32: No, the idea is that it is not *necessary* for it to be global. It is however *convenient*, which is why most logging framework end up using global objects. – Matthieu M. Oct 19 '14 at 18:23
  • @MatthieuM. Ok, then I am a little stupid. Would you care to explain how else one could obtain a handle of standard output or interact with it? Or just point to some read. EDIT: Ok, with below, I got it. – luk32 Oct 19 '14 at 18:27
  • 1
    @LightnessRacesinOrbit: It is convenient, but is it necessary that it be unique? There are issues with the buffered nature of `std::cout` for example, which [`sync_with_stdio`](http://en.cppreference.com/w/cpp/io/ios_base/sync_with_stdio) is proof of, and the various proposals for explicit controls of buffering behaviors are also proof of (using `std::cout` from multiple threads requires synchronization to avoid tangled output). There are other ways the functionality could have been exposed (such as passing a reference to an `Environment` object to `main`); but it is convenient. – Matthieu M. Oct 19 '14 at 18:28
  • @luk32: Expose an `Environment&` to `main`, which has to be thread down every single function? Not very practical, but feasible. – Matthieu M. Oct 19 '14 at 18:29
0

In a complex project, you shouldn't. You should always be within a namespace if you plan to use you're assembly in other projects.

An example of something that might be that high in scope is an operator overload or an interface that you define which will be used many times.

Good practice...organize your project to use descriptive and intuitive namespaces.

Global is really only useful in simple project that simple don't use namespaces.

Russell Trahan
  • 783
  • 4
  • 34
  • 7
    namespace-scope is still global. Just not global *-scope*. – Columbo Oct 19 '14 at 17:30
  • My point was 'Test T' should be within a namespace that describes its allocation, use, meaning, etc. unless it is an interface that describes itself. – Russell Trahan Oct 19 '14 at 17:32
  • @Loopunroller I'm sorry but I feel that defining namespace scope as global is either too much a generalization, or simply a mistake. For one, namespaces do not have to be defined in global scope. – Nard Oct 19 '14 at 17:41
  • Unless you're arguing semantics, I think @Loopunroller hits the nail on the head: whether in a namespace or not, an initterm object still suffers from all the synchronization, isolation, ordering and maintenance issues. – Cygon Oct 19 '14 at 18:01
0

The question is malposed: is there a need for if wile and do, since we can do all with just for ?

The technical answer is "no, there is no need: the fact we can do without proves it". But a little more pragmatism show us that reducing every control flow into a single keywork makes code harder to track and follow. So it is technically possible but not always convenient.

Now: can we do without global objects?

A first non-answer is "yes, with singletons". But a singleton is a static object obtained through a function. They are not that conceptually different if not for a design flaw (known as "static initialization order fiasco") due to C++ not specifying global initialization object order essentially to allow multiple translation unit to coexist in a same linked executable. Singleton allow to circumvent that problem, but are essentially a workaround to allow global "things" to exist.

The existence of that flaw (and the singleton technique) is wat makes many "teachers" to draw some "moral" suasion like "never use global objects, or the flame of hell will burn your ass-hair". But that soon do std::cout << "hello world" and immediately loose ALL their credibility.

The point is that without "globals" everything is "scope local" and there is no "dynamic scope" in C++: if funcA calls funcB, funcB cannot see funcA locals, hence the only way to access things across scopes is parameter passing of reference or pointers.

In context which are mostly "functional", the missing of "dynamic scopes" is compensated by "lamba captures", and everything else will go as paramenter.

In context which are mostly "procedural", the need of a "state" that survives scopes and can be modified while going in and out is more suited for global objects. And that's the reason cout is that. It represent a resource theat pre-exist and post-exist the program, whose state evolves across various calls. If there is no global way to access cout, it should be initialized in main, an passed as a reference parameter to whatever function call: even the one that have no output to give, since they may call themselves something else that has output to give.

In fact you can think to global object as "implicit parameters passed to every function".

You can warp in global functions but -if functions themselves can be objects and object themselves can be functional- why saying global objects are bad and global functions can be right?

The actual only reason, in fact, turns out to be the static initialization order fiasco

Josh Crozier
  • 233,099
  • 56
  • 391
  • 304
Emilio Garavaglia
  • 20,229
  • 2
  • 46
  • 63
-1

I would say that global variables are needed for backwards compatibility with c. That is for sure, and this is the only hard reason I see. Since classes and structs are essentially the same, it probably didn't make much sense in forbidding only one.

I don't know any patterns or use-cases that are universally accepted as a good practice, that would make use of global objects. Usually global objects, sooner or later, lead to mess if not interacted with properly. They hide data flow and relationships. It is extremely easily to trip over it.

Still, I have seen some libraries exposing some objects as globals. Usually things that contain some static data. But there are other cases too, notable example being standard library's std::cout and family.

I won't judge if it's good or bad approach. This is too subjective IMO. You could probably use singletons, but one might argue, you can work on a global object under a contract etc. etc.

luk32
  • 15,812
  • 38
  • 62
  • I am not sure how my answer is not useful, as it is the only one, giving a technical reason. But I would gladly improve it if given any hints. – luk32 Oct 19 '14 at 18:11