none
error LNK2005 on static class variable

    Question

  • Hi again,

    I am getting this linker error below and could not quite figure out why.  It seems that the linker is saying I declared my static class variable OptionFactory EuropeanCall::MyFactory mutliple times.  Perhaps it is the way I am declaring it inside VanillaOptions.h?  I am rather new to C++ so it is not obvious to me.

    Thank you for any help!

     

    Linking...
    OptionFactory.obj : error LNK2005: "public: static class OptionFactory<class BaseOption,class EuropeanCall> EuropeanCall::MyFactory" (?MyFactory@EuropeanCall@@2V?$OptionFactory@VBaseOption@@VEuropeanCall@@@@A) already defined in MCMain.obj
    VanillaOptions.obj : error LNK2005: "public: static class OptionFactory<class BaseOption,class EuropeanCall> EuropeanCall::MyFactory" (?MyFactory@EuropeanCall@@2V?$OptionFactory@VBaseOption@@VEuropeanCall@@@@A) already defined in MCMain.obj
    InitializeOptionFactory.obj : error LNK2005: "public: static class OptionFactory<class BaseOption,class EuropeanCall> EuropeanCall::MyFactory" (?MyFactory@EuropeanCall@@2V?$OptionFactory@VBaseOption@@VEuropeanCall@@@@A) already defined in MCMain.obj
    C:\tmp\CPP\Calvin\MC_VS_2005\MC\Debug\MC.exe : fatal error LNK1169: one or more multiply defined symbols found

     

    //OptionFactory.h
    //Creates new option based on the choice user made from menu

    #ifndef OPTIONFACTORY_
    #define OPTIONFACTORY_

    #include <string>

    template <class OptionType>
    class OptionFactoryTemplate
    {
    public:
     OptionFactoryTemplate(){};
     virtual ~OptionFactoryTemplate(){};
     virtual OptionType* CreateOption()=0;
    };

    template <class OptionType, class NewOption>
    class OptionFactory : public OptionFactoryTemplate<OptionType>
    {
    public:
     OptionFactory(){};
     virtual ~OptionFactory(){};
     virtual OptionType* CreateOption();
    };

    #endif

     

    //BaseOption.h
    //Define attributes and functions of a base option

    #ifndef BASEOPTION_
    #define BASEOPTION_

    #include <map>
    #include <OptionFactory.h>

    class BaseOption
    {
    private:
     double Strike, Expiration, RiskFreeRate, Price, Delta, Gamma, Vega, Theta;
    public:
     BaseOption();      //Constructor
     virtual ~BaseOption(){};    //Virtual destructor
     typedef OptionFactoryTemplate<BaseOption> BaseOptionFactory; //Baseoption factory
    };

    //Declare the global static option factory map
    static std::map<std::string, BaseOption::BaseOptionFactory *> OptionFactoryMap;

    #endif

     

    //VanillaOptions.h
    //Define all vanilla options, defined as single asset, non-path dependent options
    //Includes : European Call/Put, Digial Call/Put on a single underlying

    #ifndef VANILLAOPTIONS_
    #define VANILLAOPTIONS_

    #include <BaseOption.h>
    #include <OptionFactory.h>

    class EuropeanCall : public BaseOption
    {
    private:
     BaseAsset UAsset; //Underlying asset
    public:
     EuropeanCall();
     ~EuropeanCall(){};
     static OptionFactory<BaseOption, EuropeanCall> MyFactory;
     virtual BaseAsset GetUAsset() const;
    };

    OptionFactory<BaseOption, EuropeanCall> EuropeanCall::MyFactory;

    #endif

     

    //MCMain.cpp
    #include <MonteCarlo.h>
    #include <UserInterface.h>
    #include <VanillaOptions.h>
    #include <iostream>

    void main()

     UserInterface ui;   //User interface object
     std::string OptionChoice;

     //Output user interface to pick option choice until user chooses to stop
     do {
      OptionChoice = ui.MenuPickOption();
     } while (ui.AskKeepGoing());

    }

    Sunday, October 1, 2006 4:12 PM

Answers

  • You are defining the static variable in a header file that means that each *.cpp file that includes this header file defines its own definition. You should define the static data member in a single *.cpp file.
    Sunday, October 1, 2006 4:22 PM
    Moderator

All replies

  • You are defining the static variable in a header file that means that each *.cpp file that includes this header file defines its own definition. You should define the static data member in a single *.cpp file.
    Sunday, October 1, 2006 4:22 PM
    Moderator
  • Hi Jonathan,

    First thank you for the feedback.  I had thought about what you said myself, but I also thought that since I included #ifndef in the beginning of the include file, it would not do multiple declaration.  Am I not undertanding this concept correctly?

    Calvin

    Sunday, October 1, 2006 4:47 PM
  • The #ifndef trick means that the header file will not be included multiple times within one compilation unit. The header file will still be included by each compiliation unit (*.cpp file) and hence you will have multiple definitions.
    Sunday, October 1, 2006 6:19 PM
    Moderator