Access the main() from an instantiated class

Pages: 12
This is the Main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include <sstream>
#include <cstdlib>
#include <string>
#include <vector>
#include "include/object.h"
#include "include/animal.h"


using namespace std;

vector<CObject> Obj;


CObject Key ("Collar", );
CObject Chain ("Chain", );
Cobject Bell ("Bell")

int Stable=0;

Animal sheep ("Snow", "Sheep", 1);
string myName=sheep.getName();
Animal dog ("Lassie", "dog", 1);
string dogName=dog.getName();

vector<Animal> animalList;

int main()
{
    bool running=true;
    //Obj and other vector must be initialized, first, then push the object
    Obj.push_back(Key);
    Obj.push_back(Gold);

    animalList.push_back(sheep);
    animalList.push_back(dog);

    system("CLS");
    cout << "The " sheep.type << " name is: " << sheep.getName << endl;
    cout << "The " dog.type << " name is: " << dog.getName << endl;
    return 0;
}


the animal.h class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <iostream>
#include <vector>
#include <string>

using namespace std;

extern vector<int> Obj; // doesn't work conflicting declaration 'std::vector<CObject> Obj'
/*here a would like to access the object created in main (vector<CObject> Obj;), iterate through it and modifying the values, adding or removing elements.
Many suggested to avoid using globals */

struct Object {
        string name;
        string type;
        int status;
};

class Animal{

  public:
    string _name;
    string _type;
    int _inStable, _status=0;

    vector<int> objects;
    Animal (string, string, int);

    string getName () {return (_name);}
    void addObject(string objName);
    void removeObject(string name);

};

void Animal::addObject(string ObjName) {

//to do

}

void Animal::removeObject(string name){

//to do
}

Animal::Animal(string name, string type, int status) {

  _name = name;
  _type = type;
  _status = status;

}


The object class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <vector>
#include <string>


using namespace std;

class CObject{

  public:
    string _name;
    string _type;
    int _status;

    CObject (string, string, int);
    string getName () {return (_name);}
    void setName(string nm) { _name=nm;}

    int getStatus() { return _status;}
    void setStatus (int sts){
        _status=sts;
    }

};


CObject::CObject (string name, string type, int status) {

    _name=name;
    _type=type;
    _status=status;

}


It should be obvious why extern vector<int> Obj; is generating an error - you've already defined Obj to be a vector of CObject, not a vector of int.

In any case, using global variables is generally a bad habit, that can lead to problems when you start writing bigger programs. As more than one person has already suggested:

pass that vector to the class as an argument to the constructor
Since i've got many suggestions to access a global variable from a class using the declaration:
extern vector<int> Obj;

Btw, having declared the Obj as a vector of CObject, what i have to pass to the constructor of the function?

Something like this?

