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
Partager