STL sort with user defined data type

Discussion in 'C++' started by mweltin@gmail.com, Jul 17, 2007.

  1. Guest

    I have been looking in the archives and as of yet have not found an
    answer to my problem.
    Class B has four members, and class A is derived from class B. Class
    A only adds one new member to class B.
    Class A has '<', '>', '==' and '=' overloaded, as well as a copy
    constructor. Class B only has the copy constructor and assignment
    operator overloaded.

    I create a vector of A objects, and stuff them with random values.
    When I sort the vector of A objects only the member unique to the A
    object changes.

    For example say I have three A objects in a vector blah

    blah[0] {one = 5 two = 0.8 three = 0.1 mysortvar = 1}
    blah[1] {one = 2 two = 0.7 three = 0.2 mysortvar = 0}
    blah[2] {one = 7 two = 0.6 three = 0.3 mysortvar = 3 }

    I expect
    blah[0] {one = 2 two = 0.7 three = 0.2 mysortvar = 0}
    blah[1] {one = 5 two = 0.8 three = 0.1 mysortvar = 1}
    blah[2] {one = 7 two = 0.6 three = 0.3 mysortvar = 3 }

    but I get

    blah[0] {one = 5 two = 0.8 three = 0.1 mysortvar = 0}
    blah[1] {one = 2 two = 0.7 three = 0.2 mysortvar = 1}
    blah[2] {one = 7 two = 0.6 three = 0.3 mysortvar = 3 }

    Note:ONLY THE mysortvar values change.

    could someone clue me into what I'm doing wrong?
    thank you,
    Markus
     
    , Jul 17, 2007
    #1
    1. Advertising

  2. Kai-Uwe Bux Guest

    wrote:

    > I have been looking in the archives and as of yet have not found an
    > answer to my problem.
    > Class B has four members, and class A is derived from class B. Class
    > A only adds one new member to class B.
    > Class A has '<', '>', '==' and '=' overloaded, as well as a copy
    > constructor. Class B only has the copy constructor and assignment
    > operator overloaded.
    >
    > I create a vector of A objects, and stuff them with random values.
    > When I sort the vector of A objects only the member unique to the A
    > object changes.
    >
    > For example say I have three A objects in a vector blah
    >
    > blah[0] {one = 5 two = 0.8 three = 0.1 mysortvar = 1}
    > blah[1] {one = 2 two = 0.7 three = 0.2 mysortvar = 0}
    > blah[2] {one = 7 two = 0.6 three = 0.3 mysortvar = 3 }
    >
    > I expect
    > blah[0] {one = 2 two = 0.7 three = 0.2 mysortvar = 0}
    > blah[1] {one = 5 two = 0.8 three = 0.1 mysortvar = 1}
    > blah[2] {one = 7 two = 0.6 three = 0.3 mysortvar = 3 }
    >
    > but I get
    >
    > blah[0] {one = 5 two = 0.8 three = 0.1 mysortvar = 0}
    > blah[1] {one = 2 two = 0.7 three = 0.2 mysortvar = 1}
    > blah[2] {one = 7 two = 0.6 three = 0.3 mysortvar = 3 }
    >
    > Note:ONLY THE mysortvar values change.
    >
    > could someone clue me into what I'm doing wrong?


    Post at least the copy-constructors and assignment operators. My guess is
    that at least one of them (for class A) does not forward the call to the
    B-subobject. If I had to bet, I would venture the conjecture that the first
    line is missing in A::eek:perator=:

    A & operator= ( A const & other ) {
    B::eek:perator=( other ); // assign the B subobject
    mysortvar = other.mysortvar; // assign the additional member
    return ( *this );
    }


    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Jul 17, 2007
    #2
    1. Advertising

  3. Guest

    On Jul 16, 3:00 pm, Kai-Uwe Bux <> wrote:
    > wrote:
    > > I have been looking in the archives and as of yet have not found an
    > > answer to my problem.
    > > Class B has four members, and class A is derived from class B. Class
    > > A only adds one new member to class B.
    > > Class A has '<', '>', '==' and '=' overloaded, as well as a copy
    > > constructor. Class B only has the copy constructor and assignment
    > > operator overloaded.

    >
    > > I create a vector of A objects, and stuff them with random values.
    > > When I sort the vector of A objects only the member unique to the A
    > > object changes.

    >
    > > For example say I have three A objects in a vector blah

    >
    > > blah[0] {one = 5 two = 0.8 three = 0.1 mysortvar = 1}
    > > blah[1] {one = 2 two = 0.7 three = 0.2 mysortvar = 0}
    > > blah[2] {one = 7 two = 0.6 three = 0.3 mysortvar = 3 }

    >
    > > I expect
    > > blah[0] {one = 2 two = 0.7 three = 0.2 mysortvar = 0}
    > > blah[1] {one = 5 two = 0.8 three = 0.1 mysortvar = 1}
    > > blah[2] {one = 7 two = 0.6 three = 0.3 mysortvar = 3 }

    >
    > > but I get

    >
    > > blah[0] {one = 5 two = 0.8 three = 0.1 mysortvar = 0}
    > > blah[1] {one = 2 two = 0.7 three = 0.2 mysortvar = 1}
    > > blah[2] {one = 7 two = 0.6 three = 0.3 mysortvar = 3 }

    >
    > > Note:ONLY THE mysortvar values change.

    >
    > > could someone clue me into what I'm doing wrong?

    >
    > Post at least the copy-constructors and assignment operators. My guess is
    > that at least one of them (for class A) does not forward the call to the
    > B-subobject. If I had to bet, I would venture the conjecture that the first
    > line is missing in A::eek:perator=:
    >
    > A & operator= ( A const & other ) {
    > B::eek:perator=( other ); // assign the B subobject
    > mysortvar = other.mysortvar; // assign the additional member
    > return ( *this );
    > }
    >
    > Best
    >
    > Kai-Uwe Bux

    I'm in American Samoa and my internet connection is not what you would
    call good, or even bad, its worse than bad. I'm having trouble
    posting to this list so please forgive me if I reply more than once.
    You are correct. To let you in on some more detail it is for a
    genetic algorithm.
    The base class is a "genome" and the derived class is an "individual.
    Their overloaded assignment operators are posted below. As you can
    see in the old version of the individual class assignment operator I
    was copying all the members explicitly, and not using the base class
    assignment operator. I'm not sure how these differ. I ran a test
    with the newly suggested assignment operator and it works. Clearly,
    there is something about the "sort", or other aspect of the STL I have
    no idea about. If you have the time and would care to enlighten me I
    would be grateful.

    NNGenome & NNGenome::eek:perator=(const NNGenome & oldNNG){
    if(this != &oldNNG){ //Check for self assignment.
    this->Epochs = oldNNG.Epochs;
    this->LearnRate = oldNNG.LearnRate;
    this->Momentum = oldNNG.Momentum;
    this->NNStrDef = oldNNG.NNStrDef;
    }
    return *this;
    }

    Individual & Individual::eek:perator=(const Individual& GNN){
    //check for self assigement.
    if(this != &GNN){
    this->BestFitness = GNN.BestFitness;
    this->Gepochs = GNN.Gepochs;
    this->GlearnRate = GNN.GlearnRate;
    this->Gmomentum = GNN.Gmomentum;
    this->GnnStrDef = GNN.GnnStrDef;
    }
    return *this;
    }
    I switched the above to the following.
    Individual & Individual::eek:perator=(const Individual& GNN){
    //check for self assigement.
    if(this != &GNN){
    NNGenome::eek:perator=(GNN);
    this->BestFitness = GNN.BestFitness;
    }
    return *this;
    }
     
    , Jul 17, 2007
    #3
  4. Kai-Uwe Bux Guest

    wrote:

    > On Jul 16, 3:00 pm, Kai-Uwe Bux <> wrote:
    >> wrote:
    >> > I have been looking in the archives and as of yet have not found an
    >> > answer to my problem.
    >> > Class B has four members, and class A is derived from class B. Class
    >> > A only adds one new member to class B.
    >> > Class A has '<', '>', '==' and '=' overloaded, as well as a copy
    >> > constructor. Class B only has the copy constructor and assignment
    >> > operator overloaded.

    >>
    >> > I create a vector of A objects, and stuff them with random values.
    >> > When I sort the vector of A objects only the member unique to the A
    >> > object changes.

    >>
    >> > For example say I have three A objects in a vector blah

    >>
    >> > blah[0] {one = 5 two = 0.8 three = 0.1 mysortvar = 1}
    >> > blah[1] {one = 2 two = 0.7 three = 0.2 mysortvar = 0}
    >> > blah[2] {one = 7 two = 0.6 three = 0.3 mysortvar = 3 }

    >>
    >> > I expect
    >> > blah[0] {one = 2 two = 0.7 three = 0.2 mysortvar = 0}
    >> > blah[1] {one = 5 two = 0.8 three = 0.1 mysortvar = 1}
    >> > blah[2] {one = 7 two = 0.6 three = 0.3 mysortvar = 3 }

    >>
    >> > but I get

    >>
    >> > blah[0] {one = 5 two = 0.8 three = 0.1 mysortvar = 0}
    >> > blah[1] {one = 2 two = 0.7 three = 0.2 mysortvar = 1}
    >> > blah[2] {one = 7 two = 0.6 three = 0.3 mysortvar = 3 }

    >>
    >> > Note:ONLY THE mysortvar values change.

    >>
    >> > could someone clue me into what I'm doing wrong?

    >>
    >> Post at least the copy-constructors and assignment operators. My guess is
    >> that at least one of them (for class A) does not forward the call to the
    >> B-subobject. If I had to bet, I would venture the conjecture that the
    >> first line is missing in A::eek:perator=:
    >>
    >> A & operator= ( A const & other ) {
    >> B::eek:perator=( other ); // assign the B subobject
    >> mysortvar = other.mysortvar; // assign the additional member
    >> return ( *this );
    >> }
    >>
    >> Best
    >>
    >> Kai-Uwe Bux

    > I'm in American Samoa and my internet connection is not what you would
    > call good, or even bad, its worse than bad. I'm having trouble
    > posting to this list so please forgive me if I reply more than once.
    > You are correct. To let you in on some more detail it is for a
    > genetic algorithm.
    > The base class is a "genome" and the derived class is an "individual.
    > Their overloaded assignment operators are posted below. As you can
    > see in the old version of the individual class assignment operator I
    > was copying all the members explicitly, and not using the base class
    > assignment operator. I'm not sure how these differ. I ran a test
    > with the newly suggested assignment operator and it works. Clearly,
    > there is something about the "sort", or other aspect of the STL I have
    > no idea about. If you have the time and would care to enlighten me I
    > would be grateful.
    >
    > NNGenome & NNGenome::eek:perator=(const NNGenome & oldNNG){
    > if(this != &oldNNG){ //Check for self assignment.
    > this->Epochs = oldNNG.Epochs;
    > this->LearnRate = oldNNG.LearnRate;
    > this->Momentum = oldNNG.Momentum;
    > this->NNStrDef = oldNNG.NNStrDef;
    > }
    > return *this;
    > }
    >
    > Individual & Individual::eek:perator=(const Individual& GNN){
    > //check for self assigement.
    > if(this != &GNN){
    > this->BestFitness = GNN.BestFitness;
    > this->Gepochs = GNN.Gepochs;
    > this->GlearnRate = GNN.GlearnRate;
    > this->Gmomentum = GNN.Gmomentum;
    > this->GnnStrDef = GNN.GnnStrDef;
    > }
    > return *this;
    > }


    Well, I note that the base class assignment mentioness the members

    Epochs
    LearnRate
    Momentum
    NNStrDef

    whereas the assignment operator for the derived class is working on

    BestFitness // new member
    Gepochs // ?
    GlearnRate // ?
    Gmomentum // ?
    GnnStrDef // ?

    Without seeing more code, it is hard to be certain, but the mismatch in
    identifiers could indicate that the copying of the base-class member is not
    handled correctly (which matches the output).

    > I switched the above to the following.
    > Individual & Individual::eek:perator=(const Individual& GNN){
    > //check for self assigement.
    > if(this != &GNN){
    > NNGenome::eek:perator=(GNN);
    > this->BestFitness = GNN.BestFitness;
    > }
    > return *this;
    > }


    I do not quite see the need for avoiding self-assignment in the above
    assignment operators. In fact, I do not see the need for declaring the
    assignment operator at all: The compiler generated assignment operator does
    member-wise assignment. Thus, you should be fine with removing all
    assignment operators from both classes. (Similarly, you probably also don't
    need to define the copy constructor).


    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Jul 17, 2007
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Oodini
    Replies:
    1
    Views:
    1,836
    Keith Thompson
    Sep 27, 2005
  2. Replies:
    2
    Views:
    437
  3. Replies:
    1
    Views:
    728
    mlimber
    Jun 2, 2006
  4. alice
    Replies:
    2
    Views:
    377
    Thomas Tutone
    Nov 2, 2006
  5. Navin
    Replies:
    1
    Views:
    761
    Ken Schaefer
    Sep 9, 2003
Loading...

Share This Page