-4

Why can I use double colons in functions and classes not defined but I can't use in variables ??

Example:

#include <iostream>

using namespace std;

class Person{

    public:
        int age;
        string name();
};

int Person::age = 10; //It outputs an error

string Person::name(){ //It doesn't
    return "n";
}
Dormin
  • 23
  • 1
  • 6

1 Answers1

8

Why can I use double colons in functions and classes not defined but I can't use in variables ??

age is an instance field, it exists in multiple places in memory - one for each Person that exists.

I'll now expand in detail about what the :: operator does, how to use it, and how static class members compare to instance members:

The :: operator:

The :: (the scope-resolution operator) has multiple uses in C++:

If you're familiar with Java, C# or JavaScript then it can be likened to the dot dereference or "navigation operator" . (e.g. namespace.Class.Method().Result) - except C++ uses a different operators for different kinds of navigation and dereferencing:

  • . is the member-access operator, similar to C - it's only applicable for "object values" and references (foo&), not pointers (foo*).
  • -> is another member-access operator for pointer types, note that this operator can be overridden but . cannot (overridin -> is risky but it improves the ergonomics of smart-pointer libraries when done correctly).
  • :: is the scope-resolution operator - it has a few different uses:
    • Namespace navigation - whereas Java and C# use . to navigate packages and namespaces, C++ uses ::, for example: using std::time.
    • When unqualified, it's also used to reference the global namespace, e.g. ::std which is handy if you're writing code which is already in a namespace.
    • It's also used to access static members of types - typically an actual static member (a static method or field) but also items like enum class (scoped enumeration) values (e.g. SomeEnumClass::value_name)
    • Finally, it's also used to select a specific base method when dealing with virtual method implementations: it's used when an overridden method needs to call a base implementation in a superclass - C++ does not have the singular base or super keywords that C# and Java have (respectively) because C++ allows multiple inheritance, so you must specify the specific parent class name: How to call a parent class function from derived class function?

Anyway, in your case, it looks like you're confused about what instance and static members actually mean, so here is an illustration:

class Person {
public:
    int height; // each Person has their own height, so this is an instance member
    static int averageHeight; // but an individual Person doesn't have an "average height" - but a single average-height value can be used for all Persons, so this is a shared ("static") value.

    int getAverageHeight() { // this is an instance method, btw
        return Person::averageHeight; // use `Person::` to unambiguously reference a static member of `Person`
    }

    Person()
    : height(0) {
        // instance members should be initialized in the constructor!
    }
}

// This will create an array of 10 people (10 different object instances).
// Each Person object (an instance) will have its own `height` in memory
Person* multiplePeople = new Person[10];

// btw, you probably should use `std::array` with an initializer instead:
// array<Person,10> multiplePeople{}; // <-- like this

// This sets a value to the `staticField` member, which exists only once in memory, that is, all Person instances share the same value for this member...
Person::averageHeight = 175; // 175cm

// ...for example:
assert( 175 == multiplePeople[3]->getAverageHeight() );
assert( 175 == multiplePeople[6]->getAverageHeight() );

// However instance members can have different values for each instance:
multiplePeople[3]->height = 170;
multiplePeople[6]->height = 180;

// Btw `height` is initialized to 0 in each Person's constructor.
assert( 170 != multiplePeople[0]->height );
assert( 180 != multiplePeople[7]->height );
Dai
  • 141,631
  • 28
  • 261
  • 374
  • @VladfromMoscow His question was about the background and use of the `::`operator - why do you think I didn't answer his question correctly? – Dai Jun 07 '17 at 01:31
  • @Dai The operator can be used also with non-static data members. – Vlad from Moscow Jun 07 '17 at 02:14
  • why use (raw!) Pointers explaining something like this to a beginner, why not use a vector of persons. – Brosch Sep 29 '22 at 22:25