I want to have a class that is used for a one off initialization like so:
class Initialise
{
public:
Initialise()
{
m_name = "Jimmy";
}
~Initialise(){}
private:
std::string m_name;
};
class SomeClass
{
static Initialise staticStuff; // constructor runs once, single instance
};
int main()
{
SomeClass testl;
return 0;
}
When I run the above I find that the constructor of the 'Initialise' class never gets hit in the debugger. Why is this?
You didn't define staticStuff, you only declared it.
You have to declare it outside of the class like so :
Initialise SomeClass::staticStuff;
Here is a live example.
Moreover, like pointed by Borgleader, you should consider using a member initializer list to improve your code.
Related
I have a class that has a static member object. Initializing that static object means setting some of its parameter to a specific value; but this is done by a function from that object. i do not know how to do it if it is static. Any help?
To be more specific I have a static boost logger object per class. It has a ClasName attribute and setting this to the name_of_the_class value is done by add_attribute("ClassName", boost::log::attributes::constant<std::string>("MyClass")) function. What is the best way to initialize the static logger? I have done:
typedef boost::log::sources::severity_logger< severity_levels > BoostLogger;
class MyClass
{
private:
static BoostLogger m_logger;
public:
MyClass()
{
MyClass::m_logger.add_attribute("ClassName", boost::log::attributes::constant<std::string>("MyClass"));
}
}
BoostLogger MyClass::m_logger; // And here I cannot call the add_attribute() function
I know that this is done every time I instantiate the class, so: What is the best way to do it?
You can initialise the logger once e.g. with a static variable in your constructor:
MyClass()
{
static bool logger_initialised = false;
if (!logger_initialised)
{
MyClass::m_logger.add_attribute("ClassName", boost::log::attributes::constant<std::string>("MyClass"));
logger_initialised = true;
}
}
Note that this is not thread-safe. But if you do not use threads, it will work and the logger will be initialised one time but only if you instantiate MyClass.
if BoostLogger doesn't provide the constructor to add_attribute you may create your own function for that, something like:
class MyClass
{
private:
static BoostLogger m_logger;
};
BoostLogger CreateBoostLoggerWithClassName(const std::string& className)
{
BoostLogger logger;
logger.add_attribute(
"ClassName",
boost::log::attributes::constant<std::string>(className));
return logger;
}
BoostLogger MyClass::m_logger = CreateBoostLoggerWithClassName("MyClass");
First of all look at the BOOST_LOG_GLOBAL_LOGGER
Here is corrected version of your code.
MyClass.h:
class MyClass
{
private:
static BoostLogger m_logger; /* This is declaration, not definition.
You need also define the member somewhere */
public:
MyClass() /* So far as this is constructor, it may be called more than once,
I think adding new static function will be better */
{
// MyClass::m_logger.add_attribute("ClassName", boost::log::attributes::constant<std::string>("MyClass"));
// AddAttribute("ClassName"); Uncomment this line if you're really need to add attribute in constructor
}
static void AddAttribute(std::string name) /* this function has been added as advice,
if you're going add attributes as you
did in question,
remove function, and uncomment first line in the constructor */
{
MyClass::m_logger.add_attribute(name, boost::log::attributes::constant<std::string>("MyClass"));
}
}
MyClass.cpp:
BoostLogger MyClass::m_logger = BoostLogger(); // This is definition of static member item
Instead of an add_attribute call, make it so that you can fully initialise BoostLogger with its constructor. Then simply provide the necessary argument when you define it.
hei i have a c++03 class with a simple constructor that take an integer. And a derived class with serialization methods that should take a filename as a constructor, load the integer from it, and then call the first constructor.
class A {
public:
A(int foo);
}
and a derived class:
class XmlableA : public A {
public:
XmlableA(int foo);
XmlableA(string xmlfilename) {
//load foo from xml
// call A::A(foo)
}
}
i tried some different solution but every time i get
no matching function for call to ‘A::A()’
Almost all answers are same, so I would suggest a different solution, which I would prefer personally.
Define a static member function Create as:
class XmlableA : public A {
public:
XmlableA(int foo);
//static member function
static XmlableA Create(string const & xmlfilename)
{
//load foo from xml
int foo = /*load from file*/;
return XmlableA(foo);
}
};
Usage:
XmlableA xmlable = XmlableA::Create(xmlFile);
Initialize it, like so:
XmlableA(int foo) : A(foo) {}
You may also consider:
private:
static int LoadXML(const string& xmlfilename) {
int ret = ...; << load here
return ret;
}
public:
XmlableA(string xmlfilename) : A(LoadXML(xmlfilename)) {
}
In C++ the Base class is constructed BEFORE the Child class, so you will not be able to do this. You could make a Factory that takes a filename and creates an object based on what is in that file.
Example:
class XmltableAFactory {
public:
static XmltableAFactory build(string xmlfilename) {
// read int foo from xmlfilename
return XmltableAFactory(foo);
}
};
And then call it like so:
XmltableA myObj = XmltableAFactory::build(filename);
There are a few things to note.
This means that you will not need the string xmlfilename cosntructor in the XmltableA class because as discussed above, you cannot know foo before the base class's constructor is called.
You can either choose to return from the factory by value or by pointer. The compiler might optimize the return by value because you are creating the object and returning it on the same line. However, return by pointer is usually known to be faster, but you'll have to create a new object and then make sure to delete it when you're done with it.
If you don't want to muck about with memory, take a look at boost's auto_ptr and shared_ptr.
If you want to do something before the call to A::A(int), you end up having to hack, something like
int XmlableA::f(string filename) { /* load foo from xml */; return foo; }
XmlableA(string xmlfilename) : A(f(filename)) {}
OK, so the first one is easy:
XmlableA::XmlableA(int foo) : A(foo)
{
}
The second one requires doing something like
XmlableA(string xmlfilename) : A(fooFromXML(xmlfilename))
{
}
which we can implement as
class XmlableA : public A
{
static int fooFromXML(string filename);
public:
// ...
Note that fooFromXML, which loads the XML file and returns the integer you need, must be static, because when we call it we don't yet have an XmlableA instance to invoke it on.
For multiple arguments (and as a general design), the factory is probably best: if you're wedded to the constructor model and don't care about efficiency, you can do:
class XmlableA : public A
{
static int intFromXML(char const *varname, string const &filename);
public:
XmlableA(string const &xmlfilename)
: A(intFromXML("foo", xmlfilename), intFromXML("bar", xmlfilename))
{
}
if you're concerned about parsing the XML file repeatedly, and don't care about re-entrancy, you can "memoize" xFromXML by having it cache state in a static member.
If your class A does not have a default constructor you have to explicitly call a constructor in the initialization list of your derived class. XmlableA(string fn) : A(readIntegerFromFile(fn)) {}.
However, you should think about "outsourcing" the serialization into a separate class. E.g. what would happen if you have an object of type A and now you want to serialize it? You couldn't because you can only serialize a XmlableA. Furthermore, what would happen if your client decides that he no longer wants a XML serialization but Yaml or some proprietary format? You would have to change all your code.
Is it possible in c++ to access class variables in other classes without creating an object. I have tried to use static, but the other class doesnt recognize my variable.
I have 3 classes. In two of those the sae variables should be used. In the third class I am changing the values. Would be grateful if you could help. Maybe youve got an example.
class Myclass
{
public:
static int i;
};
int Myclass::i = 10;
class YourClass
{
public:
void doSomething()
{
Myclass::i = 10; //This is how you access static member variables
}
};
int main()
{
YourClass obj;
obj.doSomething();
return 0;
}
static is the right keyword here:
class A {
public:
static int i; // <-- this is a class variable
};
class B {
public:
void f() { A::i = 3; } // <-- this is how you access class variables
};
They only potential problem I can think of is that
You made the class variable protected or private, thus rendering it inaccessible from other code.
You forgot to specify the full scope of the class variable (with A:: in this example).
I think the Singleton Pattern would help, but I'm no big fan of it. A lot better design would be to have one class take ownership of the object, and pass references to this object to the other classes.
yes you can bro, try this
struct car{
string model;
string paint;
int price;
};
int main(){
// creates an object of the class car
car BMW;
// assign the values
bmw.model = "m sports";
bmw.paint ="red";
bmw.price = 24000;
}
I have a class which has a number of static function to perform some calculation. However, before the calculation, I need to pass in a data to initialize some of the static data members. Currently I have an init(data) function and a clearResource() function which should be called before and after the use of the class. Is there a better way of doing that?
For example:
classA(){
static int a;
static init(int b) {
a = b;
}
static functionA(){
//perform something based on value of a;
switch(a){
}
}
}
int main(){
classA::init(5);
classA::functionA();
}
Thanks
Avoid using static member functions : have your constructor initialize the data and the destructor clear the resources (see RAII). If the existing class cannot be changed, implement a helper class which calls init from its constructor and clearResource from its destructor.
You can use this kind of design
class A()
{
public:
static int a;
static void functionA(int arg = A::a)
{
if(A::a != arg)
A::a = arg;
...
}
};
int A::a = 0;
int main()
{
A::functionA();
}
You should apply the RAII concept: see this and this questions.
Make the member functions and data non-static, initialize in a constructor and free resources in the destructor. This will guarantee the correct sequence of calls: initialize - perform operations - free resources in the client code.
I'd avoid using static members in this case.
This is your problem. You have a class that does processing on some data. That data, for whatever reason, needs to be shared across all instances of this processing class. Ok then, we have a non-static solution!
class Data : boost::noncopyable
{
public:
Data()
{
// initialise all of our data.
}; // eo ctor
}; // eo class Data
Where you instantiate this class is up to you. It could be a member of an application class that is run at start up, or part of some root. It just needs to be accessible and does not need to be static nor a singleton.
class DataProcessor
{
private:
Data& m_Data;
public:
DataProcessor(Data& _data) : m_Data(_data)
{
}; // eo ctor
}; // eo class DataProcessor
Thank you for reading.
The to delegate Class is called Sensor. It need a reference to be set in the Constructor like:
class Sensor { Sensor(other *ref);}
I have a Class testFactory. If i now type
class testFactor{
...stuff...
private:
Sensor mySensor;}
I get ALL the Problems. It cannot alloc an abstract Object. Or it cannot declare the variable, or does not know the Type of the variable.
Even taking Sensor out of the header into the cpp with as a static variable does not help.
Only if i change the Sensor Constructor to a void/non Constructor i dont get ANY Problems.
But then i have to use a setRed Function in the Sensor and this could lead to more problems.
Hope you can help me with: declaring a Variable with holds an Class with an non Void Constructor
You need to initialise the Sensor instance correctly - for example:
class TestFactor {
public:
TestFactor() : mySensor( 0 ) {}
private:
Sensor mySensor;
};
It works fine for me using c++. Perhaps you didn't declare the construction of Sensor in the initialisation list for Fac?
class Sensor {
public:
Sensor(int *a)
{
}
};
int b;
class Fac {
public:
Fac():
sensor(&b)
{}
private:
Sensor sensor;
};
main()
{
Fac a;
return 0;
}
One thing that I can see is that your constructor for Sensor is private (try changing class to struct or putting public: before constructor or declaring the frienship between Sensor and containing class). And you should either have a default constructor in addition to it or provide the parameter when instantiating it in containing class.
But you obviously need to be more specific to get more specific answers.
If you have classes with non-default constructors the compiler wont generate a default constructor for it. You also cannot instantiate classes which have only private constructors.
You can either provide a public default constructor, use a pointer to the instance or simply initialize the member via a public constructor:
class testFactor {
Sensor mySensor;
public:
testFactor() : mySensor(0) {}
};
One more point: If sensor is an abstract class, you cannot create an instance of it.
Most factory patterns have an abstract base classes an return pointers of the base class that point to allocated derived objects.
class Sensor
{
virtual std::string get_sensor_name(void) const = 0;
};
class Fire_Sensor
: public Sensor
{
std::string get_sensor_name(void) const
{ return "Fire Sensor";}
};
Sensor *
Sensor_Factory::create_sensor(std::string name)
{
if (name == "Fire Sensor")
{
return new Fire_Sensor;
}
return NULL;
}
Also look up reference slicing.