?
Solved

pointer to two different class

Posted on 2003-02-25
29
Medium Priority
?
456 Views
Last Modified: 2010-04-01
I wrote one new class for a very big project. There are is already one class in the origional class. For one mode, it need run the original class function, for another mode, it need run the new class function I wrote. These two class have the same functions and called many place. I want to used the same point name as the original one. for one mode, it points to the original class object, for another, point to new one. Can anybody tell me how to do this. btw, the original point name is global.
0
Comment
Question by:gaohuanzx
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 9
  • 8
  • 5
  • +3
29 Comments
 

Expert Comment

by:Fallen_Knight
ID: 8023170
i'm not sure if i understand this,

calss1 {
    func()
}

class 2 {
    func()
}

and you want a pointer that can point at either class1 or class2 and call func?
0
 

Author Comment

by:gaohuanzx
ID: 8023460
yes, you are right, do you have the solution?
0
 
LVL 12

Expert Comment

by:rajeev_devin
ID: 8023474
give a skeletal structure. then its' possible to understand clearly.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:gaohuanzx
ID: 8023616
rajeev devin: I did not get what you mean, can u give me a more detail, or show me an example?
0
 

Expert Comment

by:locomojo
ID: 8023627
The Basic Idea is if you know the type of the class
then you can explicitly call a method in a specific class by using it's namespace:

for func() in class1 call:
class1::func()

for func() in class2 call:
class2::func()
0
 
LVL 12

Expert Comment

by:rajeev_devin
ID: 8023794
the way fallen_knight has given. a simple structure of your design.
0
 

Accepted Solution

by:
Fallen_Knight earned 100 total points
ID: 8023924
well the best way i can give is to use inheritance

is that a viable option in this case?

say you have 2 classes like above, add a 3rd and do the below

class interface {
    void func(void) = 0;
}

class calss1 : public interface  {
    void func(void);
}

class class2 : public interface {
    void func(void);
}

now because class1 and class2 extend the interface class, and implement the func, a array of baseclass pointers and now point to class 1 and class2 and call func. If you need to tell the diffrences between the two you can use RTTI (Run Time Type Identification).

Hope that helps, need a good example?
0
 

Expert Comment

by:locomojo
ID: 8023941
Another way:

class BaseClass
{
public:
virtual func() = 0;
};

class class1:
public BaseClass
{
 func(){ do this;};
}

class class2
public BaseClass
{
func(){do that;);
}

.
.
.

BaseClass* pMyObj = ...

use casting:
for class1
((clas1*)pMyObj)->func()

for class2
((clas2*)pMyObj)->func()


cheers.
0
 

Expert Comment

by:Fallen_Knight
ID: 8023981
opps i forgot the virtual in my example (witch is pretty much the  exact same way as locomojo)

class interface {
   virtual void func(void) = 0;
}
0
 

Author Comment

by:gaohuanzx
ID: 8024096
rajeev devin: I did not get what you mean, can u give me a more detail, or show me an example?
0
 
LVL 12

Expert Comment

by:Salte
ID: 8024169
I believe what you want is a baseclass and virtual functions:

class Base {
public:
   virtual ~Base() { cout << "Base::~Base" << endl; }
   virtual void func() = 0;
   virtual int another_func(int x) = 0;
};

class OneClass : public Base {
public:
   virtual ~OneClass() { cout << "OneClass::~OneClass" << endl; }
   virtual void func() { cout << "OneClass::func" << endl; }
   virtual int another_func(int x)
   {
      cout << "OneClass::another_func(" << x << ")" << endl;
      return x + 1;
   }
};

class AnotherClass : public Base {
public:
   virtual ~AnotherClass() { cout << "AnotherClass::~AnotherClass" << endl; }
   virtual void func() { cout << "AnotherCLass::func" << endl; }
   virtual int another_func(int x)
   {
      cout << "AnotherClass::another_func(" << x << ")" << endl;
      return x - 1;
   }
};

Base * a = new OneClass;
Base * b = new AnotherClass;

int x = 3;
a -> func(); // will print out OneClass::func
x = a -> another_func(x);
  // will print out OneClass::another_func(3)
  // will return 4 and x is set to 4.
b -> func(); // will print out AnotherClass::func
x = b -> another_func(x);
  // will print out AnotherClass::another_func(4)
  // will return 3 and x is set to 3.

