Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to initialize a static member object?

Tags:

c++

static

I didn't know that I didn't know this :) . and a similar question here didn't help much.

So here i am asking. Please Consider the following class:

//in Agent.h
class Agent : public ns3::Object{
private:
//...

    static BaseWifi m_wifi;

//...
};

is this :

//Agent.cpp
BaseWifi temp;
BaseWifi Agent::m_wifi = temp;

very much different from this:

//Agent.cpp
BaseWifi Agent::m_wifi = BaseWifi();

The second approach doesn't work for me. why and how?

I don't want to trouble you with more codes coz I faced this problem deep in my program. The program generate seg faults as things(members) inside BaseWifi's constructor are not initialized correctly. when those uninitialized internal members are used, seg faults occur.

Thank you in advance for your kind comments and answers.

p.s.: In fact I found this issue when I hadn't yet initialized this static member and I was deleting an extra line :

BaseWifi temp;

in my main(), which added more to my confusion!!!(this one could be dependent on what I put in BaseWifi's constructor, so dont mind it for now)

Update-1: For those who would like to see the BaseWifi:

class BaseWifi {
    ns3::WifiHelper m_wifiHelper; // a wifi helper apply to setup vehicles Wifi

    ns3::NqosWifiMacHelper m_wifiMacHelper; // a wifi mac helper apply to setup vehicles Wifi

    ns3::YansWifiPhyHelper m_wifiPhyHelper; // a wifi phy helper apply to setup vehicles Wifi

    std::string m_phyMode;

    double m_rss;  // -dBm

    bool m_init_done;

public:

    BaseWifi();

    virtual void init();

    ns3::NetDeviceContainer Install(ns3::NodeContainer &c);

    virtual ~BaseWifi();
};

BaseWifi::BaseWifi() {
    m_init_done = false;
    m_rss = -80;
    m_phyMode ="DsssRate1Mbps";
    // TODO Auto-generated constructor stub
    init();
}

void BaseWifi::init() {
    NS_LOG_UNCOND("inside BaseWifi::init()");
      m_wifiHelper.SetStandard (ns3::WIFI_PHY_STANDARD_80211b);

      m_wifiPhyHelper =  ns3::YansWifiPhyHelper::Default ();

      // This is one parameter that matters when using FixedRssLossModel
      // set it to zero; otherwise, gain will be added
      m_wifiPhyHelper.Set ("RxGain", ns3::DoubleValue (0) );

      // ns-3 supports RadioTap and Prism tracing extensions for 802.11b
      m_wifiPhyHelper.SetPcapDataLinkType (ns3::YansWifiPhyHelper::DLT_IEEE802_11_RADIO);

      ns3::YansWifiChannelHelper wifiChannel;

      wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");

      // The below FixedRssLossModel will cause the rss to be fixed regardless
      // of the distance between the two stations, and the transmit power
      wifiChannel.AddPropagationLoss ("ns3::FixedRssLossModel","Rss",ns3::DoubleValue (m_rss));

      m_wifiPhyHelper.SetChannel (wifiChannel.Create ());

      // Add a non-QoS upper mac, and disable rate control
      m_wifiMacHelper = ns3::NqosWifiMacHelper::Default ();

      m_wifiHelper.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
                                    "DataMode",ns3::StringValue (m_phyMode),
                                    "ControlMode",ns3::StringValue (m_phyMode));
      // Set it to adhoc mode
      m_wifiMacHelper.SetType ("ns3::AdhocWifiMac");

      m_init_done = true;
}

//Install the class's embedded settings on the nodes in this node container.
ns3::NetDeviceContainer BaseWifi::Install(ns3::NodeContainer &nc) {
    return m_wifiHelper.Install(m_wifiPhyHelper, m_wifiMacHelper, nc);
}
like image 204
rahman Avatar asked Aug 13 '13 11:08

rahman


People also ask

How do you initialize a static member?

We can put static members (Functions or Variables) in C++ classes. For the static variables, we have to initialize them after defining the class. To initialize we have to use the class name then scope resolution operator (::), then the variable name. Now we can assign some value.

How do you initialize a member object in C++?

There are two ways to initialize a class object: Using a parenthesized expression list. The compiler calls the constructor of the class using this list as the constructor's argument list. Using a single initialization value and the = operator.

Where do you initialize static variables?

As static variables are initialized only once and are shared by all objects of a class, the static variables are never initialized by a constructor. Instead, the static variable should be explicitly initialized outside the class only once using the scope resolution operator (::).

Why do static members need to be initialized C++?

Because it is a static variable the compiler needs to create only one copy of it.


1 Answers

I have run into these kind of issues before. Apparently the initialization of static member objects very much depends on where the implementation is done in your code and (probably) on how the whole thing is compiled. The solution that I found (somewhere) to the problem was to wrap the whole thing into a static member function like this:

//in Agent.h
class Agent : public ns3::Object{
    private:
    //...

    static BaseWifi& m_wifi();
    //...
};

and:

//in Agent.cpp
BaseWifi& Agent::m_wifi() {
    static BaseWifi TheObject=BaseWifi();
    return TheObject;
}

This way the object is initialized properly the first time the static member function is called.

like image 51
Thomas Kühn Avatar answered Oct 24 '22 12:10

Thomas Kühn