Search code examples
c++arraysobjectmembersubobject

Arrays and Classes?


I am new to C++ and working on a project where I have array of instances of a class, and within that class I have a struct that within that I have a function. How do I use that function within my main code block. I tried

class artwork {
    struct art {
        // the struct art contains important information such as artist, title and medium. 
    private:
        string artist;
    public:
        void setArtist(string values);
        string getArtist();
    };

    void artwork::art::setArtist(string values) {
        artist = values;
    }

int main (){
    artwork myartwork[500];
    for (int i = 0; i < 500; i++) {

        ///-----------------------------------
        ///-----------------------------------
        // below is where the error occurs? How do I reference setArtist?
        ///-----------------------------------
        ///-----------------------------------

        cout << myartwork[0].art.setArtist("Tim");
    }
    system("pause");
    return 0;
}

Solution

  • Several things need to change here:

    1. class artwork needs a member variable of type art
    2. That member variable needs to be made public
    3. The member variable needs to have a name different than the art, because that already names the type of the struct
    4. You need a closing curly brace and semicolon for artwork

    Your code should probably resolve to something like this:

    class artwork {
    public:
        struct art {
        private:
            string artist;
        public:
            void setArtist(string values){artist = values;}
            string getArtist(){return artist;}
        } art_;
    };
    
    int main (){
        artwork myartwork[500];
         for(int i = 0; i < 500; i++) {
             myartwork[i].art_.setArtist("Tim");
             cout << myartwork[i].art_.getArtist();
    
         }
    }
    

    Other helpful tips:

    1. Pass objects by reference
    2. Initialize in constructors rather than with initialization methods
    3. Prefer to do assignment initialization to a constructor for data agregation types
    4. Loop against array size not magic numbers
    5. Make getters return by const reference
    6. Make methods that cannot change the state of the object const
    7. Make members that do not change for the lifetime of the object const

    EDIT:

    Think of your class definition as the blueprint and the member as the actual object. If we wanted an artwork that had multiple art objects, in the case of a collaboration perhaps, then we could do this:

    class artwork {
    public:
        struct art {
        private:
            string artist;
        public:
            void setArtist(string values){artist = values;}
            string getArtist(){return artist;}
        };
    
        art art1_;
        art art2_;
    };
    

    Note that we don't define the struct twice, we just define 2 objects. Then if we had an artwork object like: artwork foo we could do:

    foo.art1_("Sam Arnold"s);
    foo.art2_("Jonathan Mee"s);