delete a;
// will print out OneClass::~OneClass
// and then Base::~Base
delete b;
// will print out AnotherClass::~AnotherClass
// and then Base::~Base

calling the function through the pointers a and b will go to the correct class depending on the actual type. Both a and b are of type pointer to Base but the objects pointed to are of subclasses of Base. Using virtual function mechanism you select which function to call based on the actual type of the object and not the declared type of the pointer.

This is implemented by having each object of type Base or derived subclasses of Base have an extra pointer to a virtual table. This is often referred to as the vtable pointer. This is an extra member in the class which isn't declared by you and is therefore hidden. It has no real name and you can't really refer to it by any particular manner. It is the constructor of the class that initializes this member so when the constructor for AnotherClass is called it will set the vtable pointer after the initialization list is processed but before the body of the constructor is executed. In the case above it appear that OneClass and AnotherClass doesn't have constructors but they do, C++ will define one constructor for each class because it has a vtable pointer and call that constructor to construct the object. If you write an explicit constructor the vtable pointer will be set by that constructor.

Alf
0
 

Assisted Solution

by:locomojo
locomojo earned 100 total points
ID: 8024287
We all messed up things...

The solution is as follows...

class A
{
public:
 virtual func(){Do this;);
}

class B:
public class A
{
virtual func[]{Do that;);
}

B* pBClassObj = XXXX;

pBClassObj->func(); // Do that..

((A*)pBClassObj)->func(); // Do this;

No need for an Interface etc..
0
 
LVL 12

Expert Comment

by:rajeev_devin
ID: 8024348
Here is the modified version of your code. It will work fine.

class interface {
public:
   virtual void func(void) = 0;
};

class class1 : public interface  {
public:
     void func(void)
     {
        cout << "From class1";
     }
};

class class2 : public interface {
public:
     void func(void)
     {
        cout << "From class2";
     }
};

void main()
{
     interface *ptr;

/* To access the func() of class1 */
     ptr = new class1();
     ptr->func();
     delete ptr;
/* To access the func() of class2 */
     ptr = new class2();
     ptr->func();
     delete ptr;

}

Hope this may help you
Regards
0
 
LVL 12

Expert Comment

by:Salte
ID: 8024462
locomojo,

actually, what you just designed IS an interface....

so your "no need for interface" is somewhat out of place :-)

Alf
0
 

Expert Comment

by:locomojo
ID: 8024579
Reply to Salte:

Interface is a class !!!
with only pure virtual members.

and preferably all public so it will be a struct.
0
 
LVL 12

Expert Comment

by:rajeev_devin
ID: 8024706
Reply to locomojo:

I dont' think a virtual class is a structure. A structure should poccess data in itself. A virtual function is just an interface to the outside world, or more specifically, class user.
0
 

Expert Comment

by:locomojo
ID: 8024764
Reply to rajeev_devin:

What I ment was...
Instead of declaring a class with pure virtual methods which mast be public ... just declare it as a struct..

instead of this:
class MyInterface
{
public:
virtual void func1();
vitrual void func2();
);

Do that:

struct MyInterface
{
virtual void func1();
vitrual void func2();
);


thats all :-)
0
 
LVL 12

Expert Comment

by:Salte
ID: 8024800
That depends on your definition for interface.

To me an interface is:

a set of function signatures that belongs together and allows you to manipulate a certain functionality. What it does NOT contain is the implementation of those functions - however, this is not absolute. If an interface provide a function A and another function B then you can implement a function DoAthenB which can be implemented such that it physically is a part of the interface but it is provided with a body that does A and then B. However, since it is implemented only in terms of functions which are themselves not defined by the interface it is still a part of the interface even though the function is provided with implementation. You can also take the view that that function is just a convenience function and as such is not part of the interface - i.e. the implementation doesn't have to provide a body for that function since it is already provided.

Win32 is an interface, it's your basic interface to windows.

Posix is another interface, it's your basic interface to posix compatible systems.

A class with only pure virtual functions is an interface, it allows you to manipulate all subclasses that implements that interface. I.e. they implement the body of the functions. However, here too comes the section about convenience functions which are implemented in terms of the pure virtual functions but which are themselves not pure virtual. They are still a part of the interface but they do not require implementation by the implementation since they already have one. However, they require their underlying functions (the pure virtual ones) to be implemented and operate in terms of those.

A class - any class - not just with pure virtual functions - provide an interface. With it you can manipulate all objects of that class. However, unless the interface have virtual functions you cannot manipulate subclasses of that class through that interface.

