(SOLVED) Help Sorting List of Pointers by Derived Class Member

Hi.

I am just getting into using STL and am having issues with sorting lists of pointers based on values of derived class members, when I took my C++ class in college we never went into lists and they are quite a bit trickier in my opinion, yet faster for several reasons which is why I wanted to learn how to use them correctly. Anyway, I could really use some help.

Here is an example of my base class and two derived:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Base
{
private:
	int length;

public:
	virtual void printLength() = 0;

};
class Derived1 : public Base
{
private:
	int length;
        int length2


public:
	virtual void printLength();

};
class Derived2 : public Base
{
private:
	int length;
        int length2
        int length3


public:
	virtual void printLength();

};


I am trying to get them to sort by total length, so if derived1's length + length2 = 10 and derived2's length + length2 + length3 = 11 it would sort it accordingly.

I tried overloading the > operator for all classes, and making an operator() that took two Base*'s and then inside compared Base* < Base* and returned a bool but no luck with that even though I got that method working with a vector of pointers.

Here is another fragment to give you an idea of what I am talking about, this code compiles and runs but it doesn't actually sort it by value:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int main()
{
   list<Base*> List;
   list<Base*>::iterator it;

   ......fill list here with instances of both derived classes

   List.sort(value());

   return 0
}

bool value::operator() (Base* v1, Base* v2)
{
	if(v1 < v2)
		return false;
	else
		return true;

}


Any help would be appreciated, I'm lost. Also if you need me to post more in depth code let me know, I tried to just post fragments to avoid a huge post.
Last edited on
your "derived" classes dont inherit the "base" class. try fixing that first.
your "derived" classes dont inherit the "base" class. try fixing that first.


obviously just a typo. I think you can tell by the names of the classes this is an example, not the actual code, I typed it all out from scratch and didn't type in the inheritance. Sorry.
Last edited on
Provide a virtual function in the base class that returns the total length.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct base
{
    explicit base( int aa = 0 ) : a(aa) {}
    virtual ~base() {}

    virtual int total_length() const { return a ; }

    virtual std::ostream& print( std::ostream& stm ) const
    { return stm << "base{" << a << '}' ; }
    // ...

    const int a ;
};

std::ostream& operator<< ( std::ostream& stm, const base& b ) { return b.print(stm) ; }


Override the function in the derived classes
1
2
3
4
5
6
7
8
9
10
11
struct derived : base
{
    explicit derived( int aa = 0, int bb = 0 ) : base(aa), b(bb) {}

    virtual int total_length() const override { return a + b ; }

    virtual std::ostream& print( std::ostream& stm ) const override
    { return stm << "derived{" << a << ',' << b << '}' ; }

    const int b ;
};


Use the virtual function in the binary predicate for std::sort()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int main( int argc, char* argv[] )
{
    // prefer using std::vector as the default sequence container
    std::vector< base* > seq = { new derived(1,2), new base(3), new derived(0,0),
         new base(17), new derived(10,15), new derived(5,5), new base(7) } ;
    for( const base* p : seq ) std::cout << *p << ' ' ;
    std::cout << '\n' ;

    std::sort( seq.begin(), seq.end(), [] ( const base* a, const base* b )
                                { return a->total_length() < b->total_length() ; } ) ;
    for( const base* p : seq ) std::cout << *p << ' ' ;
    std::cout << '\n' ;

    // ideaLLY, use std::unique_ptr<base> instead
    for( base*& p : seq ) { delete p ; p = nullptr ; }
}

Thanks JLBorges! I had to change a few things around to get it working with list but you got my mind in the right direction and I got it working. I was focused on trying access all the members directly and totally overlooked the option of making a virtual function (*face palm).
Topic archived. No new replies allowed.