Static implementation in C++ and other languages

Introduction

This blog post discusses the concepts and implementation of static members in programming language. Static member has a fixed allocation in memory and a lifetime that spans the entire execution of the program. Static member doesn't really mean constant values.

Both C++ and Java uses static keyword to make a member static, while Kotlin uses companion. C++ and Java static members are slightly different from Kotlin and will be discussed in detail.

Concepts

The following describes general concepts of static member that are applicable to C++, Java and Kotlin.

For Kotlin, companion keyword is equivalent to static keywords.

  • Static member variables:
    • Initialization:  are initialized only once as they are allocated space in separate static storage so, the static variables in a class are shared by the objects. For C++ program, the static member variable has to be initialized outside the class definition and used a scoped resolution. For Java, it needed not be initialized outside the class definition.
    • Memory allocation: static variables are stored in data segment of the virtual memory layout of a C++ program. But for Java Virtual Machine, static variables are stored in Method Area.
    • Access: static member variable should be accessed using the class name rather than an instance of the class
      • Note for C++: only public static variables are accessible outside class definition using class name.
  • Static member functions:
    • Memory allocation: For C++, static functions are in program's executable code section and loaded into memory when the program starts. For Java, it is in Method Area of JVM .
    • Access:  static member functions also do not depend on the object of the class. We are allowed to invoke a static member function using the object and the ‘.’ operator but it is recommended to invoke the static members using the class name and the scope resolution operator.
    • Modification of member values: static member functions can only modify the static member variables in the same class. Likewise, for Java, and Kotlin
The Virtual Memory Layout of a C++ program
Architecture of a Java Virtual Machine

C++ Implementation

The following C++ program demonstrates:

  1. a static private variable, and cannot be initialized from within the class definition
  2. all objects access the same variable, as it is assigned a static location.
  3. public static variable can be accessed from within a class definition. Outside a class definition, it has to accessed using class name, not instance of the class. Private static member variable cannot be accessed outside the class definition directly but only via member function.
  4. Only static member functions can modify static member variables.
#include <iostream>
using namespace std;

class MyClass {
private:
    static int myPrivateVar;
public:
    static int myPublicVar;
    // 4. only static function can modify static object
    static void myStaticMethod(int x, int y) {
        myPrivateVar += x; // Access and modify private member
        myPublicVar  += y;
        cout<<myPrivateVar<<" "<<myPublicVar<<endl;
    }
};

// 1. Initialize static variable outside class definition
int MyClass::myPrivateVar = 0; 
int MyClass::myPublicVar  = 0; 

int main() {
    
    MyClass::myStaticMethod(5,6);  // Output: 5,6
    // MyClass::myPrivateVar;      // error
    
    // 3. outside class definition, access static member with class name
    MyClass::myPublicVar = 10;
    MyClass::myStaticMethod(5,6);  // Output: 10,16
    
    // 2. all objects share the same static member
    MyClass obj1, obj2;
    obj1.myStaticMethod(10, 10);    // Output: 20,26
    obj1.myStaticMethod(100, 100);  // Output: 120,126
    return 0;
}

Java Implementation

The following Java program demonstrates:

  1. a static private variable, and can be initialized from within the class definition
  2. all objects access the same variable, as it is assigned a static location.
  3. it can be accessed from within a class definition. Outside a class definition, it has to accessed using class name, not instance of the class
  4. any function can modify the static member.
public class MyClass {
    // 1. static variable can be initialized inside class definition
    private static int myStaticVar = 0;
    // 2. this function demonstrates that all object can access the same static member
    // 4. any function can modify the static member
    public void myMethod() {
        myStaticVar++;
        System.out.println("myStaticVar: " + myStaticVar);
    }
    
    public static void main(String[] args) {       
        MyClass obj1 = new MyClass();
        MyClass obj2 = new MyClass();
        // static variable are declared once and assigned a location
        // all objects share it, thus they all modify the values
        obj1.myMethod(); // outputs "myStaticVar: 1"
        obj2.myMethod(); // outputs "myStaticVar: 2"
        // 3. public static variable should be accessed using class name.
        MyClass.myStaticVar = 100;
        obj1.myMethod(); // outputs "myStaticVar: 101"
        obj1.myStaticVar = 999;
        obj1.myMethod(); // outputs "myStaticVar: 1000"
    }
}

Kotlin Implementation

The following Kotlin program demonstrates:

  1. companion member properties, and can be initialized from within the class definition. In general,
    "Property must be initialized or be abstract"
  2. all instance of class access the same properties, as it is assigned a static location.
  3. public companion member variable can be accessed from within a class definition. Outside a class definition, it has to accessed using class name, not instance of the class
  4. any companion function can modify the companion member.
  5. any public companion member function must be called using class name.
class Car {
    public var owner : String ?= null   
    companion object {
        // 1. companion member properties, can be initialized from within the class definition
        public  var bodyColor : String = "red"
        private var body      : String = "sedan"
        
        // 4.any companion function can modify the companion member.      
        fun changeBody ( style: String , color: String) {
            body = style
            bodyColor = color
            // 4. companion function cannot modify non-companion properties
            // owner = "Freewind"
        }
    
        fun getColor() : String {
            return bodyColor
        }
   
        fun getBodyStyle() : String {
            return body
        }
    }
}

fun main() {Style
    //3. public companion member variable can be accessed using class name.
    Car.bodyColor = "purple"
    println(Car.getColor())
    
    Car.changeBody("Convertible", "Blue")
    // 5. any public companion member function must be called using class name.
    println(Car.getBodyStyle())
    
    // 2. Error. Only ublic companion member variable can be accessed using class name
    // Car.body 
}

Leave a Reply

Your email address will not be published. Required fields are marked *