Animal sheep (Obj,"Snow", "Sheep, 0);

moreover, the line 25 of the animal.h should be modified as

Animal (vector<CObject>, string, string, int);

instead of

Animal (string, string, int);

and the line 44 as follow

Animal::Animal(vector<CObject> my_vector, string name, string type, int status);

instead of

Animal::Animal(string name, string type, int status)

If i do this way i get:

error: redefinition of 'class CObject'
error: previous definition of 'class CObject'





Last edited on
Since i've got many suggestions to access a global variable from a class using the declaration:
extern vector<int> Obj;

Um, no. You were shown an example of doing a similar kind of thing, and that example used a vector of int. Nobody told you that a vector of int was what you should use in your program.

If you're just copying and pasting code into your program without understanding what it does and hoping it will magically work, then you are making a big mistake. You won't actually learn anything, and you'll probably end up breaking your program.

The code changes you show for the constructor of the Animal class look fine to me. Those errors look as though you haven't put multiple inclusion guards in the header that defines the CObject class. Either that, or there's some other reason you have CObject defined twice in the same translation unit.
I haven't tried yet to eliminate the Global vars.

Thank you for the suggestions.
@MikeyBoy

as you predicted, I did not use any include guards.

Now i'm trying to get rid of global variables.

When i try to pass "that vector to the class as an argument to the constructor" the class Animal should know what a vector<CObject> is, right?

for this reason i include the "object.h" in the include section @ line 4 of animal.h

i can now declare:

Animal (vector<CObject>, string, string, int);

I have to understand, at this point, where i need to add the include guards as you suggested.

Thank you
Last edited on
When i try to pass "that vector to the class as an argument to the constructor" the class Animal should know what a vector<CObject> is, right?

for this reason i include the "object.h" in the include section @ line 4 of animal.h

Yes, that's correct.

i can now declare:

Animal (vector<CObject>, string, string, int);

You can do it that way, but then you'll be passing in the entire vector by value, which may cause you to be unnecessarily creating copies of the vector. To ensure that you're not copying the entire vector, you can pass by const reference, instead:

 
Animal (const vector<CObject>&, string, string, int);

I have to understand, at this point, where i need to add the include guards as you suggested.

It's rarely a good idea to get creative with include guards. Just use them in exactly the same way as they're used in any other header file, unless you have a very good reason not to.
Last edited on
Thank you for the reply.

I started using your suggestions (and suggestion by other user of this forum) and really it's going better (especially about the globals var and so on...)

Just about the Global, it's a bad practice to declare Static vector<CObject> Obj. This will be visible to the main source only and could avoid to pass the vector to every function it's needed.

Moreover, the same rule to avoid Globals, should be applied to ENUM?
Just about the Global, it's a bad practice to declare Static vector<CObject> Obj. This will be visible to the main source only and could avoid to pass the vector to every function it's needed.

Well, if you want your file-scope variable to be a global variable, accessible from other files then, yes, you're right.

Moreover, the same rule to avoid Globals, should be applied to ENUM?

Why would there be something wrong with using enum. ?
Last edited on
Well, if you want your file-scope variable to be a global variable, accessible from other files then, yes, you're right.


In this case i want to make static vector visible only in the actual source file, in order to avoid passing the vector to various function: is this a bad practice?

Why would there be something wrong with using enum. ?


Just asking for this, cause i read some questions about this in some forum and i would like to know your opinion.
In this case i want to make static vector visible only in the actual source file, in order to avoid passing the vector to various function: is this a bad practice?

Defining the vector as static stops it being visible at global scope in other files.

It won't stop you being able to pass it to other functions, even if those functions are defined in other files.

I wouldn't say it's bad practice, but it's the C-style way of doing it. The C++ style way would be to define it in an anonymous namespace.

Just asking for this, cause i read some questions about this in some forum and i would like to know your opinion.

Really? I'm not aware of any reason why it might be bad practice to use an enum. Can you point me to those discussions where this was suggested?

Um, those discussions all seem to be discussing different, specific issues. I don't see anything there that suggests you should avoid using enums. Can you clarify exactly what is you're asking?
Since i've learned to avoid Global vars as much as possible, i asked myself if the enum are considered the same way. Having done a quick search i've noticed that someone asked if it's correct to put the enum in a unique Global enum file (like this one http://programmers.stackexchange.com/questions/178733/is-it-a-bad-practice-to-include-all-the-enums-in-one-file-and-use-it-in-multiple) or this (do-enum-values-behave-like-global-variables)?

Thank you

You should avoid global variables of any type, whether they're enums, or any other type.

That discussion you've linked to is not about global variables. It's about defining the enum types, not defining variables.
Last edited on
MikeyBoy wrote:
You should avoid global variables of any type, whether they're enums, or any other type.
But enums are not variables, they are constants.

The reason to avoid global variables is the lack of control. Global constants are ok since there is noting harmful you can do with them.
But enums are not variables, they are constants.

The reason to avoid global variables is the lack of control. Global constants are ok since there is noting harmful you can do with them.

My advice was about not using global variables, including global variables whose type is an enum.

I wasn't saying that one shouldn't define the enum types themselves in global scope.
Thank you for the help.

I will soon open a new thread for other questions :P

Topic archived. No new replies allowed.
Pages: 12