Of course, you can say "that wasn't the definition of interface I had in mind" but that's a matter of definition. Your usage of the term is a rather restricted form that has its usage in that you create an interface without any default implementation or without any implementation by making a class with only virtual functions:

class MyInterface {
public:
   virtual int do_A() = 0;
   virtual int do_B(....) = 0;
};

Since you have pure virtual functions in it, you cannot create any object of that class and so it serves ONLY as an interface. However, this does not mean that a class which CAN be instantiated can NOT serve as an interface, it only means that a class such as MyInterface serves no other purpose BUT to be an interface. Other classes also provide interfaces, in fact EVERY class does.

Also, note that it is enough to have ONE pure virtual function for the class to be a pure interface class. The reason is that you cannot instantiate it as is and MUST provide subclasses that implement the pure virtual function.

A class with ONLY pure virtual functions may also be called an interface but that does not exclude other classes from being interfaces.

Alf
0
 
LVL 12

Expert Comment

by:Salte
ID: 8024923
locomojo,

you can define an interface like this:

struct Interface {
   virtual int foo() = 0;
   virtual void bar() = 0;
};

This makes use of the fact that a struct is the same as a class but with public access.

class C : public D {
public:
   decls;
};

is equivalent to:

struct C : D {
   decls;
}

and

struct C : private D {
private:
   decls;
};

is equivalent to

class C : D {
   decls;
};

However, it is a matter of CONVENTION to NOT use struct for classes that contain methods other than convenience methods and specifically no virtual functions or methods. So it is actually common to write:

class Interface {
public:
   .....
};

instead, yes you get that extra word 'public:' there but using 'class' indicate that here comes something that is more than just a dumb record.

You can also have functions/methods in structs but they are just for convenience and you could just as well have declared them outside:

struct foo {
   int a;
   int b;
   int sumab() const { return a + b; }
};

You might as well have declared:

int sumab(const foo * p) { return p -> a + p -> b; }

but putting it in the struct is more convenient.

'virtual' should definitely imply a class and not a struct it is a signal to the reader (the human reader) that this is more than just a dumb record.

For the C++ compiler the terms struct and class means more or less the same but it is a very good convention that you hold them far away from each other and never mix them "just because".

Examples of places where you CAN mix struct and class is typically like this:

struct S { ... };

class C : public S {
  // no data, only methods to operate on S's data.
  // no virtual functions either since that would imply
  // a vtable pointer.
  // also, the constructors if any should only do simple
  // stuff like computing the data to store in S.
  // This is because it is possible to get an object
  // without every constructing it using constructor.
  // specifically there shouldn't be any destructor
  // defined or needed.
};

Essentially you end up with sizeof(C) == sizeof(S) and you can have an S and just cast it to a C and use the functions in there, you can also construct the object as an S< just cast it to C and then use it. The C constructor was never called and the C destructor will not be called. For this reason the C class should not have any destructor.

If you need virtual functions or virtual baseclass or a destructor or anything more fancy than above. Then you do it like this:

class C { // no inheritance.
private:
   S s;
public:
   ....regular class...
   C(const S & ss) : s(ss) {}

   ...
   operator const S & () const { return s; }
   const S & operator -> () const { return s; }
};

This is a regular class and can have inheritance but the struct S is not provided through inheritance or if it is it must be inherited as private or protected but it is best if it isn't inherited at all (should be no need to inherit it since it is a struct and doesn't have any virtual functions).

You can even overload the operator -> so the C can reach the s members (read only) as:

C c;

c -> a; etc..

Or by casting.

The point is that you can mix with struct as baseclass and a subclass being a class that provide functions for that struct - including constructors but there are many limitations to it and if you want anything beyond those limitations don't do it that way, put the struct inside the class instead. Then you can do whatever you want without restrictions.

So yes, as far as the language is concerned the two words means almost the same thing but they do mean different things to programmers and they should mean different things to programmers. Doing tricky stuff like:

struct C { // This is really a class!
private:
   int k;
public:
   virtual int foo();
   ...
};

is possible but none-the-less bad style. This is true even if you have only public pure virtual functions as members as you sometimes would in your typical interface class.

Alf
0
 

Expert Comment

by:locomojo
ID: 8025011
Salte:

You are right for most things...
But when you declare an Interface ...
You expect that any class that implement that interface
and referenced by the interface pointer...
the method that would be called is the one implemented in the class implements that interface...

