OO techniques Get/Set functions

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • IanWright
    New Member
    • Jan 2008
    • 179

    OO techniques Get/Set functions

    I've been doing some work in C++ for a few months now, but only just had the requirement to design and implement some new classes. I didn't think that would be a problem, however I think I'm taking an incorrect approach for implementing classes, and was wondering if anyone could help me?

    My problem, the value I return is not the same as the value I set. Not surprisingly the memory address that the value gets assigned to, doesn't match the one I'm getting the value back from either...

    [CODE=cpp]
    #include "Entity.h"
    #include <iostream>

    using namespace std;

    int main(const int &)
    {
    Entity m;
    m.Location().XY (2,15);
    cout << m.Location().Y( );

    return 0;
    }[/CODE]

    Entity.h
    [CODE=cpp]
    #include "Location.h "

    class Entity
    {
    private:
    GeoLocation mLocation;
    public:
    GeoLocation Location();
    void Location(GeoLoc ation loc);
    };[/CODE]

    Entity.cpp
    [CODE=cpp]GeoLocation Entity::Locatio n()
    {
    return mLocation;
    }

    void Entity::Locatio n(GeoLocation location)
    {
    mLocation = location;
    }[/CODE]

    GeoLocation.cpp
    [CODE=cpp]class GeoLocation
    {
    private:
    float mX;
    float mY;

    public:
    GeoLocation()
    {
    mX = 0.0f;
    mY = 0.0f;
    }
    void X(float x)
    {
    mX = x;
    }
    void Y(float y)
    {
    mY = y;
    }
    void XY(int x, int y)
    {
    mX = (float)x;
    mY = (float)y;
    }
    };[/CODE]

    Output:
    0

    Any help would be much appreciated. I'm sure it will be something simple, I'm just not quite sure what it is. Thanks.

    Ian
  • todashah
    New Member
    • Feb 2008
    • 26

    #2
    To Generate Correct output Replace Your Code within main function from following code.

    Entity m;
    GeoLocation gl;
    m.Location(gl.X Y(2,15));
    GeoLocation glt=m.Location( );
    cout<<gtl.Y()<< endl;
    return 0;

    Bye..Take Care..Enjoy Coding
    Last edited by Ganon11; Apr 15 '08, 08:04 PM. Reason: Removed Quote to make post show

    Comment

    • weaknessforcats
      Recognized Expert Expert
      • Mar 2007
      • 9214

      #3
      Your GeoLocation class has no methods that return data. There are only methods to set the data. That means this code:

      Originally posted by IanWright
      cout << m.Location().Y( );
      won't compile. You can't cout the void of GeoLocation::Y.

      Comment

      • TamusJRoyce
        New Member
        • Apr 2008
        • 108

        #4
        I may be wrong. Your code may work without the copy constructor and stuff I added. It's good practice to always have a copy constructor, and something to learn.

        I'm assuming this is one of the things you would like learn how to implement. Reply back if just a problem with trying to cout a void return type. And what compiler let you compile the cout << m.Location().Y( ); ?


        [CODE=cpp]
        #include "Entity.h"
        #include <iostream>

        using namespace std;

        int main(const int &)
        {
        Entity m;
        m.Location().XY (2,15);
        //cout << m.Location().Y( );
        [I]
        // From the int getY() const; method you can
        // learn from.
        cout << m.Location().ge tY();
        [I]
        return 0;
        }[/CODE]

        Entity.h
        [CODE=cpp]
        #include "Location.h "

        class Entity
        {
        private:
        GeoLocation mLocation;
        public:
        // The "&" means pass by reference. This means that
        // You are passing the object instead of copying to
        // another GeoLocation object and passing that.
        // If it gets copied to another GeoLocation object
        // then passed, it calls the copy constructor, which
        // you don't have. so the default constructor is called.
        // Then a new GeoLocation was returned with only
        // the default constructors called.
        GeoLocation &Location();

        // This makes program faster with less usage of memory
        // because when passed by "&" does not require a copy
        // constructor (GeoLocation x = (GeoLocation)y) .
        void Location(const GeoLocation &loc);
        };[/CODE]

        Entity.cpp
        [CODE=cpp]GeoLocation Entity::Locatio n()
        {
        return mLocation;
        }

        // Parameter here needed changed as well...
        void Entity::Locatio n(const GeoLocation &location)
        {
        mLocation = location;
        }[/CODE]

        GeoLocation.cpp
        [CODE=cpp]class GeoLocation
        {
        private:
        float mX;
        float mY;

        public:
        GeoLocation()
        {
        mX = 0.0f;
        mY = 0.0f;
        }

        // Copy constructor. Tells how it is suppose to
        // be copied. GeoLocation x = (GeoLocation)y;
        // causes it to be used.
        GeoLocation(con st GeoLocation &loc)
        {
        // Makes sure that: GeoLocation x; x = x;
        // Does not happen. Just prevents extra work.
        if (&loc != this)
        {
        mX = loc.getX();
        mY = loc.getY();
        } // End if
        }
        // Must have for copy constructor. const so that
        // copy constructor can access. getX does not
        // change mX or mY or anything, so valid use of const
        float getX() const
        {
        return(mX);
        }
        float getY() const
        {
        return(mY);
        }

        void X(float x)
        {
        mX = x;
        }
        void Y(float y)
        {
        mY = y;
        }
        void XY(int x, int y)
        {
        mX = (float)x;
        mY = (float)y;
        }
        };[/CODE]

        Changing GeoLocation Location();
        to GeoLocation &Location(); should fix your problem alone.
        This prevents a new object being returned, and passes the one returned instead.

        Sort of like:
        GeoLocation &Location()
        {
        Geolocation ret;

        // Now that there is a copy constructor, this will work...
        // But since there wasn't one, here's how it worked:
        ret = mLocation; // No copy constructor, so ret simply
        // initialized to mX = mY = 0;
        return ret;
        } // End Location() Function

        This is how your function Location was working before. If copy constructors are a bit advanced for you, leave them out for now. Stick with returning references --ClassName &function()-- and having [const ClassName &var] parameters.

        // As an example... basic data types such as int, float,
        // double, long don't need to be passed or returned by
        // reference... (they fit in one register in the processor).
        ClassName1 &foofunction(co nst ClassName2 &var);

        Also, look up how to do const functions. getX() I wrote is a good example. int getX() const; has const after it so that if an object gets passed into var through foofunction's (above) parameter, you can access it. var.getX() valid. var.X(5) invalid (because X changes data in GeoLocation, and therefore cannot be a const function).

        Apply this to each function which takes in or returns a Class Object, respectively. Experiment by removing const in all functions. It will still work. But many times there are circumstances where something that uses your Class will be const, like text "hello", which is a const char * being passed to your constructor.

        Keep programming. It's hard to get the fundamentals of c++, but once you do, the power of what you make is pushed speeds most other languages can't touch (assembly is an exception, but it's harder than c++)

        (Sorry if I'm bad at explaining things. I love programming, but am not the best at explaining myself)

        Comment

        • oler1s
          Recognized Expert Contributor
          • Aug 2007
          • 671

          #5
          You know what I find interesting? The choice to take a bunch of variables, make them private, then create a set of functions that allow you to do nothing more than either access them or assign to them. While you can continue doing this as a syntactical exercise, doing so under the cover of good design is rather dubious.

          Comment

          • IanWright
            New Member
            • Jan 2008
            • 179

            #6
            Thanks for all the responses,

            There is no compiler error, that is my fault for pasting the incorrect section of code. There is indeed a method for returning the Y value that I'm trying to use, so apologies for that...

            TamusJRoyce, thats very useful and informative. I'll try and take a look into this in more depth so I understand exactly whats going on. Unfortunately having worked mostly in managed programming languages all the passing member classes by reference is a little new.

            oler1s, you'd recommend just having variables defined just in the public scope I'm assuming?

            Ian

            Comment

            • oler1s
              Recognized Expert Contributor
              • Aug 2007
              • 671

              #7
              oler1s, you'd recommend just having variables defined just in the public scope I'm assuming?
              I recommend achieving a sensible design. If you define a number of variables privately, the idea is you want to encapsulate them. Writing functions that do nothing but allow you to read them or set them breaks encapsulation. Which then brings up the question, why even bother declaring the variables private in the first place.

              Comment

              • TamusJRoyce
                New Member
                • Apr 2008
                • 108

                #8
                Originally posted by oler1s
                I recommend achieving a sensible design. If you define a number of variables privately, the idea is you want to encapsulate them. Writing functions that do nothing but allow you to read them or set them breaks encapsulation. Which then brings up the question, why even bother declaring the variables private in the first place.
                I foremost agree with oler1s. It's an excellent point, and I do this sometimes habitually when I program. struct (same as class, except it's defaulty public instead of private) and no functions (none needed to get/set/construct) would really solve your problem with your second class.

                However if you are just practicing using Inquirers and Manipulators, this is a good example. Having public Inquirers and protected Manipulators (unlike what I've done in my example) allows for other programmers who wish to use your well documented code to change things by making that class their own (through inheritance) can.

                It does depend on your purpose and if you plan on either sharing or having others directly use your code.

                It's not that I'm implying that you shouldn't make variables public in classes, because it's ok to. Personally, my preference is to hold variables that are similar and I want to be public in a struct.

                struct bobsData {
                int x, y;
                };

                And then add an object of that type directly into being public, so users have an idea what data they are manipulating and things are more organized.

                But that's me. Coding depends on you and your project. And struct is just a glorified class that starts off as public. Otherwise the keywords are interchangeable (I believe. Research to be sure : )...

                Keep learning and programming.

                PS. I have been coding for quite a while (12-13 years & I'm 25 & 3 days), so my coding style has become somewhat hard headed. Keep your code unique to your style. It's handy when someone plagiarizes you... : )
                Last edited by TamusJRoyce; Apr 17 '08, 08:20 AM. Reason: wrong idea written. oler1s perswaded me on what was going on : )

                Comment

                • Laharl
                  Recognized Expert Contributor
                  • Sep 2007
                  • 849

                  #9
                  Structs can have member functions in C++. The only difference between structs and classes is the default access: public for structs, private for classes.

                  Comment

                  Working...