Cannot Compile .cpp File When Trying To Define Private Var - c++

I am attempting to compile a .cpp file that includes a .h file and then implements the class outlined.
In String.h:
using namespace std;
class String
{
private:
int _length;
char *data;
int getCharArraySize(char arr[]);
In String.cpp:
#include "String.h"
using namespace std;
/*
* Private vars and methods
*/
int String::_length;
char String::*data;
int String::getCharArraySize(char arr[])
{
//method body
return 0;
}
When I attempt to compile with g++ I get this error:
% g++ String.cpp -c
String.cpp:14:17: error: ‘int String::_length’ is not a static data member of ‘class String’
int String::_length;
I am only having issues with String::_length. I was initially thinking that it was due to _length being private but all the other private methods/vars, compile just fine. I also need to leave this .h file as is so I cannot just make it public. Any help would be appreciated!

Well, it's exactly as the compiler says: _length is not a static member variable. Yet, you are treating it as one by providing it with its own definition. Simply do not do that. Only static member variables should be defined like that.
The same goes for data.
By the way, if you do ever have to define a char* variable, then this is wrong:
char String::*data;
and this is right:
char* String::data;
Lexical grammar production oddities (inherited from C) notwithstanding, the * is part of the type, not the name.

Related

Why the singleton initialization failed (link error) [duplicate]

Very simply put:
I have a class that consists mostly of static public members, so I can group similar functions together that still have to be called from other classes/functions.
Anyway, I have defined two static unsigned char variables in my class public scope, when I try to modify these values in the same class' constructor, I am getting an "unresolved external symbol" error at compilation.
class test
{
public:
static unsigned char X;
static unsigned char Y;
...
test();
};
test::test()
{
X = 1;
Y = 2;
}
I'm new to C++ so go easy on me. Why can't I do this?
If you are using C++ 17 you can just use the inline specifier (see https://stackoverflow.com/a/11711082/55721)
If using older versions of the C++ standard, you must add the definitions to match your declarations of X and Y
unsigned char test::X;
unsigned char test::Y;
somewhere. You might want to also initialize a static member
unsigned char test::X = 4;
and again, you do that in the definition (usually in a CXX file) not in the declaration (which is often in a .H file)
Static data members declarations in the class declaration are not definition of them.
To define them you should do this in the .CPP file to avoid duplicated symbols.
The only data you can declare and define is integral static constants.
(Values of enums can be used as constant values as well)
You might want to rewrite your code as:
class test {
public:
const static unsigned char X = 1;
const static unsigned char Y = 2;
...
test();
};
test::test() {
}
If you want to have ability to modify you static variables (in other words when it is inappropriate to declare them as const), you can separate you code between .H and .CPP in the following way:
.H :
class test {
public:
static unsigned char X;
static unsigned char Y;
...
test();
};
.CPP :
unsigned char test::X = 1;
unsigned char test::Y = 2;
test::test()
{
// constructor is empty.
// We don't initialize static data member here,
// because static data initialization will happen on every constructor call.
}
in my case, I declared one static variable in .h file, like
//myClass.h
class myClass
{
static int m_nMyVar;
static void myFunc();
}
and in myClass.cpp, I tried to use this m_nMyVar. It got LINK error like:
error LNK2001: unresolved external symbol "public: static class...
The link error related cpp file looks like:
//myClass.cpp
void myClass::myFunc()
{
myClass::m_nMyVar = 123; //I tried to use this m_nMyVar here and got link error
}
So I add below code on the top of myClass.cpp
//myClass.cpp
int myClass::m_nMyVar; //it seems redefine m_nMyVar, but it works well
void myClass::myFunc()
{
myClass::m_nMyVar = 123; //I tried to use this m_nMyVar here and got link error
}
then LNK2001 is gone.
Since this is the first SO thread that seemed to come up for me when searching for "unresolved externals with static const members" in general, I'll leave another hint to solve one problem with unresolved externals here:
For me, the thing that I forgot was to mark my class definition __declspec(dllexport), and when called from another class (outside that class's dll's boundaries), I of course got the my unresolved external error.
Still, easy to forget when you're changing an internal helper class to a one accessible from elsewhere, so if you're working in a dynamically linked project, you might as well check that, too.
When we declare a static variable in a class, it is shared by all the objects of that class. As static variables are initialized only once they are never initialized by a constructor. Instead, the static variable should be explicitly initialized outside the class only once using the scope resolution operator (::).
In the below example, static variable counter is a member of the class Demo. Note how it is initialized explicitly outside the class with the initial value = 0.
#include <iostream>
#include <string>
using namespace std;
class Demo{
int var;
static int counter;
public:
Demo(int var):var(var){
cout<<"Counter = "<<counter<<endl;
counter++;
}
};
int Demo::counter = 0; //static variable initialisation
int main()
{
Demo d(2), d1(10),d3(1);
}
Output:
Count = 0
Count = 1
Count = 2
In my case, I was using wrong linking.
It was managed c++ (cli) but with native exporting. I have added to linker -> input -> assembly link resource the dll of the library from which the function is exported. But native c++ linking requires .lib file to "see" implementations in cpp correctly, so for me helped to add the .lib file to linker -> input -> additional dependencies.
[Usually managed code does not use dll export and import, it uses references, but that was unique situation.]

Putting all const values of a class in the same place

I am trying to use some compile-time const values for a class and I am using constexpr/const, but I dislike a lot the fact that some will be inited in the hpp and some in the .cpp.
I've read the explanation related to string incompatibility with constexpr, but
isn't a trick to put all of them in the same location?
It's strange that in the modern C++ 11/14 you have to declare them in two separate locations.:)
Thank you
// test.hpp
class Test
{
// initialization values are located clear in the header
static constexpr int a_{10};
static constexpr int b_{20};
// we must go to the cpp file to see this string value
static const std::string str_;
};
// test.cpp
const std::string Test::str_{"abc"};

Trouble with using namespace and static methods

I am trying to write some namespaces statics methods and variables in order to have a set of functions i can use from anywhere in the code. This is what I have:
Header:
namespace CProfileIO
{
static void setAppDir(std::string appDir);
static int reloadProfiles();
static std::string directory;
static std::list<std::string> profilesList;
}
Source:
namespace CProfileIO
{
void setAppDir(std::string appDir)
{
directory = appDir;
}
int reloadProfiles()
{
// ...
}
} // namespace CProfileIO
Then somewhere in the code I have:
#include "CProfileIO.h"
int main(int argc, char * argv[])
{
string appDir = string(dirname(*argv));
CProfileIO::setAppDir(appDir);
.
.
.
}
When I try to compile, i get error at the line I am using the function:
... undefined reference to `CProfileIO::setAppDir(std::string)'
I cant figure out what is wrong. I would aprichiate all help!
You should not use static functions here, as they are visible only in the current translation unit. Thus, you declare a static function which you define (statically) in the cpp, then it won't be visible from other translation units.
You should simply not use the static keyword here, but declare variables (but not functions) as extern.
Also, I recommend to pass the string argument as const reference (void setAppDir(const std::string& appDir);)
That is because static methods are only visible in the current module, (source file). They are not linked.
Hence you other sourcefile doesn't find the function. That is supposed to happen if you use static. I don't know why you would declared naked functions as static, maybe you meant to put them into a class?

C++: Defining void* array in header file and declaring it in a cpp file?

I saw this question and I tried to do as the answer to that question said. To use the extern keyword in the header file to define an array and then declare it outside of that namespace or class in a other cpp file.
It didn't work for me really, I'm not sure if it because I'm using a void pointer array (i.e void* array[]) or if it's just my ignorance that prevents me from seeing the problem.
This is the shortest example I can come up with:
[cpp.cpp]
#include "h.h"
void main(){
void* a::b[] = {
a::c = a::d(1)
};
}
[h.h]
namespace a{
struct T* c;
struct T* d(int e);
extern void* b[];
}
So the problem is that I receive the error:
IntelliSense: variable "a::b" cannot be defined in the current scope
And I have no clue why that is.
First, you should declare main() as int ! See here why.
Declaring your array as extern in a namespace means that it belongs to the namespace but is defined somewhere ele, normally in a separate compilation unit.
Unfortunately, in your main(), you try to redefine the element as a local variable. This explains the error message you receive.
You shoud do as follows:
#include "h.h"
void* a::b[] { a::c, a::d(1) }; // global variable belonging to namespace
int main() // int!!!
{
/* your code here */
}
The code will compile. The fact that a::b[] is defined in the same compiling unit is accepted. But the linker will complain because a::d(1) is a call to the function d returning a pointer to a struct, and this function is defined nowhere.
Therfore you should also define this:
namespace a {
struct T* d(int e)
{
return nullptr; // in reality you should return a pointer to struct T
}
}
Interestingly, struct T does not need to work for this code to compile and link.

static member inside class c++ undefined reference

Why this code is giving me an error that undefined reference to student::count. I am using static count and I know that static members are by default is 0 but dont know why giving me an error. Please explain me.
#include <iostream>
using namespace std;
class Student{
static int count;
string name;
public:
Student(){
count++;
cout<<"I am student"<<count<<endl;
}
int getCount() const
{
return count;
}
void setCount(int x){
count=x;
}
};
int main(){
Student stud[20];
return 0;
}
You have no definition of Student::count, violating the one definition rule. Put a definition in one, and only one, translation unit.
Note that if static int count; was a definition, static members would be almost impossible to use. You'd wind up with a definition each time you included the header file, making the one definition rule almost impossible to comply with.
Writing static int count; in your header means: Compiler, somewhere you will find a variable scoped to this class, it will be a int and will be nammed count.
Now, you need to actually instantiate (define) your variable somewhere. Maybe in your case, adding int Student::count; to your main file would be fine.