Categories: MSDN / DotNet / Java / Scripts / Linux / PHP Ask - La ask - La Answer

get() set() ?

Hello,

I have a problem with setting and getting values.

My code is as follows :-

#include <iostream>
#include <string>

using namespace std;

class Meal
{
private:
string m_starter;

public:
virtual ~Meal() {}

const string& set_m_starter()
{
// here I want m_starter to be the value returned from get_m_starter()
}
void print()
{
cout << "Starter = " << m_starter << "\n";
}
};

class Vegan : public Meal
{
private:
string first;
public:
Vegan()
{
first = "Asparagus";
}
const string& get_m_starter() const { return first; }
};

class CourseFactory
{
public:
virtual Meal* createMeal() const = 0;
};

class VeganFactory : public CourseFactory
{
public:
Meal* createMeal() const { return new Vegan; }
};

int main( void )
{

CourseFactory* pFactory;

pFactory = new VeganFactory;
Meal* pMeal = pFactory->createMeal();

delete pFactory;

return 0;
}

I want to be able to capture the "Asparagus" in Vegan class and initiliase m_starter variable of Meal with it.

I know I can use protected and then I have no problem, but is there a nicer way leaving the AbstractFactory design pattern as it is ? I thought about RTTI, but I cannot get this to work.

Can someone please help ?
[1570 byte] By [ami] at [2007-11-11 9:57:29]
# 1 Re: get() set() ?
You can't call a member function that doesn't exist in the base class from a pointer to a base class (pMeal) even if pMeal's dynamic type is Vegan. You will have to define a virtual set() function in the base class, and Vegan override it. Then, pMeal can call that virtual function.
Alternatively, you can dynamic_cast pMeal to Vegan* but that's inelegant, as you already pointed out.
Danny at 2007-11-11 20:59:46 >
# 2 Re: get() set() ?
Thanks Danny, but even if I create a set() and override it, how will I get to display private member variables of Meal ? I mean, I'm at Vegan level of the hierarchy and want to set there Meal's private members values. I know I can use protected, but that's probably not very nice..
ami at 2007-11-11 21:00:46 >
# 3 Re: get() set() ?
Well, the fact that you can't do that easily more than suggests that it's a bad idea. Why would a derived object set the members of its parent object? Each object has to set its own private data. An no, I'm not implying that the string member should be protected. Protected data members are evil.
You can have a member function in Vegan that calls a member function in Meal like this:
Vega::set() { this->Meal::set("something");}

However, this design is questionable. Perhaps you should consider giving up set() and make sure that each constructor calls Meal::set with a new value. Alternatively, you can simply define a virtual get() function that returns the name of the class without using a private data member. After all, the string data member has no real purpose other than reporting the class name, so you can simply remove the string and the set functions, and define a virtual get() const { return "myname";}
Danny at 2007-11-11 21:01:50 >