I know that declaring and interface with some basic implementation of methods is common but it is a bad O-O desighn.

Interface should not implement anything instead of declarations.
0
 
LVL 12

Expert Comment

by:Salte
ID: 8025123
If something is "good" or "bad" O-O design is very much a matter of opinion. In my experience something is good design if it works well for its purpose and is even better design if you can easily extend it beyond its original purpose.

If you have an interface that define basic functions like this:


class Interface {
public:
   virtual void do_A(int x) = 0;
   virtual void do_B(int x) = 0;
};

If 99% of the usages then becomes something like:


void do_something(Interface * if, int x)
{
   if -> do_A(x);
   if -> do_B(x);
}

Then the interface specification might be extended to also include a new function:

class Interface { // version 2
public:
   virtual void do_A(int x) = 0;
   virtual void do_B(int x) = 0;
   void do_A_then_B(int x)
   {
      do_A(x);
      do_B(x);
   }
};

In your mind it is no longer a pure interface and it is "bad" design, but really what is bad with it? It is a pure extension, people who want to do A but not B can still do so, it just cover that vast majority who do A and then B and help them do it right without getting an error in that the variable x shich is supposed to be the same for the two functions changes value in the meantime.

If the previous interface was "good" then how can this be "worse". I would say it is "better" in that it is a supsrset of the previous and also contain some convenience function that cover what the majority of users need.

Now you might even encounter that a large portion of the implementations of do_B() is done by calling do_A() with a value of (x >> 1) twice. There are some interfaces that implement do_B differently but there are enough of them that we might even provide a reasonable default:

class Interface { // version 3
public:
   virtual void do_A(int x) = 0;

   virtual void do_B(int x)
   {
      do_A(x >> 1);
      do_A(x >> 1);
   }

   void do_A_then_B(int x)
   {
      do_A(x);
      do_B(x);
   }
};

Now, the majority of interfaces that did implement do_A as above can now remove their implementation since the default is sufficient. Those that need another will override it.

Again, if the original interface is "good" how can this interface be "bad"? All we did was to provide a common default for one of the functions and so the people implementing the interface now has an easier job in that they only need to provide do_A() if this default satisfies their needs.

We eased the burden for implementors and we previously eased the burden for users. When did "ease the burden" imply "bad design"? Who is this design for anyway if it is not for the users and implementors?

I think you should rethink your definitions of "good O-O design" and "bad O-O design" and which is which. Stating that all interfaces with only pure virtual functions are good and all that contain one or more non-pure virtual functions are "bad" is simply too simplistic. After all "good" or "bad" design isn't a matter of counting the number of pure virtual functions or lack of such in an interface.

Alf
0
 

Expert Comment

by:locomojo
ID: 8025279
Salte:

You are right for most things...
But when you declare an Interface ...
You expect that any class that implement that interface
and referenced by the interface pointer...
the method that would be called is the one implemented in the class implements that interface...

I know that declaring and interface with some basic implementation of methods is common but it is a bad O-O desighn.

Interface should not implement anything instead of declarations.
0
 
LVL 12

Expert Comment

by:Salte
ID: 8025303
There's also a solution not using inheritance if you want. This problem though is the archetypical inheritance problem and so that is the most immediate and simple solution.

The other solution is to use templates:

let's say you have two classes:

class A1 {
private:
   ....
public:
   ....
   void func(int x);
   void func2(A1 * p, double x);
   ...
};

and

class A2 {
private:
   ....
public:
   ....
   void func(int x);
   void func2x(A2 * p, int x, int y);
};

Now, the func2 isn't exactly the same types since they have different argument types but that is of no problem for us. Virtual mechanism cannot handle that but using templates we can.

Define a class like this:

template <class T>
class An_traits;

// specialize on A1 and A2
template <>
class An_traits<A1> {
public:
   typedef double func2_arg2_type;
   static void func(A1 * p, int x)
   { p -> func(x); }

   static void func2(A1 * p, A1 * q, double x, int /* y */)
   { p -> func2(q,x); }
};

template <>
class An_traits<A2> {
public:
   typedef int func2_arg2_type;
   static void func(A2 * p, int x)
   { p -> func(x); }

   static void func2(A2 * p, A2 * q, int x, int y)
   { p -> func2x(q,x,y); }
};

Note that the functions in the original classes didn't even have to have the same name or a similar number of arguments.

Write a template function or class that can work on either class:

