Bonjour,

Lorsque je compile le code ci-dessous j'obtiens les messages d'erreur suivant:
1>Generating Code...
1>Compiling...
1>SimpleMC.cpp
1>Generating Code...
1>Linking...
1>SimpleMCMain2.obj : error LNK2005: "protected: virtual void __thiscall debugFlowTracer::AddFlow(void)" (?AddFlow@debugFlowTracer@@MAEXXZ) already defined in SimpleMC.obj
1>SimpleMCMain2.obj : error LNK2005: "protected: virtual void __thiscall debugFlowTracer::RemoveFlow(void)" (?RemoveFlow@debugFlowTracer@@MAEXXZ) already defined in SimpleMC.obj
1>SimpleMCMain2.obj : error LNK2005: "private: static class debugFlowTracerManager * debugFlowTracerManager::m_Instance" (?m_Instance@debugFlowTracerManager@@0PAV1@A) already defined in SimpleMC.obj
1>C:\MoonDragon\DistanceLearning\cpp\code\Chap2\Debug\Chap2.exe : fatal error LNK1169: one or more multiply defined symbols found
1>Build log was saved at "file://c:\MoonDragon\DistanceLearning\cpp\code\Chap2\Chap2\Debug\BuildLog.htm"
1>Chap2 - 4 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========


SimpleMC.cpp :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <SimpleMC.h>
#include <Random1.h>
#include <cmath>
 
#include "FlowTracerManager.h"
 
// the basic math functions should be in namespace std but aren't in VCPP6
#if !defined(_MSC_VER)
using namespace std;
#endif
 
double SimpleMonteCarlo2(const PayOff& thePayOff,
                         double Expiry,  
						 double Spot, 
						 double Vol, 
						 double r, 
						 unsigned long NumberOfPaths)
{
	debugFlowTracer flow("SimpleMonteCarlo2");
 
 
	double variance = Vol*Vol*Expiry;
	double rootVariance = sqrt(variance);
	double itoCorrection = -0.5*variance;
 
	double movedSpot = Spot*exp(r*Expiry +itoCorrection);
	double thisSpot;
	double runningSum=0;
 
	for (unsigned long i=0; i < NumberOfPaths; i++)
	{
		double thisGaussian = GetOneGaussianByBoxMuller();
		thisSpot = movedSpot*exp( rootVariance*thisGaussian);
		double thisPayOff = thePayOff(thisSpot);
		runningSum += thisPayOff;
	}
 
	double mean = runningSum / NumberOfPaths;
	mean *= exp(-r*Expiry);
	return mean;
}

SimpleMCMain.cpp :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include<SimpleMC.h>
#include<iostream>
#include "FlowTracerManager.h"
 
using namespace std;
 
int main()
{
 
	debugFlowTracer flow("main");
 
	double Expiry;
	double Strike; 
	double Spot; 
	double Vol; 
	double r; 
	unsigned long NumberOfPaths;
 
	cout << "\nEnter expiry\n";
	cin >> Expiry;
 
	cout << "\nEnter strike\n";
	cin >> Strike;
 
	cout << "\nEnter spot\n";
	cin >> Spot;
 
	cout << "\nEnter vol\n";
	cin >> Vol;
 
	cout << "\nr\n";
	cin >> r;
 
	cout << "\nNumber of paths\n";
	cin >> NumberOfPaths;
 
	PayOff callPayOff(Strike, PayOff::call);
	PayOff putPayOff(Strike, PayOff::put);
 
	double resultCall = SimpleMonteCarlo2(callPayOff,
                                          Expiry,                                           
							              Spot, 
							              Vol, 
							              r, 
						                  NumberOfPaths);
 
    double resultPut = SimpleMonteCarlo2(putPayOff,
                                         Expiry,                                           
							             Spot, 
							             Vol, 
							             r, 
						                 NumberOfPaths);
 
	cout <<"the prices are " << resultCall << "  for the call and " 
                                    << resultPut << " for the put\n";
 
    double tmp;
    cin >> tmp;
 
	return 0;
 
}

