So here's my situation: I have a class foo residing in foo.cpp with header file foo.h included in my main.cpp. I need to be able to declare a foo object as a global variable in main.cpp so that it is available to all functions within main.cpp without having to pass a reference to it every time. The problem is, foo's constructor requires a variable which isn't retrieved from the user until halfway through the main function in main.cpp. I thought I could do this this way:
static foo myFoo;
As a global variable above the main function, then after the necessary data is retrieved from the user (let's call it "variable"), I could call:
myFoo = new foo(variable);
I'm getting an error however with this:
error: no matching function for call to ‘foo::foo()’
referencing the line with static foo myFoo;
So it's basically saying that I'm trying to declare an instance of foo with a constructor taking zero arguments, when there is none.
So my question is: Is there a way to declare a label myFoo out of foo as a global variable so that the program compiles, and then later it can actually be instantiated using the constructor with a variable passed?
I know I could just do something like this:
string temp = "";
static foo myFoo(temp);
above main() and then have some function defined where I could do
myFoo.setVar(variable);
when I needed to. To me this is very ugly and necessitates the inclusion of the function setVar which has no tangible purpose other than to circumvent this very issue. Thoughts?
One option you have is to make your static instance a pointer:
static foo *myFoo = NULL;
// Later...
myFoo = new foo(variable);
Or you may want to use a default constructor and make an Init method instead.
static foo myFoo;
// Later...
myFoo.Init( variable );
When you're exposing a variable, you don't define it as static. Remove the static keyword and use extern in the header's declaration.
static foo myFoo;
That line will create a new object of type foo during the static initialization if your program. It will call the default constructor (if you don't define one, the compiler will create one for you in certain situations - you haven't posted enough code to know if that is the case here). Note that if it is defined in a header file, you will need to extern it.
Attempting to set myFoo to a pointer using
myFoo = new foo(variable);
will not compile. new foo(...) returns a foo*, not a foo. If you want it to be a pointer, you need to declare your static variable as
static foo* myFoo;
If you want it to be an object and want to set it to something other than the default, you can implement a copy-assignment operator and do something like this
foo newFoo(variable);
myFoo = newFoo;
Or provide an initialization function to change the construction values after the fact (prefer the copy-assignment in most cases as it will be less prone to errors).
I believe you might not be defining the default constructor. Once you define a constructor, the default constructor is not automatically defined. This works for me:
myclass.hpp:
#ifndef _MYCLASS_
#define _MYCLASS_
class myClass
{
public:
int I;
myClass(int i);
myClass();
};
#endif
myclass.cpp:
#include "myclass.hpp"
myClass::myClass(int i) : I(i) {};
myClass::myClass() : I(0) {};
main.cpp:
#include "myclass.hpp"
myClass myGlobalClassObject;
int main()
{
myClass myLocalClassObject(1);
myGlobalClassObject.I = 2;
return 0;
}
You are indicating that you foo object cannot be properly instantiated until halfway down the main function. This sounds like you will have an object in an inconsistent state for the first half of your main function. Very dangerous.
Anyway, there is a couple of ways to get to it:
1) If you want to create a static foo object you can use a default value for your constructor:
class foo {
public:
foo( type variable = default ) {
...
}
...
You can now declare your foo object as a global in main
foo myFoo;
and myFoo's variable will be initialised with “default”
or, without a default:
class foo {
public:
foo( type variable ) {
...
}
...
Declare your foo object as a global in main
foo myFoo(default);
Depending whether “default” makes sense in your application you can now use your myFoo object in main.cpp's functions. If “default” does not make sense you will have to add a test function before you use myFoo.
Of course you also need another member function to be able to set “variable” to your user input (something like set_variable(variable); )
2) Use a pointer. Declare a global foo * myFoo in main.cpp and test if the pointer is NULL before using it.
Now your constructor does not need a default value, it still needs the variable:
foo::foo(type variable) { ... }
You initialise your myFoo object by using: myFoo = new foo(user_input);
You can test the myFoo pointer to NULL as all uninitialised global variables are set to 0 by the startup code.
(As an aside: you do realise of course that globals are frowned upon and as such should be avoided)
Good luck
Related
The relevant part of my code is as follows:
In foo.h:
namespace foo_ns {
class Foo
{
static Class1 object1;
};
}
In foo.cpp
#include <foo.h>
namespace foo_ns {
Class1 Foo::object1(/*another object. Need to call copy constructor*/)
}
Here, "another object" is defined in main(). Furthermore, Class1 is part of a large library and has no zero argument constructors, so simply removing the parenthesis gives a no matching function call error during compilation. From what I understand, static initialization MUST be performed outside of any function.
So ithere any workaround for this?
Of course, if Class1 has methods that you can use later then an easy solution would be:
Class1 Foo::object1(some_rubbish);
// in main
object1 = Class1(the_real_initializer);
If Class1 does not have a working assignment operator, but it can safely be destroyed and re-created, you can write in main:
object1.~Class1();
new(&object1) Class1(the_real_initializer);
although if this constructor throws then you have to abort the program.
If it is not possible to destroy a Class1 correctly before the end of the program then you will have to defer its initialization, e.g.:
static std::unique_ptr<Class1> p_object1;
and then in main, when you are ready,
p_object1.reset( new Class1(bla bla bla) );
This way you will have to change any other code that accesses object1. to use p_object1-> instead.
I have to call a static functions inside a class(say UserApp) which returns static value.
Class Definition and declaration done in 2 files.
File1.h:
userApp(){
static int* foo;
}
file1.cpp:
{
int* userApp::foo = 0;
...
.
.
foo = somevar;
}
The same class(userApp) is implemented in file2 and to avoid linkage error I'm forced to declare and define the static variable in file2 as well.
In file 2.cpp as userApp::foo is initialized to 0 , the return value of function getFoo is always zero.
I need the value associated to foo in file1.
Is there any way I can avoid defining static variable in file2?
Thanks in advance.
What a mess :D
If I understood you right, I believe you have to declare the static member as extern in one of the files, to indicate it's actually referencing to a variable declared elsewhere.
In UserApp.h:
class UserApp {
private:
static int* foo_;
public:
static int* getFoo() { return foo_; }
};
In UserApp.cpp:
#include "UserApp.h"
int* UserApp::foo_ = NULL;
In any other where you need to use it:
#include "UserApp.h"
...
int* foo = UserApp::getFoo();
You haven't provided any details about your namespace / class full of static things, but consider making more OO design or in case it seems reasonable to keep it in one class, consider implementing a singleton that would also allow you to hold the information about its state in more reasonable way. (you might end up with something like this)
I have a library that is written for me in C. In the library there is a variable that I need to use
In foo.h (which is in C)
extern mystruct foobar;
In bar.h (which is in C++)
I have the following class.
#include foo.h
class myfoo {
private:
mystruct foobar;
}
What I would like to know is if I create an array of myfoo, will each instance of foobar be referencing the same variable, or will each instance be its own unique instantiation of the myfoo that independent from the other myfoo foobars?
Here’s the deal: you are not using foo.h’s foobar variable in bar.h (this is particularly true because foo.h only declares foobar, a definition would have to be in an implementation file). Rather, you are redeclaring a variable with the same name and type in the scope of the class.
With that, all the normal rules for an instance member variable apply. In particular, every instance of myfoo will have its own instance of foobar.
If you removed the declaration from foo.h nothing would change: the declaration is completely irrelevant for your bar.h file.
The foobar member inside the class definition of myfoo is defined at a different scope from the foobar at global scope. The are different variables, unrelated to each other, except that they are of the same type, and happen to have the same name (although at different scopes).
If you create an array of myfoo objects, each one will have an instance of mystruct. All of those instances will be separate from the one declared in the global scope.
What I would like to know is if I create an array of myfoo, will each
instance of foobar be referencing the same variable, or will each
instance be its own unique instantiation of the myfoo that independent
from the other myfoo foobars?
if you do this:
#include foo.h
class myfoo
{
private:
mystruct foobar;
};
void func()
{
myfoo f[3];
// ...
}
you create 3 different myfoo objects, each with its own foobar instance.
if you change the myfoo declaration as follows:
#include foo.h
class myfoo
{
private:
static mystruct foobar;
};
// this extra declaration is required for
// static member variables
mystruct myfoo::foobar;
void func()
{
myfoo f[3];
// ...
}
then the three instances of myfoo will share their single instance of foobar.
NOTE:
The class myfoo declaration may be in either a '.h' or a '.cpp' file.
The mystruct myfoo::foobar; declaration may only appear once, so it normally has to be in a '.cpp' file (or '.cc' or whatever you use).
I have the following situation:
class Foo
{
public:
static const Foo memberOfFoo;
........
}
So the thing is I can't initialize it in the same line where I declared it, and, I can't initialize it via Initializations List in the constructor, does anyone know what to do?
Put this outside of the class definition then:
const Foo Foo::memberOfFoo = whateverValue;
That is the definition of Foo::memberOfFoo, which can supply an initializer and has to go into the .cpp file (like any other definition of objects, it can only appear once in the whole program, otherwise you will get linker errors).
Sometimes you will find code that doesn't have definitions for its static data members:
struct A {
// sometimes, code won't have an "const int A::x;" anywhere!
static const int x = 42;
};
Omitting the definition like that is valid only if A::x is never address-taken and never passed to reference parameters. A more formal way to say when it is valid to omit the definition is: "When all uses of A::x immediately read the stored value of A::x". That's the case for many static integer constants.
Class statics other than constant integral types need to/can be initialized at the point of definition. You need to declare your (not so)memberOfFoo somewhere, by adding
const Foo Foo::memberOfFoo = /*construct here*/;
This is how you can implement initialization...
class Foo
{
public:
static const Foo memberOfFoo;
Foo(int, double)
{
...
};
};
const Foo Foo::memberOfFoo(42, 3.141592654);
...
I have noticed that some of my functions in a class are actually not accessing the object, so I made them static. Then the compiler told me that all variables they access must also be static – well, quite understandable so far. I have a bunch of string variables such as
string RE_ANY = "([^\\n]*)";
string RE_ANY_RELUCTANT = "([^\\n]*?)";
and so on in the class. I have then made them all static const because they never change. However, my program only compiles if I move them out of the class: Otherwise, MSVC++2010 complains "Only static constant integral variables may be initialized within a class".
Well that's unfortunate. Is there a workaround? I would like to leave them inside the class they belong to.
They can't be initialised inside the class, but they can be initialised outside the class, in a source file:
// inside the class
class Thing {
static string RE_ANY;
static string RE_ANY_RELUCTANT;
};
// in the source file
string Thing::RE_ANY = "([^\\n]*)";
string Thing::RE_ANY_RELUCTANT = "([^\\n]*?)";
Update
I've just noticed the first line of your question - you don't want to make those functions static, you want to make them const. Making them static means that they are no longer associated with an object (so they can't access any non-static members), and making the data static means it will be shared with all objects of this type. This may well not be what you want. Making them const simply means that they can't modify any members, but can still access them.
Mike Seymour has given you the right answer, but to add...
C++ lets you declare and define in your class body only static const integral types, as the compiler tells. So you can actually do:
class Foo
{
static const int someInt = 1;
static const short someShort = 2;
// etc.
};
And you can't do that with any other type, in that cases you should define them in your .cpp file.
Some answers including even the accepted answer seem to be a little misleading.
You don't have to
Always assign a value to static objects when initializing because that's optional.
Create another .cpp file for initializing since it can be done in the same header file.
You can even initialize a static object in the same class scope just like a normal variable using the inline keyword.
Initialize with no values in the same file
#include <string>
class A
{
static std::string str;
static int x;
};
std::string A::str;
int A::x;
Initialize with values in the same file
#include <string>
class A
{
static std::string str;
static int x;
};
std::string A::str = "SO!";
int A::x = 900;
Initialize in the same class scope using the inline keyword
#include <string>
class A
{
static inline std::string str = "SO!";
static inline int x = 900;
};
Since C++11 it can be done inside a class with constexpr.
class stat {
public:
// init inside class
static constexpr double inlineStaticVar = 22;
};
The variable can now be accessed with:
stat::inlineStaticVar
Static member variables must be declared in the class and then defined outside of it!
There's no workaround, just put their actual definition in a source file.
From your description it smells like you're not using static variables the right way. If they never change you should use constant variable instead, but your description is too generic to say something more.
Static member variables always hold the same value for any instance of your class: if you change a static variable of one object, it will change also for all the other objects (and in fact you can also access them without an instance of the class - ie: an object).
I feel it is worth adding that a static variable is not the same as a constant variable.
using a constant variable in a class
struct Foo{
const int a;
Foo(int b) : a(b){}
}
and we would declare it like like so
fooA = new Foo(5);
fooB = new Foo(10);
// fooA.a = 5;
// fooB.a = 10;
For a static variable
struct Bar{
static int a;
Foo(int b){
a = b;
}
}
Bar::a = 0; // set value for a
which is used like so
barA = new Bar(5);
barB = new Bar(10);
// barA.a = 10;
// barB.a = 10;
// Bar::a = 10;
You see what happens here. The constant variable, which is instanced along with each instance of Foo, as Foo is instanced has a separate value for each instance of Foo, and it can't be changed by Foo at all.
Where as with Bar, their is only one value for Bar::a no matter how many instances of Bar are made. They all share this value, you can also access it with their being any instances of Bar. The static variable also abides rules for public/private, so you could make it that only instances of Bar can read the value of Bar::a;
Just to add on top of the other answers. In order to initialize a complex static member, you can do it as follows:
Declare your static member as usual.
// myClass.h
class myClass
{
static complexClass s_complex;
//...
};
Make a small function to initialize your class if it's not trivial to do so. This will be called just the one time the static member is initialized. (Note that the copy constructor of complexClass will be used, so it should be well defined).
//class.cpp
#include myClass.h
complexClass initFunction()
{
complexClass c;
c.add(...);
c.compute(...);
c.sort(...);
// Etc.
return c;
}
complexClass myClass::s_complex = initFunction();
If your goal is to initialize the static variable in your header file (instead of a *.cpp file, which you may want if you are sticking to a "header only" idiom), then you can work around the initialization problem by using a template. Templated static variables can be initialized in a header, without causing multiple symbols to be defined.
See here for an example:
Static member initialization in a class template
Optionally, move all your constants to .cpp file without declaration in .h file. Use anonymous namespace to make them invisible beyond the cpp module.
// MyClass.cpp
#include "MyClass.h"
// anonymous namespace
namespace
{
string RE_ANY = "([^\\n]*)";
string RE_ANY_RELUCTANT = "([^\\n]*?)";
}
// member function (static or not)
bool MyClass::foo()
{
// logic that uses constants
return RE_ANY_RELUCTANT.size() > 0;
}