Monostate Data Members

Mar 13, 2012 at 2:00am
Hi

I'm doing an exercise to convert an existing Factory Pattern implemented with the Singleton Pattern into a Factory Pattern implemented with the Monostate Pattern.

The Factory Pattern has 3 data members, 1) a string, 2) a double, and 3) a map.

The problem I've run into is in trying to make all the data members static, I don't know how make a data member of type map static. Doing so results in LNK2001 errors on compile. I'm not 100% as to why but my guess is that it's due to map being a variable container?

How can I make the map data member static?

Thanks
Mar 13, 2012 at 7:50am
1
2
3
4
5
class MyClass {
   static std::map<foo, bar> my_map;
};

std::map<foo, bar> MyClass::my_map;

This should work. I'm guessing you forgot that last line. If you didn't, you'll have to show the code.
Mar 13, 2012 at 11:27am
thank you, I did indeed.

but where is the last line supposed to go and what does it achieve?
Mar 13, 2012 at 11:37am
i thought i'd just post my code anyway. thanks again.

Header
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class PayOffFactory2
{
public:
	PayOffFactory2(){}
	PayOffFactory2(const PayOffFactory2&){}
	
	typedef PayOff* (*CreatePayOffFunction)(double);
	
	void RegisterPayOff(string, CreatePayOffFunction);
	PayOff* CreatePayOff(string PayOffId, double Strike);

	PayOffFactory2& operator=(const PayOffFactory2&)
	{
		return *this;
	}
	~PayOffFactory2(){}
	
private:
	static map<string, CreatePayOffFunction> TheCreatorFunctions;
	static string PayOffId;
	static double Strike;
};


Source
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
void PayOffFactory2::RegisterPayOff(
	string PayOffId,
	CreatePayOffFunction CreatorFunction)
{	
	map<string, CreatePayOffFunction> TheCreatorFunctions; // <==?
	TheCreatorFunctions.insert(
		pair<string, CreatePayOffFunction>
			(PayOffId, CreatorFunction));
}

PayOff* PayOffFactory2::CreatePayOff(
	string PayOffId,
	double Strike)
{
	// Retrieve the requested PayOff
	map<string, CreatePayOffFunction>::const_iterator
		i = TheCreatorFunctions.find(PayOffId);

	if (i == TheCreatorFunctions.end())
	{
		cout << PayOffId<<" is an unknown payoff"<<endl;
		return NULL;
	}

	return (i->second)(Strike);
}

Mar 13, 2012 at 11:38am
The last line should go in an implementation file (cpp.)

In the class definition, the line is a declaration.

In the implementation file you supply the definition.
Mar 13, 2012 at 12:01pm
Thanks.

Relating back to the overarching problem, RegisterPayOff() is not working as when CreatePayOff() is called, the PayOffFactory object can't find the PayOffId in TheCreatorFunctions. I thought the problem might be because I don't have all the data members as static yet.

So does the line initialise (or create?) another instance of TheCreatorFunctions? My vague understanding of static data members was that they come into existence the moment they are declared (and so aren't defined).

Then have I inserted the line in right place above? Another compile error LNK1120 is reported.

Last edited on Mar 13, 2012 at 12:34pm
Mar 13, 2012 at 1:05pm
In RegisterPayOff() you create a local object TheCreatorFunctions. This object goes out of scope when the function returns.

The map should be defined at file scope (outside of any functions, just like you would define a global variable.)
Last edited on Mar 13, 2012 at 1:05pm
Mar 13, 2012 at 1:49pm
As cire stated the static members must go to the implementation file. And you need to initialize them there.

That you don't get a link errror according to 'PayOffId' and 'Strike' are missing means that you never use this variables.
Mar 13, 2012 at 9:43pm
ahhh thank you all for your help. that makes a lot more sense now!
Topic archived. No new replies allowed.