C + +: Static member has to be defined seperately

Source: Internet
Author: User

If you write a single example of C + +:

classSingleton {Private:    StaticSingleton *Singleton;Private: Singleton () {} Public:    StaticSingleton *getinstance () {if(Singleton = =NULL) {Singleton::singleton=NewSingleton (); }        returnSingleton; }};intMain () {Singleton* p =singleton::getinstance (); return 0;}

There will be linker error (unsolved external ' singleton ').

As the name implies, unsolved external that linker can not find this symbol.

Note that this is not a compiler error, but a linker error.

If you change to this:

classSingleton {Private:    StaticSingleton *Singleton;Private: Singleton () {} Public:    StaticSingleton *getinstance () {if(Singleton = =NULL) {Singleton::singleton=NewSingleton (); }        returnSingleton; }}; Singleton* Singleton::singleton = nullptr;//add this definition.intMain () {Singleton* p =singleton::getinstance (); return 0;}

Then there will be no problem.

Why? Why add more of this definition? Not already defined in the Singleton class? Even if you want to assign a value to that class static variable, why not add Singleton::singleton = nullptr directly? After all, there is already a declaration in the class, and there is no repetition in declaring it once. After all, in general, you can't do this: int x; int x;

In fact, this is not the C + + language problem, but the C + +, C, Pascal this kind of static language problem. Java, which relies on the virtual machine language, has no such problem (and why).

Among the many programming languages, there is a language called native Language, such as C, C + +, Pascal. This is called native, not because they can be compiled (Java can also be compiled, Python can), but because what they compile can be changed directly into machine code and then executed by the underlying operating system. Java, Python, Perl, C # This kind of language that relies on virtual machines to operate is not. This is also the English meaning of native.

This means that the obj files they compile are generic. As long as you use the C + + compiler,c Compiler,pascal compiler to follow the same obj file format specification (such as Elf, PE, COFF, etc.), then the same linker can link these obj files into an executable file.

So, in other words, each compilation unit can be ignorant of the other compilation units (compilation unit). (even if the compiler wants to know, because you don't know if the obj file that you're linked with is not the same language)

You can write a code in C, compile it into an obj file, write one in C + +, compile it into an obj file, and then write a copy of Pascal and compile it into an obj. Then, use a linker to link them up and turn them into an executable file.

In fact, the C + + language does not know the existence of the linker (just the general compilation suite such as visual STUDIO,GCC automatically calls linker), it is only responsible for compiling multiple copies of the obj file, and then a linker to link them together.

This compilation model (compilation models) is called separation compilation .

There are advantages to separating compilation, but it can also lead to many problems. One of these is the problem of multiple definitions.

The basic meanings of multiple definitions are as follows:

If you've written three C + + code:

// File1.cpp int C;
// File2.cpp int C;
// File3.cpp int C;

Then a main entry:

// main.cpp int main () {}

When you compile any of the individual copies, it will succeed (with gcc-c file1.cpp ... command compile,- c for compile, but not link), Generate file1.o .... File.

However, when you link them together with the linker, there will be a link error, because you have defined three times the variable C, when the connector to the four compilation units (compilation unit) linked together, it will find that C has been defined multiple times, so error. This is the problem of multiple definitions.

As you can see, this is because each compilation unit can have no knowledge of the other compilation units (compilation unit) , so even if you define multiple C, the compiler does not know. Wait until linker to deal with it again.

Go back to the top of the singleton.

In the above code, the reason for this is Singleton * Singleton::singleton = nullptr , and the static member "re" in a class is defined in general, also for this reason.

You know, defining a variable is equivalent to allocating a certain amount of memory space to it. Static member too. But the static member is common to all instance (instances), so it has only one piece of memory space.

However, the declaration of a class is usually placed in a header file, and a header file can be included multiple times, divided into different compilation units compiled, each compilation unit to another compilation unit is not ignorant, so the compiler does not know how to deal with this static member. If the compiler allocates memory space to the static member when the class declares it (acknowledging the definition and taking action), then the static member will be allocated once again if the header file containing the class is included in the other compilation unit. In this way, the static member will not be static.

So, to solve this problem, the C + + language stipulates that when compiling this class, the static member in the class is not processed (defined), and the programmer should define the static member separately in another place.

So why would Java be like this? Why doesn't Java have to define static member separately? Very simple, because Java is independent, its own virtual machine, only the Java language compiled by things to run on it. Even if Java compiles from the compilation process described above, it discovers duplicate static member, it only needs to integrate these duplicate objects into one (depending on its runtime mechanism). So, at the language (grammar) level, Java has no such problem (no separate definition of static member is required). C # is also.

To say a word, C + + in the singleton generally do not write this way, generally:

class Singleton {private:    Singleton () {    }    Singleton (Singleton& );    Singletonoperator= (singleton&);  Public :     Static singleton& getinstance () {        static  Singleton instance;         return instance;        }};

:)

C + +: Static member has to be defined seperately

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.