FlowTracerManager.h :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
 
#ifndef FLOWTRACERMANAGER_H
#define FLOWTRACERMANAGER_H
 
#include "FlowTracer.h"
 
class debugFlowTracerManager
{
private:
	std::stack< debugFlowTracer> m_functionStack;
	static debugFlowTracerManager *m_Instance;
 
public:
	static debugFlowTracerManager *Instance()
	{
		if ( m_Instance == NULL )
			m_Instance = new debugFlowTracerManager();
		return m_Instance;
	}
	void addFlow( debugFlowTracer& cFlow )
	{
		m_functionStack.push( cFlow );
	}
	void removeFlow(debugFlowTracer& cFlow)
	{
		if ( m_functionStack.empty() )
			return;
 
		// Get the top element
		debugFlowTracer t = m_functionStack.top();
 
		// Remove it.
		m_functionStack.pop();
 
		// If there is anything left, add it
		if ( m_functionStack.empty() )
		{
			printf("Flow [%s]:\n", t.Name().c_str() );
			t.PrintStack(0);
		}
		else
			m_functionStack.top().AddSubFlow( t );
 
	}
 
private:
	debugFlowTracerManager()
	{
	}
	debugFlowTracerManager(const debugFlowTracerManager& aCopy )
	{
	}
	virtual ~debugFlowTracerManager(void)
	{
	}
};
 
debugFlowTracerManager *debugFlowTracerManager::m_Instance = NULL;
 
void debugFlowTracer::AddFlow()
{
	debugFlowTracerManager::Instance()->addFlow( *this );
}
 
void debugFlowTracer::RemoveFlow()
{
	debugFlowTracerManager::Instance()->removeFlow( *this );
}
 
#endif


FlowTracer.h :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
 
#ifndef _FLOWTRACER_H_
#define _FLOWTRACER_H_
 
#include <string>
#include <stack>
#include <vector>
 
class debugFlowTracer
{
private:
	std::string m_sFlowName;
	std::vector< debugFlowTracer > m_activefunctionStack;
	bool						   m_bRemoved;
protected:
	virtual void AddFlow();
	virtual void RemoveFlow();
 
public:
	debugFlowTracer(void)
	{
		m_sFlowName = "Unknown";
		m_bRemoved = false;
		AddFlow();
	}
 
	debugFlowTracer(const char *strFlow)
	{
		m_sFlowName = strFlow;
		m_bRemoved = false;
		AddFlow();
	}
	debugFlowTracer( const debugFlowTracer& aCopy )
	{
		m_sFlowName = aCopy.m_sFlowName;
		std::vector< debugFlowTracer >::const_iterator iter;
		for ( iter = aCopy.m_activefunctionStack.begin(); iter != aCopy.m_activefunctionStack.end(); ++iter )
			m_activefunctionStack.insert( m_activefunctionStack.end(), (*iter) );
	}
 
 
	~debugFlowTracer(void)
	{
		if ( !m_bRemoved )
			RemoveFlow();
		m_bRemoved = true;
	}
 
	std::string Name()
	{
		return m_sFlowName;
	}
 
	void AddSubFlow( debugFlowTracer& cSubFlow )
	{
		// Just push it on top of the active function stack
		m_activefunctionStack.insert( m_activefunctionStack.end(), cSubFlow );
	}
	void PrintStack(int iLevel)
	{
		std::vector< debugFlowTracer >::iterator iter;
		for ( iter = m_activefunctionStack.begin(); iter != m_activefunctionStack.end(); ++iter )
		{
			for ( int i=0; i<iLevel; ++i )
				putchar ('\t');
			printf("%s\n", (*iter).Name().c_str() );
			(*iter).PrintStack(iLevel+1);
		}
	}
};
 
 
 
 
 
#endif