Thread: c++: how accessing a class instances, on array way, using the class name?

  1. #1
    Registered User
    Join Date
    Aug 2013
    Posts
    451

    c++: how accessing a class instances, on array way, using the class name?

    we have a new class. i can calculate the number of instances\objects using a static variable, on constructor.
    but using an array, how can i get it's values?

    Code:
    #include <iostream>
    #include <string>
    #include <string.h>
    
    using namespace std;
    
    class test1
    {
    private:
    
       static int stcintCount;
    public:
       string a;
         test1()
        {
           stcintCount++;
           a=to_string(stcintCount);
        }
    
        test1 operator[](int index)
        {
            this[index];
        }
    };
    int test1::stcintCount=-1;
    
    test1 tstCount;
    test1 tstCount1;
    test1 tstCount2;
    
    int main()
    {
    
      for(int i=0; i<3;i++)
          cout << test1[i].a;
      return 0;
    }
    i'm testing the code but i'm getting problems
    my objective is accessing the instances values in these way... using the class name.

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You can only access static variables by the way of using the class name, e.g.: test1::stcintCount (assuming it's public). All other variables are bound to an instance of a class.
    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.

  3. #3
    Registered User
    Join Date
    Aug 2013
    Posts
    451
    Quote Originally Posted by Elysia View Post
    You can only access static variables by the way of using the class name, e.g.: test1::stcintCount (assuming it's public). All other variables are bound to an instance of a class.
    now the code works:
    Code:
    #include <iostream>
    #include <string>
    #include <string.h>
    
    using namespace std;
    
    class test1
    {
    private:
    
    public:
       static int stcintCount;
       string a;
        test1()
        {
           stcintCount++;
           a=to_string(stcintCount);
        }
    
        test1 &operator[](int index)
        {
            return this[index];
        }
    };
    int test1::stcintCount=-1;
    
    test1 tstCount;
    test1 tstCount1;
    test1 tstCount2;
    
    int main()
    {
    
      for(int i=0; i<=tstCount.stcintCount;i++)
          cout << tstCount[i].a;
      return 0;
    }
    but i see 2 problems:
    1 - i can only use the instance name, instead class name;
    2 - if i add another variable type between tstCount1 and tstCount, i will get memory problems(memory leaks or something).
    see my real objective: i have a form class, that create forms(application windows). instead use win32 cycle, i coud use in these way, for get it's values(width, caption, text and much more).
    what you can tell me more?

  4. #4
    Registered User
    Join Date
    Aug 2013
    Posts
    451
    finally i put it to work:
    Code:
    #include <iostream>
    #include <string>
    #include <string.h>
    #include <vector>
    
    using namespace std;
    
    class test1
    {
    private:
    
    public:
       static int stcintCount;
       static vector<void*> vdTest1;
       string a;
        test1()
        {
           stcintCount++;
           vdTest1.push_back(static_cast<void*>(this));
           a=to_string(stcintCount);
        }
    
        test1 &operator[](unsigned int index)
        {
            test1 *tstTest;
            tstTest=static_cast<test1*>(vdTest1[index]);
            return *tstTest;
        }
    };
    int test1::stcintCount=-1;
    vector<void*> test1::vdTest1;
    
    test1 tstCount1;
    test1 tstCount[4];
    
    int main()
    {
    
      for(int i=0; i<4;i++)
          cout << tstCount[i].a;
        //cout << strName;
      return 0;
    }
    output:
    1234

    another sample:
    Code:
    test1 tstCount1;
    test1 tstCount[4];
    
    int main()
    {
    
      for(int i=0; i<=tstCount1.stcintCount;i++)
          cout << tstCount1[i].a;
        //cout << strName;
      return 0;
    }
    output:
    01234
    using a void* vector, i can save all instances pointers
    now i can do what i need, except use the class name
    but it's cool. thanks for all

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    What exactly are you trying to achieve?
    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

  6. #6
    Registered User
    Join Date
    Aug 2013
    Posts
    451
    Quote Originally Posted by laserlight View Post
    What exactly are you trying to achieve?
    think in these way: imagine that you have a class, button, for create buttons, on form. now by some reason you need to know their caption(for exemple) using a for cycle.
    Code:
    for(int i=0; i<button.count(); i++)
            cout << button[i].caption();
    but, by C\C++ rules, i can't use the class name, but only the instance name

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by joaquim
    think in these way: imagine that you have a class, button, for create buttons, on form. now by some reason you need to know their caption(for exemple) using a for cycle.
    Create the buttons in a container, then loop over that container.
    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
    Aug 2013
    Posts
    451
    Quote Originally Posted by laserlight View Post
    Create the buttons in a container, then loop over that container.
    sorry. that class avoid me creating the container
    my problem is that i must use an instance name, instead the class name.

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by joaquim
    that class avoid me creating the container
    You cannot avoid creating the container. If you really want to keep track of all the objects such that you could access them via static member functions of the class, maybe something like this would work:
    Code:
    #include <iostream>
    #include <string>
    #include <unordered_set>
    
    class Button
    {
    public:
        typedef std::unordered_set<const Button*> container_type;
    
        static container_type::const_iterator all_begin()
        {
            return objects.begin();
        }
    
        static container_type::const_iterator all_end()
        {
            return objects.end();
        }
    
        explicit Button(const std::string& caption_) : caption(caption_)
        {
            objects.insert(this);
        }
    
        // Forbid copying:
        Button(const Button& other) = delete;
        void operator=(const Button& other) = delete;
        // Allow moving:
        Button(Button&& other) = default;
        Button& operator=(Button&& other) = default;
    
        ~Button()
        {
            objects.erase(this);
        }
    
        std::string get_caption() const
        {
            return caption;
        }
    private:
        static container_type objects;
    
        std::string caption;
    };
    
    Button::container_type Button::objects;
    
    void print_all_button_captions(std::ostream& out)
    {
        for (auto iter = Button::all_begin(); iter != Button::all_end(); ++iter)
        {
            out << (*iter)->get_caption() << '\n';
        }
    }
    
    int main()
    {
        auto button_x = Button{"Button X"};
        auto button_y = Button{"Button Y"};
        {
            auto button_z = Button{"Button Z"};
            print_all_button_captions(std::cout);
        }
        std::cout << "--------" << std::endl;
        print_all_button_captions(std::cout);
    }
    Last edited by laserlight; 01-31-2016 at 09:21 AM.
    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

  10. #10
    Registered User
    Join Date
    Aug 2013
    Posts
    451
    Quote Originally Posted by laserlight View Post
    You cannot avoid creating the container. If you really want to keep track of all the objects such that you could access them via static member functions of the class, maybe something like this would work:
    Code:
    #include <iostream>
    #include <string>
    #include <unordered_set>
    
    class Button
    {
    public:
        typedef std::unordered_set<const Button*> container_type;
    
        static container_type::const_iterator all_begin()
        {
            return objects.begin();
        }
    
        static container_type::const_iterator all_end()
        {
            return objects.end();
        }
    
        explicit Button(const std::string& caption_) : caption(caption_)
        {
            objects.insert(this);
        }
    
        // Forbid copying:
        Button(const Button& other) = delete;
        void operator=(const Button& other) = delete;
        // Allow moving:
        Button(Button&& other) = default;
        Button& operator=(Button&& other) = default;
    
        ~Button()
        {
            objects.erase(this);
        }
    
        std::string get_caption() const
        {
            return caption;
        }
    private:
        static container_type objects;
    
        std::string caption;
    };
    
    Button::container_type Button::objects;
    
    void print_all_button_captions(std::ostream& out)
    {
        for (auto iter = Button::all_begin(); iter != Button::all_end(); ++iter)
        {
            out << (*iter)->get_caption() << '\n';
        }
    }
    
    int main()
    {
        auto button_x = Button{"Button X"};
        auto button_y = Button{"Button Y"};
        {
            auto button_z = Button{"Button Z"};
            print_all_button_captions(std::cout);
        }
        std::cout << "--------" << std::endl;
        print_all_button_captions(std::cout);
    }
    i'm so sorry. but you don't answer on what i mean.
    see my code again:
    Code:
    #include <iostream>
    #include <string>
    #include <string.h>
    #include <vector>
    
    using namespace std;
    
    class test1
    {
    private:
    
    public:
       static int stcintCount;
       static vector<void*> vdTest1;
       string a;
        test1()
        {
           stcintCount++;
           vdTest1.push_back(static_cast<void*>(this));
           a=to_string(stcintCount);
        }
    
        test1 &operator[](unsigned int index)
        {
            test1 *tstTest;
            tstTest=static_cast<test1*>(vdTest1[index]);
            return *tstTest;
        }
    };
    int test1::stcintCount=-1;
    vector<void*> test1::vdTest1;
    
    test1 tstCount1;
    test1 tstCount[4];
    
    int main()
    {
    
      //see the next 2 lines:
      for(int i=0; i<=test1::stcintCount;i++)//i started on -1
          cout << test1[i].a;
        //cout << strName;
      return 0;
    }
    see that 2 lines on for cycle. the compiler give us an error(or errors), because i use the class name(is what i mean)

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by joaquim
    i'm so sorry. but you don't answer on what i mean.
    Did you read my code? I presented a way for which "you have a class, button, for create buttons, on form. now by some reason you need to know their caption(for exemple) using a for cycle" and then using the class name to access two static member functions (Button::all_begin and Button::all_end), you can accomplish this without having to involve the name of any particular instance.

    Quote Originally Posted by joaquim
    see that 2 lines on for cycle. the compiler give us an error(or errors), because i use the class name(is what i mean)
    What you are trying to do is simply impossible: test1 is a class, so test1[i] is invalid syntax. End of story.

    EDIT:
    Note that your vector<void*> member is a container (i.e., you do not actually avoid creating a container), except that it is pointless to store pointers to void when you know for sure that they will point to test1 objects. This is why I used a container of pointers to const Button in my example: the const is because objects that really are const might be created. Furthermore, I used an unordered_map rather than a vector because:
    • It is likely to be more efficient to use a hash table rather than do linear search.
    • Elements could be frequently removed from the start or middle of the container, so a vector is not ideal as such removal takes linear time.

    Also, there is no need for a separate static member to keep track of the number of elements since the container already does that.
    Last edited by laserlight; 01-31-2016 at 01:15 PM.
    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

  12. #12
    Registered User
    Join Date
    Aug 2013
    Posts
    451
    Quote Originally Posted by laserlight View Post
    Did you read my code? I presented a way for which "you have a class, button, for create buttons, on form. now by some reason you need to know their caption(for exemple) using a for cycle" and then using the class name to access two static member functions (Button::all_begin and Button::all_end), you can accomplish this without having to involve the name of any particular instance.


    What you are trying to do is simply impossible: test1 is a class, so test1[i] is invalid syntax. End of story.

    EDIT:
    Note that your vector<void*> member is a container (i.e., you do not actually avoid creating a container), except that it is pointless to store pointers to void when you know for sure that they will point to test1 objects. This is why I used a container of pointers to const Button in my example: the const is because objects that really are const might be created. Furthermore, I used an unordered_map rather than a vector because:
    • It is likely to be more efficient to use a hash table rather than do linear search.
    • Elements could be frequently removed from the start or middle of the container, so a vector is not ideal as such removal takes linear time.

    Also, there is no need for a separate static member to keep track of the number of elements since the container already does that.
    i'm sorry something. thanks for all. and yah i mistake that, i must use test1*, instead void*.... that mistake happened, because i'm thinking that it's a type that don't exists. the class don't exist, but i can use it anyway

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Why would a class allocate an instance of itself?
    By -Adrian in forum C++ Programming
    Replies: 5
    Last Post: 10-05-2014, 03:58 PM
  2. Can't get my class to inheret Collection<T>
    By indigo0086 in forum C# Programming
    Replies: 2
    Last Post: 10-01-2007, 12:27 PM
  3. Declaring an instance of a class inside a class
    By nickodonnell in forum C++ Programming
    Replies: 4
    Last Post: 10-01-2005, 11:46 PM
  4. pointer to an instance of a different class
    By xlix in forum C++ Programming
    Replies: 4
    Last Post: 07-24-2003, 04:19 PM
  5. C++ Class Object Collection
    By Visual Develope in forum C++ Programming
    Replies: 3
    Last Post: 05-04-2002, 04:48 PM