E
Ed
Let's say I to classes, SuperClass and SubClass (the latter a sub class of the former). I have a vector of SubClasses, but I want to pass them to an API method somewhere that requires a vector of SuperClasses. What is the easiest way for me to go about passing the vector<SubClass> I have on hand to the API method which requires a vector<SuperClass>?
The code I'm working on is a little to convoluted right now to past in, so I came up with what I believe to be an equivalent example in a much more simplified problem domain. In the example, I have a Greeter class that knows how to greet someone. There are specialized version of this class that knowhow to greet males and females (MaleGreeter and FemaleGreeter respectively). My question is, how do I achieve what I am trying to achieve in the commented out line (it won't compile with this line uncommented):
greetAll(maleGreeters);
Please forgive me for compiling my code against Boost in this example. I don't have a C++ 11 compliant compiler yet. I believe the classes I'm using from boost are included in the new C++ 11 standard (I recognize that this list is for standard C++ questions only).
Anyway, here's the code (followed by a short explanation of the real problem I'm trying to solve):
#include <iostream>
#include <string>
#include <vector>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
using std::cout; using std::endl;
using std::string; using std::vector;
using boost::shared_ptr; using boost::make_shared;
/*
* Greeter
*/
class Greeter{
public:
Greeter(string ln);
string greet();
virtual string getFormalAddress(string lastName) = 0;
protected:
string lastName;
};
Greeter::Greeter(string ln){
lastName = ln;
}
string Greeter::greet(){
return "Hello " + getFormalAddress(lastName);
}
/*
* MaleGreeter
*/
class MaleGreeter : public Greeter{
public:
MaleGreeter(string ln);
string getFormalAddress(string lastName);
};
MaleGreeter::MaleGreeter(string ln) : Greeter(ln) {}
string MaleGreeter::getFormalAddress(string lastName){
return "Mr. " + lastName;
}
/*
* FemaleGreeter
*/
class FemaleGreeter : public Greeter{
public:
FemaleGreeter(string ln);
string getFormalAddress(string lastName);
};
FemaleGreeter::FemaleGreeter(string ln) : Greeter(ln) {}
string FemaleGreeter::getFormalAddress(string lastName){
return "Ms. " + lastName;
}
/*
* greetAll()
*/
void greetAll(vector<shared_ptr<Greeter> > greeters);
void greetAll(vector<shared_ptr<Greeter> > greeters){
for( vector<shared_ptr<Greeter> >::iterator i = greeters.begin();
i != greeters.end(); i++){
cout << (*i)->greet() << endl;
}
}
/*
* main()
*/
int main(int argc, char** argv){
//Example 1
shared_ptr<Greeter> g = make_shared<MaleGreeter>(string("MacDonald"));
cout << g->greet() << endl << endl;
//Example 2
vector<shared_ptr<Greeter> > greeters;
greeters.push_back(make_shared<MaleGreeter>("Jones"));
greeters.push_back(make_shared<FemaleGreeter>("Doe"));
greeters.push_back(make_shared<MaleGreeter>("Smith"));
greeters.push_back(make_shared<FemaleGreeter>("Johnson"));
greetAll(greeters);
cout << endl;
//Example 3
vector<shared_ptr<MaleGreeter> > maleGreeters;
greeters.push_back(make_shared<MaleGreeter>("Jones"));
greeters.push_back(make_shared<MaleGreeter>("Smith"));
//How do I make this line work?
//greetAll(maleGreeters);
}
// End of code
So, the real problem I'm trying to solve is that I'm trying to write a chess rules engine. In my code, I have a representation of a chess board in a Board class of my own making. The representation in the Board class of the actual board is a member variable of this type:
vector<vector<shared_ptr<Square> > >
where Square is another class of my making. Square extends a virtual class,AsciiRenderable. AsciiRenderables are passed to an AsciiRendering framework which I intend to have print the representation of the board out on the terminal.
In other words, I wish the framework to operate on things with this signature:
vector<vector<shared_ptr<AsciiRenderable> > >
and Ideally, I would like to have it believe that
vector<vector<shared_ptr<Square> > > ISA vector<vector<shared_ptr<AsciiRenderable> > >
As I write this, I do realize that the ISA relationship there cannot be true because you can add elements to the latter that cannot be elements of theformer (anything that is AsciiRenderable yet not a Square). But is there asimple way to achieve what I seek?
Thanks,
Ed
The code I'm working on is a little to convoluted right now to past in, so I came up with what I believe to be an equivalent example in a much more simplified problem domain. In the example, I have a Greeter class that knows how to greet someone. There are specialized version of this class that knowhow to greet males and females (MaleGreeter and FemaleGreeter respectively). My question is, how do I achieve what I am trying to achieve in the commented out line (it won't compile with this line uncommented):
greetAll(maleGreeters);
Please forgive me for compiling my code against Boost in this example. I don't have a C++ 11 compliant compiler yet. I believe the classes I'm using from boost are included in the new C++ 11 standard (I recognize that this list is for standard C++ questions only).
Anyway, here's the code (followed by a short explanation of the real problem I'm trying to solve):
#include <iostream>
#include <string>
#include <vector>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
using std::cout; using std::endl;
using std::string; using std::vector;
using boost::shared_ptr; using boost::make_shared;
/*
* Greeter
*/
class Greeter{
public:
Greeter(string ln);
string greet();
virtual string getFormalAddress(string lastName) = 0;
protected:
string lastName;
};
Greeter::Greeter(string ln){
lastName = ln;
}
string Greeter::greet(){
return "Hello " + getFormalAddress(lastName);
}
/*
* MaleGreeter
*/
class MaleGreeter : public Greeter{
public:
MaleGreeter(string ln);
string getFormalAddress(string lastName);
};
MaleGreeter::MaleGreeter(string ln) : Greeter(ln) {}
string MaleGreeter::getFormalAddress(string lastName){
return "Mr. " + lastName;
}
/*
* FemaleGreeter
*/
class FemaleGreeter : public Greeter{
public:
FemaleGreeter(string ln);
string getFormalAddress(string lastName);
};
FemaleGreeter::FemaleGreeter(string ln) : Greeter(ln) {}
string FemaleGreeter::getFormalAddress(string lastName){
return "Ms. " + lastName;
}
/*
* greetAll()
*/
void greetAll(vector<shared_ptr<Greeter> > greeters);
void greetAll(vector<shared_ptr<Greeter> > greeters){
for( vector<shared_ptr<Greeter> >::iterator i = greeters.begin();
i != greeters.end(); i++){
cout << (*i)->greet() << endl;
}
}
/*
* main()
*/
int main(int argc, char** argv){
//Example 1
shared_ptr<Greeter> g = make_shared<MaleGreeter>(string("MacDonald"));
cout << g->greet() << endl << endl;
//Example 2
vector<shared_ptr<Greeter> > greeters;
greeters.push_back(make_shared<MaleGreeter>("Jones"));
greeters.push_back(make_shared<FemaleGreeter>("Doe"));
greeters.push_back(make_shared<MaleGreeter>("Smith"));
greeters.push_back(make_shared<FemaleGreeter>("Johnson"));
greetAll(greeters);
cout << endl;
//Example 3
vector<shared_ptr<MaleGreeter> > maleGreeters;
greeters.push_back(make_shared<MaleGreeter>("Jones"));
greeters.push_back(make_shared<MaleGreeter>("Smith"));
//How do I make this line work?
//greetAll(maleGreeters);
}
// End of code
So, the real problem I'm trying to solve is that I'm trying to write a chess rules engine. In my code, I have a representation of a chess board in a Board class of my own making. The representation in the Board class of the actual board is a member variable of this type:
vector<vector<shared_ptr<Square> > >
where Square is another class of my making. Square extends a virtual class,AsciiRenderable. AsciiRenderables are passed to an AsciiRendering framework which I intend to have print the representation of the board out on the terminal.
In other words, I wish the framework to operate on things with this signature:
vector<vector<shared_ptr<AsciiRenderable> > >
and Ideally, I would like to have it believe that
vector<vector<shared_ptr<Square> > > ISA vector<vector<shared_ptr<AsciiRenderable> > >
As I write this, I do realize that the ISA relationship there cannot be true because you can add elements to the latter that cannot be elements of theformer (anything that is AsciiRenderable yet not a Square). But is there asimple way to achieve what I seek?
Thanks,
Ed