Newbie: Subclassing a <map> value.

T

twisteddweeb

Trying to learn the basics & this one has me stumped. Goggle hasn't
been too much help either.

How can I change the following so that it's the subclass's () operator
that gets called rather than the base class's () operator?

====================================================
#include <iostream>
#include <map>
using namespace std;

class BaseClass {
public:
void operator () (void) {
cout << "I don't want this to print\n";
}
};

class SubClass : public BaseClass {
public:
void operator () (void) {
cout << "I want this to print\n:";
}
};

int main(int argc, char** argv) {
map<int, BaseClass> table;
map<int, BaseClass>::iterator pos;

SubClass action;

//table.insert(pair<int, BaseClass>(1, action));
table.insert(pair<int, SubClass>(1, action));

pos = table.find(1);
pos->second();

return 0;
}
==================================================
Program output...

$ make && ./test
g++ -Wall -o test test.cc
I don't want this to print

==================================================
Yes, I've tried virtual functions... I've tried everything that
doesn't work ;)

If this is a FAQ, I apologize.

thanks
dweeb
 
J

John Harrison

Trying to learn the basics & this one has me stumped. Goggle hasn't
been too much help either.

How can I change the following so that it's the subclass's () operator
that gets called rather than the base class's () operator?

====================================================
#include <iostream>
#include <map>
using namespace std;

class BaseClass {
public:
void operator () (void) {
cout << "I don't want this to print\n";
}
};

class SubClass : public BaseClass {
public:
void operator () (void) {
cout << "I want this to print\n:";
}
};

int main(int argc, char** argv) {
map<int, BaseClass> table;
map<int, BaseClass>::iterator pos;

SubClass action;

//table.insert(pair<int, BaseClass>(1, action));
table.insert(pair<int, SubClass>(1, action));

pos = table.find(1);
pos->second();

return 0;
}
==================================================
Program output...

$ make && ./test
g++ -Wall -o test test.cc
I don't want this to print

==================================================
Yes, I've tried virtual functions... I've tried everything that
doesn't work ;)

Nothing works, because you are storing BaseClass objects in your map. If you
store a BaseClass object then the only method that gets called is a
BaseClass method.

Effectively you are doing this

BaseClass b;
SubClass c;
b = c;
b(); // of course BaseClass::eek:perator() get called.

Polymorphism only works in C++ if you use pointers or references. Store
pointer to a BaseClass in your map and make operator() virtual and it will
work.

John
 
V

Victor Bazarov

Trying to learn the basics & this one has me stumped. Goggle hasn't
been too much help either.

How can I change the following so that it's the subclass's () operator
that gets called rather than the base class's () operator?

====================================================
#include <iostream>
#include <map>
using namespace std;

class BaseClass {
public:
void operator () (void) {

virtual void operator () (void) {
cout << "I don't want this to print\n";
}
};

class SubClass : public BaseClass {
public:
void operator () (void) {
cout << "I want this to print\n:";
}
};

int main(int argc, char** argv) {
map<int, BaseClass> table;

map said:
map<int, BaseClass>::iterator pos;

map said:
SubClass action;

//table.insert(pair<int, BaseClass>(1, action));
table.insert(pair<int, SubClass>(1, action));

table.insert(pair said:
pos = table.find(1);
pos->second();

return 0;
}
==================================================
Program output...

$ make && ./test
g++ -Wall -o test test.cc
I don't want this to print

==================================================
Yes, I've tried virtual functions... I've tried everything that
doesn't work ;)

If this is a FAQ, I apologize.

It is and it isn't. No biggie.

Victor
 
T

twisteddweeb

John & Victor,

Very clear explanations.

In this case the operator () turns the map access into a butt ugly
notation: (*(pos->second))();

This seems clearer: pos->second->Act();

Now that I've learned *how* I'll have to figure out if this is a
reasonable OO factorization. But that's another issue entirely.

Thanks to both.

dweeb
 
J

John Harrison

John & Victor,

Very clear explanations.

In this case the operator () turns the map access into a butt ugly
notation: (*(pos->second))();

This seems clearer: pos->second->Act();

Now that I've learned *how* I'll have to figure out if this is a
reasonable OO factorization. But that's another issue entirely.

Thanks to both.

dweeb

You could write another class

class BaseClassPointer
{
void operator()()
{
(*ptr)();
}
BaseClass* ptr;
};

Then put BaseClassPointer instead of BaseClass* into your map.

john
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,175
Latest member
Vinay Kumar_ Nevatia
Top