Operater < overloading for struct problem

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Frank

    #1

    Operater < overloading for struct problem

    Hello everyone,

    I am having trouble overloading the < operator for an assignment. I
    use a struct that contains information and I would like to sort this
    structure using STL sort with my own criteria of sorting. Basically, I
    would like to sort on visitor count of the Attraction structure.
    However, it never uses the < overloaded operator with my code.

    Handler.h:

    #ifndef H_HANDLER //Guard
    #define H_HANDLER

    #include <iostream>
    #include <vector>
    using namespace std;

    struct Attraction {
    string name;
    int visitors;
    };

    class Handler { //Define the class Handler

    private:
    vector<Attracti on*attractions ;
    vector<Attracti on*>::iterator p ;

    public: //Public functions
    ~Handler();
    void addAttraction(s tring name, int visitors);
    void printAttraction s();
    };


    #endif

    and in the Handler.cpp I have:

    Handler.cpp - snippet:

    bool operator<(const Attraction& a,const Attraction& b){
    return a.visitors < b.visitors;
    }

    Here is the function that performs the sort after adding a value:

    void Handler::addAtt raction(string name, int visitors){

    Attraction *attr;
    attr=new Attraction();

    attr->name=name;
    attr->visitors=visit ors;


    attractions.pus h_back(attr);
    sort(attraction s.begin(),attra ctions.end());

    }

    However, whatever I do, it will never use the overloaded < operator
    for sorting. What am I doing wrong? If I add the overloaded function
    in the header it starts complaining because it will also be inserted
    into the main program which is confusing since I have a guard around
    the header file.

    Regards,
    Frank

  • Victor Bazarov

    #2
    Re: Operater &lt; overloading for struct problem

    Frank wrote:
    I am having trouble overloading the < operator for an assignment. I
    use a struct that contains information and I would like to sort this
    structure using STL sort with my own criteria of sorting. Basically, I
    would like to sort on visitor count of the Attraction structure.
    However, it never uses the < overloaded operator with my code.
    >
    Handler.h:
    >
    #ifndef H_HANDLER //Guard
    #define H_HANDLER
    >
    #include <iostream>
    #include <vector>
    using namespace std;
    >
    struct Attraction {
    string name;
    int visitors;
    };
    >
    class Handler { //Define the class Handler
    >
    private:
    vector<Attracti on*attractions ;
    vector<Attracti on*>::iterator p ;
    >
    public: //Public functions
    ~Handler();
    void addAttraction(s tring name, int visitors);
    void printAttraction s();
    };
    >
    >
    #endif
    >
    and in the Handler.cpp I have:
    >
    Handler.cpp - snippet:
    >
    bool operator<(const Attraction& a,const Attraction& b){
    return a.visitors < b.visitors;
    }
    >
    Here is the function that performs the sort after adding a value:
    >
    void Handler::addAtt raction(string name, int visitors){
    >
    Attraction *attr;
    attr=new Attraction();
    >
    attr->name=name;
    attr->visitors=visit ors;
    >
    >
    attractions.pus h_back(attr);
    sort(attraction s.begin(),attra ctions.end());
    >
    }
    >
    However, whatever I do, it will never use the overloaded < operator
    for sorting. What am I doing wrong?
    Your operator< is defined for _objects_, but your vector is storing
    _pointers_. Drop the 'new', drop the pointers, keep objects, and
    everything will be fine.

    You can declare/define a local Attraction object in 'addAttraction'
    and then push_back it, the vector will make a copy.
    [..]
    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask


    Comment

    • mlimber

      #3
      Re: Operater &lt; overloading for struct problem

      On Mar 1, 10:45 am, "Frank" <f.f.nee...@gma il.comwrote:
      Hello everyone,
      >
      I am having trouble overloading the < operator for an assignment. I
      use a struct that contains information and I would like to sort this
      structure using STL sort with my own criteria of sorting. Basically, I
      would like to sort on visitor count of the Attraction structure.
      However, it never uses the < overloaded operator with my code.
      >
      Handler.h:
      >
      #ifndef H_HANDLER //Guard
      #define H_HANDLER
      >
      #include <iostream>
      #include <vector>
      using namespace std;
      >
      struct Attraction {
      string name;
      int visitors;
      >
      };
      >
      class Handler { //Define the class Handler
      >
      private:
      vector<Attracti on*attractions ;
      vector<Attracti on*>::iterator p ;
      >
      public: //Public functions
      ~Handler();
      void addAttraction(s tring name, int visitors);
      void printAttraction s();
      >
      };
      >
      #endif
      >
      and in the Handler.cpp I have:
      >
      Handler.cpp - snippet:
      >
      bool operator<(const Attraction& a,const Attraction& b){
      return a.visitors < b.visitors;
      }
      >
      Here is the function that performs the sort after adding a value:
      >
      void Handler::addAtt raction(string name, int visitors){
      >
      Attraction *attr;
      attr=new Attraction();
      >
      attr->name=name;
      attr->visitors=visit ors;
      >
      attractions.pus h_back(attr);
      sort(attraction s.begin(),attra ctions.end());
      >
      }
      >
      However, whatever I do, it will never use the overloaded < operator
      for sorting. What am I doing wrong? If I add the overloaded function
      in the header it starts complaining because it will also be inserted
      into the main program which is confusing since I have a guard around
      the header file.
      I suspect the fundamental problem is that you are sorting pointers
      rather than objects. In other words, std::sort works on the value_type
      of the container, which in your case is Attraction*, not Attraction.

      So, do you need to operator on the Attraction object polymorphically ?
      If not, don't use pointers; just allocate it on the stack, and let
      vector make a copy (assuming attractions is now of type
      vector<Attracti on>:

      void Handler::addAtt raction( const string& name, const int visitors )
      {
      const Attraction attr = { name, visitors };
      attractions.pus h_back(attr);
      sort(attraction s.begin(),attra ctions.end());
      }

      Note also that I changed the function parameters to const (see
      http://www.parashift.com/c++-faq-lit...rrectness.html) and the
      string to a reference so it doesn't make an additional copy (see
      http://www.parashift.com/c++-faq-lite/references.html).

      If you do need to use it polymorphically and to store it in a vector,
      prefer smart pointers such as std::tr1::share d_ptr (aka
      boost::shared_p tr) or one of the smart pointers found in this FAQ and
      those following:



      BTW, you could put just the function prototype for your operator< in
      the header or you could declare it "inline" to get rid of the
      duplication problem.

      Cheers! --M

      Comment

      • red floyd

        #4
        Re: Operater &lt; overloading for struct problem

        Frank wrote:

        Victor and mlimber have addressed your main issue. I'd like to address
        one other item.
        Handler.h:
        >
        #ifndef H_HANDLER //Guard
        #define H_HANDLER
        >
        #include <iostream>
        #include <vector>
        using namespace std;
        Do *NOT* put "using namespace std;" into a header file. It can
        seriously mess up other code. It should only go into non-header files,
        after all include directives.

        Comment

        • Frank

          #5
          Re: Operater &lt; overloading for struct problem

          On 1 mrt, 17:35, red floyd <no.s...@here.d udewrote:
          Frank wrote:
          >
          Victor and mlimber have addressed your main issue. I'd like to address
          one other item.
          >
          Handler.h:
          >
          #ifndef H_HANDLER //Guard
          #define H_HANDLER
          >
          #include <iostream>
          #include <vector>
          using namespace std;
          >
          Do *NOT* put "using namespace std;" into a header file. It can
          seriously mess up other code. It should only go into non-header files,
          after all include directives.

          Thanks everyone for the quick response!
          It works like a charm now,
          Regards,
          Frank

          Comment

          • Roland Pibinger

            #6
            Re: Operater &lt; overloading for struct problem

            On Thu, 1 Mar 2007 10:56:53 -0500, "Victor Bazarov" wrote:
            >Your operator< is defined for _objects_, but your vector is storing
            >_pointers_. Drop the 'new', drop the pointers, keep objects, and
            >everything will be fine.
            Except that objects in the OO sense like Attraction, Handler, ...
            usually are not copyable.
            >You can declare/define a local Attraction object in 'addAttraction'
            >and then push_back it, the vector will make a copy.
            That's the problem.

            Best regards,
            Roland Pibinger

            Comment

            • Victor Bazarov

              #7
              Re: Operater &lt; overloading for struct problem

              Roland Pibinger wrote:
              On Thu, 1 Mar 2007 10:56:53 -0500, "Victor Bazarov" wrote:
              >Your operator< is defined for _objects_, but your vector is storing
              >_pointers_. Drop the 'new', drop the pointers, keep objects, and
              >everything will be fine.
              >
              Except that objects in the OO sense like Attraction, Handler, ...
              usually are not copyable.
              "Usually"? What in the world do you mean? See to original post for
              clarification.
              >You can declare/define a local Attraction object in 'addAttraction'
              >and then push_back it, the vector will make a copy.
              >
              That's the problem.
              REALLY? Do you mean that the OP's Attraction object is non-copiable?
              Could you please elaborate?

              V
              --
              Please remove capital 'A's when replying by e-mail
              I do not respond to top-posted replies, please don't ask


              Comment

              • mlimber

                #8
                Re: Operater &lt; overloading for struct problem

                On Mar 1, 2:31 pm, "Victor Bazarov" <v.Abaza...@com Acast.netwrote:
                Roland Pibinger wrote:
                On Thu, 1 Mar 2007 10:56:53 -0500, "Victor Bazarov" wrote:
                Your operator< is defined for _objects_, but your vector is storing
                _pointers_. Drop the 'new', drop the pointers, keep objects, and
                everything will be fine.
                >
                Except that objects in the OO sense like Attraction, Handler, ...
                usually are not copyable.
                >
                "Usually"? What in the world do you mean? See to original post for
                clarification.
                >
                You can declare/define a local Attraction object in 'addAttraction'
                and then push_back it, the vector will make a copy.
                >
                That's the problem.
                >
                REALLY? Do you mean that the OP's Attraction object is non-copiable?
                Could you please elaborate?
                Roland's just being an OO purist. Objects in his world are always
                polymorphic, but in C++'s multiple paradigms, they are not. In this
                case, I don't think the OP was intending to use pure OO anyway, so our
                answers sufficed.

                Cheers! --M

                Comment

                • Roland Pibinger

                  #9
                  Re: Operater &lt; overloading for struct problem

                  On Thu, 1 Mar 2007 14:31:38 -0500, "Victor Bazarov" wrote:
                  >Roland Pibinger wrote:
                  >On Thu, 1 Mar 2007 10:56:53 -0500, "Victor Bazarov" wrote:
                  >>You can declare/define a local Attraction object in 'addAttraction'
                  >>and then push_back it, the vector will make a copy.
                  >>
                  >That's the problem.
                  >
                  >REALLY? Do you mean that the OP's Attraction object is non-copiable?
                  >Could you please elaborate?
                  Objects (in the OO sense) are characterized by identity, state and
                  behavior. When you duplicate (copy) objects you get into trouble with
                  identity and state, e.g.

                  Account a1 (12345);
                  Account a2 = a1;
                  a1.deposit (100);
                  a2.withdraw (200);

                  What does it mean to copy the account with account number 12345? What
                  is the balance of this account now? To answer your question,
                  Attraction (whatever that exactly means in the example) is an object
                  (in the sense of OO) and should not be copied.

                  Best regards,
                  Roland Pibinger

                  Comment

                  • Roland Pibinger

                    #10
                    Re: Operater &lt; overloading for struct problem

                    On 1 Mar 2007 12:12:00 -0800, "mlimber" <mlimber@gmail. comwrote:
                    >Roland's just being an OO purist. Objects in his world are always
                    >polymorphic, but in C++'s multiple paradigms, they are not.
                    So 'C++'s multiple paradigms' have changed the paradigms? C++ has
                    changed the meaning of object (OO) and polymorphism?


                    Comment

                    • kwikius

                      #11
                      Re: Operater &lt; overloading for struct problem

                      On 2 Mar, 08:26, rpbg...@yahoo.c om (Roland Pibinger) wrote:
                      Objects (in the OO sense) are characterized by identity, state and
                      behavior. When you duplicate (copy) objects you get into trouble with
                      identity and state, e.g.
                      >
                      Account a1 (12345);
                      Account a2 = a1;
                      a1.deposit (100);
                      a2.withdraw (200);
                      >
                      What does it mean to copy the account with account number 12345? What
                      is the balance of this account now?
                      struct Account{

                      double value;
                      Account(double value_in) :value(value_in ){}
                      Account(Account & other)
                      {
                      value = other.value;
                      other.value =0;
                      }

                      void deposit( double val)
                      {
                      value += val;
                      }
                      void withdraw(double val)
                      {
                      value -= val;
                      }
                      };

                      #include <iostream>
                      int main()
                      {
                      Account a1 (12345);

                      std::cout << a1.value <<'\n';

                      Account a2 = a1;
                      std::cout << a1.value <<'\n';

                      a1.deposit (100);
                      std::cout << a1.value <<'\n';

                      a2.withdraw (200);
                      }

                      output:

                      12345
                      0
                      100


                      I Am Joking of course :-) :-) :-)





                      Comment

                      • mlimber

                        #12
                        Re: Operater &lt; overloading for struct problem

                        On Mar 2, 3:36 am, rpbg...@yahoo.c om (Roland Pibinger) wrote:
                        On 1 Mar 2007 12:12:00 -0800, "mlimber" <mlim...@gmail. comwrote:
                        >
                        Roland's just being an OO purist. Objects in his world are always
                        polymorphic, but in C++'s multiple paradigms, they are not.
                        >
                        So 'C++'s multiple paradigms' have changed the paradigms? C++ has
                        changed the meaning of object (OO) and polymorphism?
                        C++ has not changed the meaning of polymorphism, but because of its
                        multi-paradigmatic nature, not every "object" is an OO object either.

                        struct B { virtual void f(); };

                        B b;
                        b.f(); // Will invoke B::f() directly
                        B& bref = b;
                        bref.f(); // Will invoke B::f() indirectly

                        In this example "b" is not being used polymorphically in the first
                        invocation of B::f(), but it is in the second.

                        Cheers! --M

                        Comment

                        • Victor Bazarov

                          #13
                          Re: Operater &lt; overloading for struct problem

                          Roland Pibinger wrote:
                          On Thu, 1 Mar 2007 14:31:38 -0500, "Victor Bazarov" wrote:
                          >Roland Pibinger wrote:
                          >>On Thu, 1 Mar 2007 10:56:53 -0500, "Victor Bazarov" wrote:
                          >>>You can declare/define a local Attraction object in 'addAttraction'
                          >>>and then push_back it, the vector will make a copy.
                          >>>
                          >>That's the problem.
                          >>
                          >REALLY? Do you mean that the OP's Attraction object is non-copiable?
                          >Could you please elaborate?
                          >
                          Objects (in the OO sense) are characterized by identity, state and
                          behavior. When you duplicate (copy) objects you get into trouble with
                          identity and state, e.g.
                          >
                          Account a1 (12345);
                          Account a2 = a1;
                          a1.deposit (100);
                          a2.withdraw (200);
                          >
                          What does it mean to copy the account with account number 12345?
                          You made a copy of the C++ object. I see nothing bad about it.
                          What
                          is the balance of this account now?
                          How the F should I know? Youi didn't explain any behaviour of the
                          'Account' class.
                          To answer your question,
                          Attraction (whatever that exactly means in the example) is an object
                          (in the sense of OO) and should not be copied.
                          You seem confused a bit...

                          '12345' has nothing to do with the identity of the object. &a1 and &a2
                          are the identities of the objects. '12345' is just a value that takes
                          part in the object's behaviour. Now, the "identity issue" can be seen
                          if you *pretend* that the operation

                          Accout &ra1 = a1;

                          is actually "making a copy". It isn't, of course, since &ra1 == &a1.

                          In the account example you gave, the actual bank account associated in
                          some way with 'a1' and 'a2' *objects* (instances of the 'Account' type)
                          is a separate "object" that has little to do with the program, and only
                          exists in the model, which apparently is not very well represented by
                          the 'Account' class (in terms of copying, obviously, using the terms of
                          what seems to be the model you're alluding to).

                          In "pure" OOP, according to you, no copy can be made. That doesn't
                          sound like a good thing. In the real world copies are made all the
                          time. Perhaps making a copy means different thing to different people
                          and your meaning is different from the C++'s one? The saying we use
                          in a situation like this is "don't push your own charter in someone
                          else's monastery". If you'd like the other monastery to adopt your
                          charter (or to amend its charter according to some of your views), you
                          might want to explain instead of attacking the monastery's principles
                          and values.

                          V
                          --
                          Please remove capital 'A's when replying by e-mail
                          I do not respond to top-posted replies, please don't ask


                          Comment

                          • Roland Pibinger

                            #14
                            Re: Operater &lt; overloading for struct problem

                            On Fri, 2 Mar 2007 12:06:01 -0500, "Victor Bazarov" wrote:
                            >Roland Pibinger wrote:
                            >Account a1 (12345);
                            >Account a2 = a1;
                            >a1.deposit (100);
                            >a2.withdraw (200);
                            >>
                            >What does it mean to copy the account with account number 12345?
                            >
                            >You made a copy of the C++ object. I see nothing bad about it.
                            So there is no problem?
                            >What
                            >is the balance of this account now?
                            >
                            >How the F should I know? Youi didn't explain any behaviour of the
                            >'Account' class.
                            So actually there is a problem! Why should copying need an
                            explanation?
                            >To answer your question,
                            >Attraction (whatever that exactly means in the example) is an object
                            >(in the sense of OO) and should not be copied.
                            >
                            >You seem confused a bit...
                            The confusion is not on my side.
                            >'12345' has nothing to do with the identity of the object. &a1 and &a2
                            >are the identities of the objects. '12345' is just a value that takes
                            >part in the object's behaviour.
                            Right, in C++ object identity by default is established as address.
                            'Object IDs' are necessary e.g. when the object is stored in a
                            database (and the memory address is lost). But that doesn't affect my
                            example at all.
                            >Now, the "identity issue" can be seen
                            >if you *pretend* that the operation
                            >
                            Accout &ra1 = a1;
                            >
                            >is actually "making a copy". It isn't, of course, since &ra1 == &a1.
                            The example just shows what happens when you try to duplicate stateful
                            objects with identity. But ...
                            >In the account example you gave, the actual bank account associated in
                            >some way with 'a1' and 'a2' *objects* (instances of the 'Account' type)
                            >is a separate "object" that has little to do with the program, and only
                            >exists in the model, which apparently is not very well represented by
                            >the 'Account' class (in terms of copying, obviously, using the terms of
                            >what seems to be the model you're alluding to).
                            You seem to confirm my example. It makes no sense to have 2 instances
                            of the same underlying "object".
                            >In "pure" OOP, according to you, no copy can be made. That doesn't
                            >sound like a good thing.
                            Look at dedicated OO languages like Java. You can implement a
                            copy-constructor in Java but why should you duplicate an object?
                            >In the real world copies are made all the
                            >time. Perhaps making a copy means different thing to different people
                            >and your meaning is different from the C++'s one?
                            Copies of _values_ are made all the time but not of objects. You need
                            to distinguish between objects and values, see e.g.

                            >The saying we use
                            >in a situation like this is "don't push your own charter in someone
                            >else's monastery". If you'd like the other monastery to adopt your
                            >charter (or to amend its charter according to some of your views), you
                            >might want to explain instead of attacking the monastery's principles
                            >and values.
                            I don't have a 'charter' and use only vocabulary commonly applied in
                            software engineering. The downside of the 'multiparadigm' approach in
                            C++ is that one not only needs to understand multiple paradigms but
                            also know how to combine them in a reasonable way. Otherwise one will
                            tackle the problems with the wrong tools.

                            Best regards,
                            Roland Pibinger

                            Comment

                            • Victor Bazarov

                              #15
                              Re: Operater &lt; overloading for struct problem

                              Roland Pibinger wrote:
                              [..] The downside of the 'multiparadigm' approach in
                              C++ is that one not only needs to understand multiple paradigms but
                              also know how to combine them in a reasonable way. Otherwise one will
                              tackle the problems with the wrong tools.
                              No! You don't need to combine anything. There is no requirement
                              not to wear OO after Labor Day. There is no requirement to combine
                              any paradigms or do it in any "reasonable way". Any way that gets
                              you where you're going is good.

                              V
                              --
                              Please remove capital 'A's when replying by e-mail
                              I do not respond to top-posted replies, please don't ask


                              Comment

                              Working...