problem with initializing static class member

Jan 29, 2014 at 4:22pm
can someone plz tell me why does the function assign brings to a compilation error??
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
#include <string>

using namespace std;

class String
{
	static char s[255];
	int len;
public:
	void assign(const char*);
	int length()const;
	void print()const;
};

void String::assign(const char* str)
{
	strcpy(s,str);
	len=strlen(str);
}

int String::length()const
{
	return len;
}

void String::print()const
{
	cout<<"The string: "<<s<<endl;
}

int main()
{
	String s1;
	s1.assign("Hello");
	cout<<s1.length()<<endl;
	s1.print();
}


i tried without the static initialization and it works...how can i make it work with the static declaration?
Last edited on Jan 29, 2014 at 4:28pm
Jan 29, 2014 at 4:32pm
can someone plz tell me why does the function assign brings to a compilation error??

Next time give us the compiler errors.

You need to include cstring for strlen, strcpy etc..

You need to initialize s outside of the class (to get it to work, I simply added the line char String::s[255] = {'0'}; right after the class declaration)
Jan 29, 2014 at 4:33pm
i'm not sure why you'd want that as static? surely each String object should contain it's own unique char array?
Jan 29, 2014 at 4:39pm
this is the compilation error:
Error 1 error LNK2001: unresolved external symbol "private: static char * String::s" (?s@String@@0PADA) c:\Users\Al\documents\visual studio 2012\Projects\ConsoleApplication32\ConsoleApplication32\string.obj ConsoleApplication32


the only reason this memebr is static its because that what i was asked to do in this excerise:/
Jan 29, 2014 at 4:41pm
thank you very much danny that solved the problem...didnt understand why but still..thanks!
Jan 29, 2014 at 5:09pm
didnt understand why but still..thanks!

Because you need to actually define that static variable somewhere, so that it can be instantiated. It's not instantiated when a String object is instantiated, because it's static, so you have to do it in the same way as you would a (*spit*) global variable.
Jan 29, 2014 at 5:14pm
The problem is that `String::s` doesn't exist. A class definition only describes how the class looks like, it doesn't create it.

For regular members creation (or definition) happens when you instatiate the class, as in String s1;.

Static class members are more tricky. Since there is only one you can't create it every time you create an object, so you have to define it only once in a separate piece of code.
That piece of code is usually the source¹ file where the class member functions are defined (class.h -> class.cpp). In your case you only have one file so class definition and members definitions all go there.

The reason why char String::s[255] = {'0'};² made the program compile is because that's how you define static members: having a line like <type> <class>::<name> [initialization] at global scope.
Note that initialization is optional. char String::s[255]; would have worked too, but it's a good idea to always initialize data.


¹ Definitions should not be put in header files because when you compile, each source file #including the header with the definition will try to create the static member. To put it simply, you would end up with multiple copies of `String::s`, but then how can String::assign() know which copy is the actual `s`? It can't, so the compiler doesn't allow you to end up with this situation.
This is called the "One definition rule"

² I'm guessing this was meant to be '\0'
Last edited on Jan 29, 2014 at 5:28pm
Topic archived. No new replies allowed.