Thread: Can I not reference another class within a class?

  1. #1
    Registered User
    Join Date
    Dec 2007
    Location
    Rochester
    Posts
    40

    Can I not reference another class within a class?

    I'm having some trouble with classes...again. I just can't seem to get my head around them.

    I made a class for the player, and classes for the weapons, armor, items, etc that he will use, but everytime I reference the instance of the class for the particular item, It says that I haven't defined it. I make sure that I have all the necessary instances defined in the same function, but it still didn't work. Here is some sample code:

    Code:
    #include <iostream>
    
    using namespace std;
    
    class item {
        public:
        item () {}
        ~item () {}
        void use ( void ) {
            cout << "This item is pretty cool";
        }
    };
    
    class person {
        public:
        person(){}
        ~person(){}
        void useone ( void ) {
            cout << "Hello World\n";
            item1.use(); //ERROR: 'item1' undeclared (first use this function)
        }
    };
    
    int main()
    {
        item item1;
        person bob;
        bob.useone();
        cout << "Did it fail?";
        cin.get();
    }

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    A member function is not going to be able to access variables from the main function, only from the class itself. Now if item item1; were declared in person (so that every person had an item "inside" him), then it would work.

  3. #3
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    You need an item member variable of type item named item1, or perhaps a variable local to useone() named item1.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    All functions can access variables declared within its own scope, the class scope (if it's a class), which is essentially all class member variables, and lastly all global variables.
    It cannot access variables declared within another function which is what your code does. item1 is declared in main.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Registered User
    Join Date
    Dec 2007
    Location
    Rochester
    Posts
    40
    Quote Originally Posted by tabstop View Post
    A member function is not going to be able to access variables from the main function, only from the class itself. Now if item item1; were declared in person (so that every person had an item "inside" him), then it would work.
    So make a class within a class?

  6. #6
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    a more logical approach would be to pass a reference of the item to bob
    Code:
    ...
    void useone ( item &item_to_use ) {
            cout << "Hello World\n";
            item_to_use.use();
    }
    ... //in main
    bob.useone(item1);
    ...
    btw, it is conventional to capitalize the first letter of names of classes. eg. Item, Person.

    names of objects (instances) should be all in lowercase like you have done.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    So make a class within a class?
    Not quite. Here is one approach, using a member variable:
    Code:
    #include <iostream>
    
    using namespace std;
    
    class item {
    public:
        void use() {
            cout << "This item is pretty cool";
        }
    };
    
    class person {
    public:
        person(const item& new_item) : item1(new_item) {}
        void useone() {
            cout << "Hello World\n";
            item1.use();
        }
    private:
        item item1;
    };
    
    int main()
    {
        item item1;
        person bob(item1);
        bob.useone();
        cout << "Did it fail?";
        cin.get();
    }
    Here's another approach, using a local variable that is actually an argument to the member function:
    Code:
    #include <iostream>
    
    using namespace std;
    
    class item {
    public:
        void use() {
            cout << "This item is pretty cool";
        }
    };
    
    class person {
    public:
        void useone(const item& item1) {
            cout << "Hello World\n";
            item1.use();
        }
    };
    
    int main()
    {
        item item1;
        person bob;
        bob.useone(item1);
        cout << "Did it fail?";
        cin.get();
    }
    btw, it is conventional to capitalize the first letter of names of classes. eg. Item, Person.
    I like to do that, but it is only one convention. For example, the C++ standard does not do that.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User
    Join Date
    Dec 2007
    Location
    Rochester
    Posts
    40
    Yeah, that sounds more convienient to me as well, since I don't have to pass a whole bunch of variable around individually to make everything work the way i want it to. I'll read up on it.

  9. #9
    Registered User
    Join Date
    Dec 2007
    Location
    Rochester
    Posts
    40
    Code:
    person(const item& new_item) : item1(new_item) {}
    I don't quite understand how this part works^.
    I know that it is part of an initialization list, but how does that work to set up a bunch of variables?

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I know that it is part of an initialization list, but how does that work to set up a bunch of variables?
    If you are talking about the syntax to initialise more than one member variable, it would be:
    Code:
    person(const item& new_item1, const item& new_item2) : item1(new_item1), item2(new_item2) {}
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    Registered User
    Join Date
    Dec 2007
    Location
    Rochester
    Posts
    40
    [QUOTE=laserlight;703970]Not quite. Here is one approach, using a member variable:
    Code:
    #include <iostream>
    
    using namespace std;
    
    class item {
    public:
        void use() {
            cout << "This item is pretty cool";
        }
    };
    
    class person {
    public:
        person(const item& new_item) : item1(new_item) {}
        void useone() {
            cout << "Hello World\n";
            item1.use();
        }
    private:
        item item1;
    };
    
    int main()
    {
        item item1;
        person bob(item1);
        bob.useone();
        cout << "Did it fail?";
        cin.get();
    }
    I think that this is the best option for what I'm trying to do, but I tried to implement it and it didn't quite work. I don't think i quite understand how it works. What are the important parts of the referencing?

    When I use it in my main code, it complains about weapon::weapon() not being a candidate and it lists off weapon::weapon ( weapon& ) or weapon::weapon (/*name of weapon and long list of integers used for setting up weapon at beginning*/)

    Here is the creator for the player class

    Code:
        player ( const weapon& new_weapon1, const weapon& new_weapon2, const weapon& new_weapon3,
                 const armor& new_armor ) : weap1(new_weap1), weap2(new_weap2), weap3(new_weap3),
                 armorused(new_armor) {/*user choses his stat amounts*/}
    Here is the creator for the weapon class

    Code:
    weapon ( string name, int itemtype, int piercepwrl, int piercepwrh,
                 int bluntpwrl, int bluntpwrh, int firepwrl, int firepwrh,
                 int durability, int durabilitydmg, int clean, int cleandmg,
                 int rateoffire, int range, int clipsize, int leftinclip, int ammo,
                 int autoreload, int infiniteammo) { /*whole bunch of stuff*/ }
    my compiler also complains about 'new_weapon1', etc. not being defined.

    I don't understand why all these errors are now coming up when none of this happened with the sample code.

  12. #12
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    check your spelling
    parameter name is new_weapon1
    but argument passed as a parameter to weap1(new_weap1) has another name
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  13. #13
    Registered User
    Join Date
    Dec 2007
    Location
    Rochester
    Posts
    40
    That fixed the problem with 'new_weapon1' not being defined, but the other problems still occur

  14. #14
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    When I use it in my main code, it complains about weapon::weapon() not being a candidate and it lists off weapon::weapon ( weapon& ) or weapon::weapon (/*name of weapon and long list of integers used for setting up weapon at beginning*/)
    Once you have defined a constructor for a class, its default constructor is no longer automatically provided for you by the compiler. You have to provide the default constructor yourself if you need it.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  15. #15
    Registered User
    Join Date
    Dec 2007
    Location
    Rochester
    Posts
    40
    ok, that makes sense. thanks.

    But just one last question...If I'm referencing a class that is elsewhere, why do I have to construct the class as if i'm making a new one?


    also, there is now yet another problem that I can't explain...what a surprise
    My compiler returns this and a whole bunch of alternatives that I can't even begin to decipher

    main.cpp:472: error: no match for 'operator<<' in 'std::cout << ((weapon*)this)->weapon::namecentered(20)'

    for this code

    Code:
            cout<< "+----------------------+----------------------+----------------------+----------------------+\n";
            cout<< "|                         Please select your weapon of destruction                          |\n";
            cout<< "+----------------------+----------------------+----------------------+----------------------+\n";
            cout<< "|       Option #       |          1.          |          2.          |          3.          |\n";
            cout<< "|     Weapon Name      | " << weap1.namecentered(20) << " | " << weap2.namecentered(20) << " | " << weap3.namecentered(20) << " |\n";
            cout<< "| Piercing Damage High | " << weap1.statfilled(20, 1)<< " | " << weap2.statfilled(20, 1)<< " | " << weap3.statfilled(20, 1)<< " |\n";
            cout<< "| Piercing Damage Low  | " << weap1.statfilled(20, 2)<< " | " << weap2.statfilled(20, 2)<< " | " << weap3.statfilled(20, 2)<< " |\n";
            cout<< "|   Blunt Damage Low   | " << weap1.statfilled(20, 3)<< " | " << weap2.statfilled(20, 3)<< " | " << weap3.statfilled(20, 3)<< " |\n";
            cout<< "|   Blunt Damage Low   | " << weap1.statfilled(20, 4)<< " | " << weap2.statfilled(20, 4)<< " | " << weap3.statfilled(20, 4)<< " |\n";
            cout<< "|    Fire Damage Low   | " << weap1.statfilled(20, 5)<< " | " << weap2.statfilled(20, 5)<< " | " << weap3.statfilled(20, 5)<< " |\n";
            cout<< "|   Fire Damage High   | " << weap1.statfilled(20, 6)<< " | " << weap2.statfilled(20, 6)<< " | " << weap3.statfilled(20, 6)<< " |\n";
            cout<< "|      Durability      | " << weap1.statfilled(20, 7)<< " | " << weap2.statfilled(20, 7)<< " | " << weap3.statfilled(20, 7)<< " |\n";
            cout<< "|     Left in Clip     | " << weap1.statfilled(20, 8)<< " | " << weap2.statfilled(20, 8)<< " | " << weap3.statfilled(20, 8)<< " |\n";
            cout<< "|      Clip Size       | " << weap1.statfilled(20, 9)<< " | " << weap2.statfilled(20, 9)<< " | " << weap3.statfilled(20, 9)<< " |\n";
            cout<< "|      Store Ammo      | " << weap1.statfilled(20, 10)<< " | " << weap2.statfilled(20, 10)<< " | " << weap3.statfilled(20, 10)<< " |\n";
            cout<< "+----------------------+----------------------+----------------------+----------------------+\n\n";
    it says that message for the first two that include my function, but it displays such a long list of alternatives that I think it may have just run out of room

    These functions are both within the weapon class

    Code:
    void statfilled ( int gap, int stat )//displays the indicated stat to completely fill the gap indicated
    Code:
    void namecentered ( int gap )//displays the name of the weapon centered within the gap indicated

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 05-13-2011, 08:28 AM
  2. Textbox
    By maxorator in forum Windows Programming
    Replies: 20
    Last Post: 09-25-2005, 10:04 AM
  3. How to: Use OpenGL with Jgrasp
    By Pickels in forum Game Programming
    Replies: 3
    Last Post: 08-30-2005, 10:37 AM
  4. Replies: 10
    Last Post: 06-05-2004, 07:40 PM
  5. structure vs class
    By sana in forum C++ Programming
    Replies: 13
    Last Post: 12-02-2002, 07:18 AM