4
    #include <iostream>
    using namespace std;
    class First{
        public:
        void fun()
        {
            cout<<"base fun called\n";
        }
    };

    class Second{
        public:
        static First x; //Line 1
        static First *y; //Line 2
    };

    First Second::x; //Line 3

    First* Second::y; //Line 4

    int main()
    {
        Second::x.fun();
        Second::y->fun();
        return 0;
    }

Line 1 and Line 2 are declarations and Line 3 and Line 4 are definitions, this I have understood from some other stackoverflow posts about static members.

Q1. Why we have to define static objects like this ? (Line 3 and line 4)

Q2. Whats difference between x and y?(Line 1 and Line 2)

Q3. Where is the memory allocated for x and y objects ?(Line 3 and Line 4)

Mike
  • 1,215
  • 7
  • 12
Aman Raj
  • 59
  • 1
  • 5
  • 4
    You should really ask one question at a time. – juanchopanza Nov 27 '16 at 08:51
  • 4
    Are you really asking what's the difference between an object and a pointer to an object? Static doesn't change that at all. And there is no pointer to a static object. There is a static pointer to an object. – Sami Kuhmonen Nov 27 '16 at 08:56

3 Answers3

7

Your y is a pointer (not an object - a pointer is not the same as the object it could point to). Since it is static, it gets initialized with nullptr, unless you explicitly define it initialized to something else (e.g. have some First z; object and define First* Second::y= &z;). So Second::y->fun(); is dereferencing a null pointer, and that is undefined behavior. You really should be very scared.

We cannot answer all your questions here (an entire book would be needed, and the notion of pointer and its semantics is difficult to explain, and related to pointer aliasing; read also about virtual address space). So take a few weeks to read some good book like Programming - Principles and Practice Using C++; you probably will benefit by also reading SICP & Introduction to Algorithms (even if neither is about C++; however both are related to programming, which is difficult to learn).

See also some good C++ reference site, it gives a short explanation about static class members.

Notice that using raw pointers is often (but not always) a bad smell in genuine C++11. You probably should consider having smart pointers, but YMMV.

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • 2
    Technically, a pointer is also itself an object. – davmac Nov 27 '16 at 11:10
  • 1
    A C++ smart pointer is an object, but not a C++ raw pointer. You cannot apply any member function `fun` to `y` as `y.fun();` – Basile Starynkevitch Nov 27 '16 at 11:21
  • 1
    1.8 The C++ Object Model: _an object is a region of storage_ - a pointer also requires storage. The ability to call member functions is not what defines an object. The standard clearly defines pointers, and eg `int` variables, as objects (just as in C). – davmac Nov 27 '16 at 12:29
  • @ davmac - The standard doesn't "clearly define pointers" as objects - "The following entities are not objects: value, reference,.., and this" (http://en.cppreference.com/w/cpp/language/object). But "this’ pointer is a constant pointer that holds the memory address of the current object. – SChepurin Nov 27 '16 at 16:46
  • @SChepurin a pointer in a variable is an object. This discussion is referring to OP's question, and this answer, which states that "your `y` is a pointer (not an object)". However, `y` is an object, despite also being a pointer. My comment above is intended to refer to pointer variables, not pointer values. (Also, cppreference.com is not the standard). – davmac Nov 27 '16 at 17:55
  • @davmac - I understand, and that happens just because the standard doesn't clearly define pointers. And now we discuss raw pointers, smart pointers, "this" pointer, pointer variables and pointer values. Some - are objects, some - are not. – SChepurin Nov 27 '16 at 18:03
  • 1
    @SChepurin The standard defines pointers (in 8.3.1 "Pointers"). All raw pointers which occupy storage are objects. In the context of this question, the pointer designated by `y` is clearly an object. That pointers might not be objects is not something that the standard allows for, from my reading ("pointer" is the object, "pointer value" is its value). The "`this` is not an object" claim is not actually stated in the standard at all. (That `this` is a prvalue does not require that it does not refer to a value stored in an object.) If part of the actual standard contradicts, feel free to quote. – davmac Nov 27 '16 at 18:23
  • 1
    My point is that a pointer is not the same as the object it is pointing to (if any). – Basile Starynkevitch Nov 27 '16 at 20:49
  • 1
    @SChepurin: The standard does clearly define lvalue pointers as "objects". In C++ terminology "variable", "object" and "data lvalue" are virtually synonymous concepts. `this` pointer is not an lvalue, which is why it is not an object. All lvalues of pointer type are objects. – AnT stands with Russia Nov 27 '16 at 20:54
  • @AnT - "The standard does clearly define lvalue pointers as "objects". - Yes. And that is exactly what i wanted to say: The person has to correctly interpret the standard to come to conclusion that "in C++ terminology" "this pointer is not an lvalue, which is why it is not an object". – SChepurin Nov 28 '16 at 07:25
  • @SChepurin is the problem the missing "variables" in the sentence? "The standard clearly defines pointer _variables_, and eg int variables, as objects (just as in C)" - is how it was intended to be read. I had thought this was clear from context (it's clearly talking about variables) and ongoing discussion. I think that whether pointer values (including `this`) are or are not objects is besides the point. – davmac Nov 28 '16 at 10:04
  • @davmac - "is the problem the missing "variables" in the sentence?" - Of course this matters. And also, i would avoid the sentence - "the standard clearly defines". – SChepurin Nov 28 '16 at 10:28
  • @SChepurin in that case, you have interpreted my comment in the wrong context, as I say. 'i would avoid the sentence - "the standard clearly defines"' - we'll have to agree to disagree on that. – davmac Nov 28 '16 at 10:31
  • @davmac - Finally, defined clearly enough to disagree. :) – SChepurin Nov 28 '16 at 10:38
  • @davmac the standard defines objects by enumerating ways in which they are created (1.8[intro.object]). The expression `this` is not on that list. In non-lawyerese, `this` has no address, and no object identity, it's just a value. Pointer variables (created by definitions, which is the first item on that list) are, of course, objects. – Cubbi Dec 15 '16 at 14:24
  • 2
    @Cubbi this is getting out of hand. There is no reason why the value of `this` cannot be stored in a temporary object, which 1.8 allows ("An object is created ... by the implementation (12.2) when needed|). But that's beside the point; the answer says "Your y is a pointer (not an object ...)" but `y` by definition defines an object (which holds a pointer value) according to the same section 1.8. Pointer variables represent objects. Whether `this` is an object or not has no bearing on the answer or question and so does not bear discussing here. – davmac Dec 15 '16 at 20:04
4

1) Because when the objects of a class are created, there will be no memory allocated for theirs static members - so lines 1&2 declare that there should be such members, but lines 3&4 define where the memory should be allocated.

2) There is literally no big difference - both x and y are just members of class Second, but of different type. x is of type First and its size equals to sum of First members. y is of type First* - its size depends on a size of pointer used in a particular compilator.

3) There is already a good answer about memory allocation for static members. The most common implementation is to use data segment of a program.

Community
  • 1
  • 1
Artalus
  • 1,114
  • 12
  • 25
2

Q1 When you write a class statement it is usually the declaration. No actual data members are allocated anywhere. For non-static members, the definition takes place upon instantiation, when the constructor is being called. However, static members are not related to instantiation. They should be allocated once, and you should decide where. This is the reason for the actual definition. That file (when compiled) will be responsible to actually allocate those members.

That actually answers Q3 as well. As for Q2, I am not sure what is the exact question.

Mike
  • 1,215
  • 7
  • 12