template <class A, class _traits = An_traits<A> >
class Ax {
public:
  typedef typename _traits traits_type;
  typedef typename traits_type::func2_arg_type f2_type;

  static void do_something(A & a)
  {
    f2_type v = f2_type();
    int y = 3;
    traits_type::func(& a,y);
    traits_type::func(& a, & a,v,y);
  }
};

If you have two classes:

A1 a1;
A2 a2;

Ax<A1>::do_something(& a1);
Ax<A2>::do_something(& a2);

will then call the corresponding functions from both A1 and A2.

Note that the traits types only have typedefs and static functions (enum values are also ok). It can even have static variables but no non-static stuff. You never actually instantiate the classes.

The traits types contain typedefs for the types that differ between the two functions. Also note that A1::func2() had only two arguments and so the third argument of the traits type function is ignored in this case. It is still defined so that its interface fit with the traits type for A2.

Btw, this is ALSO an interface, i.e. the traits types define some interface that allow you to handle the two classes in an identical manner and which allow you to define another template class (another interface) that allow you to manipulate either A1 or A2 through that interface. The Ax class is also not instantiated as done here since it too is only an interface to the real classes A1 and A2 and so only provide typedefs and static functions.

Alf
0
 
LVL 12

Expert Comment

by:rajeev_devin
ID: 8025393
Reply to locomojo:

Actually I like to go with the convension, not the compiler support. Its' just my opinion. Every programmer may have his likings and dislikings.

Regards
Rajeev
0
 

Expert Comment

by:locomojo
ID: 8025582
Well Good/Bad/Worse/Better is not issue here...
The point is if you look at the original question you will se that there was a solution which needed an extention..
so when you implement and interface it is a good practice to make it only declerative so you can extent it any time
even if you do not have the sources, oly libs or dlls.
So the so called interface will not over extend funtionality which was not intended... I mean
if a method declared in interface it should be pure virtual.
0
 
LVL 12

Expert Comment

by:Salte
ID: 8025607
locomojo,

There you go again:

"I know that declaring and interface with some basic implementation of methods is common but it is a bad O-O desighn."

Why on earth is it bad? I showed an argument as to why it's not bad so unless you explain why it is bad design I simply don't buy your argument.

What is "bad" and what is "good" O-O design? Appearantly to you it means something like:

If a design is exactly the way I think a "good" O-O design should be then the design is good, otherwise it is bad. I.e. you have some form of template as to what is "good O-O design" and if the design fall into that template it is "good" otherwise it isn't.

That may be your idea of good or bad design but the problem is twofold:

1. It is possible to make a design completely according to your specification and in your eyes it is "good" however, it may be a hopeless design that most people only feel frustration from using and every user of it would consider the design to be hopelessly bad. It is not difficult to make such a design, believe me, it's very easy!

2. It is also possible to make a design that isn't according to your idea of a "good O-O design" but the design work and people find it useful, extensible, just enough flexible to fill their needs but not so overly flexible that they loose sight. Such an interface is harder to make than the first but it isn't any more difficult than to write one that follow your "good O-O design". However, you would consider it "bad" but every user of it would consider it a "good" design.

Third, what is this idea about "good O-O design"? I know about "good" design and "bad" design and I know very well what object oriented programming and object oriented design is, but I really don't know what is "good O-O design". A bad design cannot be made good by making it object oriented and a good non-object oriented design wouldn't become bad if you made it object oriented. Good or bad design has - on the whole - very little to do with object orientation.

Also, it is possible to make a good O-O design also in languages like C where you don't even have pure virtual functions so how an interface can be a bad design just because it contain non-pure virtual functions is beyond me. For example the FILE * interface for C style FILE i/o is object oriented and has been used for such a long time that I guess you can safely say it is a good interface - it wouldn't be so popular if it was a bad design. However, you don't find a single pure virtual function in it.

Alf
0
 

Expert Comment

by:locomojo
ID: 8025646
Well Good/Bad/Worse/Better is not issue here...
The point is if you look at the original question you will se that there was a solution which needed an extention..
so when you implement and interface it is a good practice to make it only declerative so you can extent it any time
even if you do not have the sources, oly libs or dlls.
So the so called interface will not over extend funtionality which was not intended... I mean
if a method declared in interface it should be pure virtual.
0
 
LVL 12

Expert Comment

by:Salte
ID: 8026014
Locomojo,

