Say you have a file example.h
class example
{
public:
int doStuff();
};
and a file example.cpp
#include "example.h"
static const int data[] = {1, 2};
inline int doStuffImpl()
{
return data[0] + data[1];
}
int example::doStuff()
{
return doStuffImpl();
}
When I compile the equivalent on solaris using the native compiler, I get a linker error that it can't find the symbol 'data'. Is what I'm doing invalid?
No it's not, it should be
static const int data[] = {1, 2};
Related
I would like to initialize a constexpr variable with another variable, made visible by extern:
test.cpp
#include "test.h"
int const a[] = {1};
int const d = 4;
test.h
extern int const a[];
extern int const d;
main.cpp
#include "test.h"
int main(void) {
constexpr const int * b = a;
constexpr const int e = d;
}
(Only) The second line in main gives the following error:
error: the value of 'd' is not usable in a constant expression and
test.h:3:18: note: 'd' was not initialized with a constant expression
Could somebody help me to understand, why only one of the two examples fails?
Here's the code:
#include <iostream>
using namespace std;
class Zaix
{
private:
static int mor;
public:
static int beri;
static void setmor(int lip)
{
Zaix::mor=lip;
}
static int getmor(void)
{
return mor;
}
};
int Zaix::beri=3;
int main()
{
cout<<Zaix::beri<<endl;
Zaix::beri++;
cout<<Zaix::beri<<endl;
Zaix::setmor(6);
return 0;
}
Now, line 4 of main() function Zaix::setmor(6); somehow invalidates line 11 of the code presented Zaix::mor=lip;. With this line commented out, the whole thing compiles OK, with it present, compiler gives this error:
undefined reference to Zaix::mor"
Any idea why that is?
Define the variable outside class as well.
int Zaix::mor;
For assignment:
int Zaix::mor = 4;
In C++ we need to define all the static member variable of a class outside of it else we get a linking error. You just need to do like below:-
int Zaix::mor;// Just add this line below int Zaix::beri = 3;
I'm trying to initialise static pointers as arrays inside a class definition, but getting runtime errors. I've seen examples where something similar is done, but I can't get it working, and not sure why. Some example code I've tried is:
class Header
{
private:
static int *pointer;
public:
int getVal(int val);
};
Class definition:
#include "Header.h"
int* Header::pointer = new int[] {0, 1, 2, 3, 4};
int Header::getVal(int val)
{
return pointer[val];
}
main:
#include "Header.h"
#include <iostream>
int main(int argc, char ** argv)
{
Header header;
for (int i = 0; i < 5; i++)
{
std::cout << header.getVal(i);
}
}
Running this causes an error while initialising the pointer. If I run through it in the debugger, and ignore the error, I can see that the pointer is initisalised with 0 at the beginning. If I then continue to step through it I get another error saying the heap's been corrupted. Is it possible to intitialise a pointer in this way? If not, are there any suggestions on how one can initialise a member variable pointer into an array, and assign it values, inside the class definition without having to assign each element of the array individually.
You could probably get away with:
class Header
{
public:
int getVal(int valIndex);
};
and then
#include "Header.h"
static int s_vals[] = {0, 1, 2, 3, 4}; // could move this line to B
int Header::getVal(int valIndex)
{
// B
return s_vals[valIndex];
}
Considering that you know the size of the array at compile time and there is no need to advertise an implementation detail if you are providing accessors anyway.
it is possible that your compiler simply does not support braced-init-list.
If so you can rewrite your class the following way
class Header
{
private:
static int *pointer;
static int *init()
{
int *p = new int[5];
std::iota( p, p + 5, 0 );
return ( p );
}
public:
int getVal(int val);
};
And then pointer is defined the following way
int * Header::pointer = Header::init();
I have written a class as shown below:
#include<iostream>
using namespace std;
class A
{
static int cnt;
static void inc()
{
cnt++;
}
int a;
public:
A(){ inc(); }
};
int main()
{
A d;
return 0;
}
I want to call the function inc through the constructor, but when i compile i am getting an error as:
/tmp/ccWR1moH.o: In function `A::inc()':
s.cpp:(.text._ZN1A3incEv[A::inc()]+0x6): undefined reference to `A::cnt'
s.cpp:(.text._ZN1A3incEv[A::inc()]+0xf): undefined reference to `A::cnt'
I am unable to understand what the error is... plz help...
Static field is not defined - Take a look at Why are classes with static data members getting linker errors?.
#include<iostream>
using namespace std;
class A
{
static int cnt;
static void inc(){
cnt++;
}
int a;
public:
A(){ inc(); }
};
int A::cnt; //<---- HERE
int main()
{
A d;
return 0;
}
Inside the class static int cnt; is only declared, and need to be defined. In C++ you usually declare in your .h .hpp files and then define your static class members in your .c and .cpp files.
In your case, you need to add
int A::cnt=0; // = 0 Would be better, otherwise you're accessing an uninitialized variable.
I have a class
class foo {
public:
foo();
foo( int );
private:
static const string s;
};
Where is the best place to initialize the string s in the source file?
Anywhere in one compilation unit (usually a .cpp file) would do:
foo.h
class foo {
static const string s; // Can never be initialized here.
static const char* cs; // Same with C strings.
static const int i = 3; // Integral types can be initialized here (*)...
static const int j; // ... OR in cpp.
};
foo.cpp
#include "foo.h"
const string foo::s = "foo string";
const char* foo::cs = "foo C string";
// No definition for i. (*)
const int foo::j = 4;
(*) According to the standards you must define i outside of the class definition (like j is) if it is used in code other than just integral constant expressions. See David's comment below for details.
Since C++17 the inline specifier also applies to variables. You can now define static member variables in the class definition:
#include <string>
class foo {
public:
foo();
foo( int );
private:
inline static const std::string s { "foo" };
};
In a translation unit within the same namespace, usually at the top:
// foo.h
struct foo
{
static const std::string s;
};
// foo.cpp
const std::string foo::s = "thingadongdong"; // this is where it lives
// bar.h
namespace baz
{
struct bar
{
static const float f;
};
}
// bar.cpp
namespace baz
{
const float bar::f = 3.1415926535;
}
Static members need to be initialized in a .cpp translation unit at file scope or in the appropriate namespace:
const string foo::s( "my foo");
Only integral values (e.g., static const int ARRAYSIZE) are initialized in header file because they are usually used in class header to define something such as the size of an array. Non-integral values are initialized in implementation file.