I agree as far as the original question was, that good/bad/worse/better is not the issue and so we can let it lie. It is an interesting debate in itself though but I doubt this is the correct forum for such a debate.

I also believe the original question has been answered. The immediate and most obvious answer is to use inheritance. Another - perhaps not so obvius - solution is to use templates. Templates are better in that they do not require the functions to have the same parameters or type. Templates work on 'concepts', as long as the classes are the same on a conceptual level and you have two member functions (or non-member functions) that operate on the two classes in a conceptually identical manner, i.e. they "do the same job for their respective classes" then you can use templates.

For example if you say that type A and type B are both comparable and this function x is to work on any comparable type T, then you can make a template function:

template <class T> class comparer;

template <class T, class Comp = comparer<T> >
T * find(T a[], int n, const T & e)
{
   int L = 0;
   int H = n;
   while (L < H) {
      int M = (L + H) >> 1; // M is middle point.
      int x = Comp::compare(a[M],e);
      if (x == 0)
         return & a[M]; // found it!
      if (x < 0) // a[M] < e, set L = M + 1.
         L = M + 1;
      else // a[M] > e, set H = M - 1.
         H = M - 1;
  }
  return 0; // not found.
}

This function does binary search on a sorted array of ANY type, the only thing we require of the type is that there is a companion type that have a static function to compare elements of the type.

template <>
class comparer<const char *> {
public:
   static int compare(const char * a, const char * b)
   { return strcmp(a,b); }
};

will be a default comparer for const char * objects so an array of strings can now be searched using find above.

If you want to do a compare without case:

template <>
class no_case_comparer<const char *> {
public:
   static int compare(const char * a, const char * b)
   { return stricmp(a,b); }
};

if you want to do compare on integer values instead:

template <>
class comparer<int> {
public:
   static int compare(int a, int b)
   { return a < b ? -1 : a > b; }
};

if you have a sorted array of strings (sorted while ignoring case) you can call find:

const char ** s = find<const char *,no_case_comparer<const char *>(sorted_table,"hello");

if you have an sorted array of string (not ignoring case)
you can call find:

const char ** s2 = find(another_sorted_table,"world");

if you have an array of int values:

int * p = find(int_table, 3);

etc.

Now, you might even want to consider not having the compare function there, after all most basic types already have a less than etc operator, but you can also provide one for all that aren't otherwise specialized:

template <class T>
class comparer {
public:
   static int compare(const T & a, const T & b)
   { return a < b ? -1 : b < a; }
};

This class assumes that for any two a and b you have:

a < b || a == b || a > b

so if ! (a < b) && ! (a > b) then you must have a == b.

For some types such an assumption isn't valid and then you
cannot use that type for the binary search as written above. The binary search algorithm also assumes the same thing.

Note that this template class for comparer allows you to compare any two elements of any type provided the type implement the less than operator. It doesn't require anything more.

This provides a huge flexibility and allows a user to use the function for many types and if he has a type and he wants to do binary search on it all he has to do is implement the operator < for the type.

Also, since the comparer is an argument to find, the caller can also provide a non-default compare function if he wants to compare the values in a different manner, for example for a sorting function the compare will typically sort the elements in ascending order, but you can create a reverse comparer that sort in descending order:

template <class T, class _comp = comparer<T> >
class reverse_comparer {
public:
   static int compare(const T & a, const T & b)
   { return _comp::compare(b,a); }
};

Now using reverse_comparer as argument to the sort algorithm will sort the elements in descending order. The only thing we require is that 1. the sort function takes a comparer argument as second template argument and 2. There is a comparer that would sort the array in ascending order.

sort<int, reverse_comparer<int> >(table,num_elems);

will then sort an integer array in descending order.

Note that used this way the comparer is also an interface, it contain a function compare() that takes two elements of type T and return a value > 0 if a > b, a negative int value if a < b and the value 0 if a == b. Each specialization of that template is an implementation of that interface.

Alf
0
 
LVL 11

Expert Comment

by:bcladd
ID: 9846101
No comment has been added lately, so it's time to clean up this TA. I will
leave a recommendation in the Cleanup topic area that this question is:

Answered: Points split between Fallen_Knight and locomojo

Please leave any comments here within the next seven days.

Experts: Silence means you don't care. Grading recommendations are made in light
of the posted grading guidlines (http://www.experts-exchange.com/help.jsp#hi73).

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

-bcl (bcladd)
EE Cleanup Volunteer
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.

801 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question