static CS106L Spring 2009 Handout #21 May 12, 2009 Introduction

Similar documents
Copy Constructors and Assignment Operators

Member Initializer Lists

const int length = myvector.size(); for(int i = 0; i < length; i++) //...Do something that doesn't modify the length of the vector...

Assignment 1: grid. Due November 20, 11:59 PM Introduction

Special Member Functions


Special Member Functions. Compiler-Generated Destructor. Compiler-Generated Default Constructor. Special Member Functions

Chapter 1 Getting Started

Programming in C++ Prof. Partha Pratim Das Department of Computer Science and Engineering Indian Institute of Technology, Kharagpur

Chapter 10 Pointers and Dynamic Arrays. GEDB030 Computer Programming for Engineers Fall 2017 Euiseong Seo

CSCI-1200 Data Structures Spring 2018 Lecture 10 Vector Iterators & Linked Lists

3.Constructors and Destructors. Develop cpp program to implement constructor and destructor.

QUIZ. What is wrong with this code that uses default arguments?

Assignment 1: SmartPointer

Functions, Pointers, and the Basics of C++ Classes

Arrays. Returning arrays Pointers Dynamic arrays Smart pointers Vectors

Chapter 10. Pointers and Dynamic Arrays. Copyright 2016 Pearson, Inc. All rights reserved.

CSCI-1200 Data Structures Fall 2017 Lecture 10 Vector Iterators & Linked Lists

Supporting Class / C++ Lecture Notes

CS2141 Software Development using C/C++ C++ Basics

Object-Oriented Programming, Iouliia Skliarova

Ar r ays and Pointer s

C:\Temp\Templates. Download This PDF From The Web Site

CPSC 427a: Object-Oriented Programming

7.1 Optional Parameters

C++ 8. Constructors and Destructors

CS103 Spring 2018 Mathematical Vocabulary

CS93SI Handout 04 Spring 2006 Apr Review Answers

A PROGRAM IS A SEQUENCE of instructions that a computer can execute to

Super-Classes and sub-classes

Chapter 17 vector and Free Store. Bjarne Stroustrup

Chapter 11: Resource Management

AIMS Embedded Systems Programming MT 2017

III. Classes (Chap. 3)

Fast Introduction to Object Oriented Programming and C++

1 Getting used to Python

Programming Data Structures and Algorithms Prof. Shankar Balachandran Department of Computer Science Indian Institute of Technology, Madras

Slide 1 Side Effects Duration: 00:00:53 Advance mode: Auto

Computer Science II CSci 1200 Lecture 18 Operators and Friends

The Stack, Free Store, and Global Namespace

CS201 Some Important Definitions

CPSC 427: Object-Oriented Programming

C++ for Java Programmers

class Array; // Class template declaration class Array public: // T="type",e.g.,int or float Array(int n); // Create array of n elements Array(); // C

5.6.1 The Special Variable this

Pointer Basics. Lecture 13 COP 3014 Spring March 28, 2018

Variables. Data Types.

Type Checking and Type Equality

CSE 333 Autumn 2013 Midterm

Preconditions and Postconditions

CMSC 341 Lecture 6 Templates, Stacks & Queues. Based on slides by Shawn Lupoli & Katherine Gibson at UMBC

G52CPP C++ Programming Lecture 13

Problem Set 1. You might want to read Chapter 12 of the course reader before attempting this problem.

Introduction to Programming in C Department of Computer Science and Engineering. Lecture No. #29 Arrays in C

Exercise 6.2 A generic container class

6.096 Introduction to C++

Introduction to C++ Introduction to C++ Dr Alex Martin 2013 Slide 1

CS Final Exam Review Suggestions - Spring 2014

Lecture 2, September 4

Quiz Start Time: 09:34 PM Time Left 82 sec(s)

Consider the above code. This code compiles and runs, but has an error. Can you tell what the error is?

Object Oriented Software Design II

CS201 Latest Solved MCQs

COSC 2P95 Lab 5 Object Orientation

Introduction to C++ Introduction. Structure of a C++ Program. Structure of a C++ Program. C++ widely-used general-purpose programming language

Constants, References

CS 2505 Computer Organization I Test 1. Do not start the test until instructed to do so!

CSc 328, Spring 2004 Final Examination May 12, 2004

Increases Program Structure which results in greater reliability. Polymorphism

School of Computer Science CPS109 Course Notes 5 Alexander Ferworn Updated Fall 15

Annotation Annotation or block comments Provide high-level description and documentation of section of code More detail than simple comments

377 Student Guide to C++

Introduction to C++ with content from

M.EC201 Programming language

Programming in C++ Prof. Partha Pratim Das Department of Computer Science and Engineering Indian Institute of Technology, Kharagpur

CSCI 102 Fall 2010 Exam #1

Modern C++ for Computer Vision and Image Processing. Igor Bogoslavskyi

CS201- Introduction to Programming Current Quizzes

Learning Objectives. Introduction to Arrays. Arrays in Functions. Programming with Arrays. Multidimensional Arrays

Short Notes of CS201

Protection Levels and Constructors The 'const' Keyword

Page. No. 1/15 CS201 Introduction to Programmming Solved Subjective Questions From spring 2010 Final Term Papers By vuzs Team

5. Control Statements

CS201 - Introduction to Programming Glossary By

And Even More and More C++ Fundamentals of Computer Science

Chapter 6 Classes and Objects

Introduction to Programming Using Java (98-388)

Chapter 17 vector and Free Store

Lecturer: William W.Y. Hsu. Programming Languages

COP 3330 Final Exam Review

Chapter 17 vector and Free Store

Ch. 11: References & the Copy-Constructor. - continued -

CS143 Handout 05 Summer 2011 June 22, 2011 Programming Project 1: Lexical Analysis

Chapter 18 Vectors and Arrays [and more on pointers (nmm) ] Bjarne Stroustrup

6.001 Notes: Section 6.1

Final CSE 131B Spring 2004

CPS311 Lecture: Procedures Last revised 9/9/13. Objectives:

CS193D Handout 10 Winter 2005/2006 January 23, 2006 Pimp Your Classes

a data type is Types

Pointers and Memory 1

Transcription:

CS106L Spring 2009 Handout #21 May 12, 2009 static Introduction Most of the time, you'll design classes so that any two instances of that class are independent. That is, if you have two objects one and two, changes to one shouldn't affect two in any way. However, in some circumstances you'll want to share data among all copies of a class. For example, perhaps you'll want all copies of a class to access a single global resource, or perhaps there's some initialization code you'd like to call when you create the very first instance of a class. C++ thus provides the static keyword to create class-specific information shared by all copies of that class. Like const, static has its nuances and at times can be a bit counterintuitive. This handout discusses static member functions, their relation to const, and static data members. static Data Members In C++, static data members are class-specific variables that are shared by each instance of that class. That is, if you have multiple instances of a class, each uses the same copy of that variable, so changes to static data members affect multiple objects. The syntax for declaring static data members is a bit confusing since it exists in two steps declaration and definition. For example, suppose you have the following class definition: class MyClass /* Omitted */ static int mystaticdata; ; Here, mystaticdata is declared as a static data member with the static keyword. However, the line static int mystaticdata does not actually create the variable mystaticdata. Instead, it simply tells the compiler that there will be a variable called mystaticdata shared among all class instances. To initialize mystaticdata, you will need to add another line to your program that looks like int MyClass::myStaticData = 137; There are several important points to note here. First, when declaring the variable, you must use the fully-qualified name MyClass::myStaticData instead of just mystaticdata. Second, you do not repeat the static keyword during the variable declaration otherwise, the compiler will think you're doing something completely different (see the More to Explore section). Finally, although mystaticdata is declared private, you are still allowed to (and in fact, are required to) declare it outside of the class definition. The reason for this two-part declaration/definition for static data is a bit technical and has to do with where the compiler allocates storage for variables, so for now just remember that static data has to be separately declared and defined. - 1 -

Static data members look just like regular data members in almost every aspect beyond declaration. Consider the following member function of MyClass called dosomething: void MyClass::doSomething() ++mystaticdata; // Modifies mystaticdata for all classes Nothing here seems all that out-of-the-ordinary and this code will work just fine. Note, however, that when you're modifying mystaticdata, you are modifying a variable that any number of other instances of MyClass might be accessing. Thus it's important to make sure that you only use static data when you're sure that the information isn't specific to any one instance. To understand how static data members can be useful, let's consider an example case. Suppose that you're debugging some code and you're pretty sure that you've forgotten to delete all copies of a certain object you've allocated with new. Since C++ won't give you any warnings about this, you'll need to do the instance counting yourself, and you decide to use static data members to do the trick. The number of active instances of a class is class-specific information that doesn't pertain to any specific instance of the object. This is the perfect spot to use static data members, so to do our instance counting, we'll insert the following declaration into our class definition: static int numinstances; We'll also define the variable outside the class as int MyClass::numInstances = 0. We know that whenever we create a new instance of the class, the class's constructor will be called. This means that if we increment numinstances inside the class's constructor, we'll correctly track the number of instances of the class that have been created over time. Thus, we'll rewrite the MyClass constructor to look like MyClass::MyClass() // All older initialization code ++numinstances; Similarly, we'll decrement numinstances in the destructor. We'll also have the destructor print out a message if this is the last remaining instance of the class so we can see how many instances are left: MyClass::~MyClass() // All older cleanup code --numinstances; if(numinstances == 0) cout << "No more active instances!" << endl; - 2 -

static Member Functions Inside of member functions, a special variable called this acts as a pointer to the current object. Whenever you're accessing instance variables, you're really accessing the instance variables of the this pointer. But how does C++ know what value this refers to? The answer is subtle but important. Suppose you have a class MyClass with a member function dosomething that accepts two integer parameters. Whenever you invoke dosomething on a MyClass object using this syntax: myinstance.dosomething(a, b); It's as though you're actually calling dosomething(&myinstance, a, b); Where dosomething is prototyped as void dosomething(myclass *const this, int a, int b). For almost all intents and purposes this is a subtle distinction that from your standpoint as a programmer should rarely be of interest. However, the fact that an N-argument member function is really an (N+1)-argument free function can cause problems in a few places. For example, suppose you're writing a class Point that looks like this: class Point bool comparetwopoints(const Point &one, const Point &two) const if(one.x < two.x) return true; if(one.x > two.x) return false; return one.y < two.y; int x, y; ; If you have a vector<point> that you'd like to pass to the STL sort algorithm, you'll run into trouble if you try to use this syntax: sort(myvector.begin(), myvector.end(), &Point::compareTwoPoints); The problem is that the sort function expects a function that takes two parameters and returns a bool. However, you've provided a function that takes three parameters: two points to compare and an invisible this pointer. Thus the above code will generate an error. In cases like this, you'll want to create a member function that doesn't have an invisible this. These functions are referred to as static member functions and are functions that act like free functions but that exist within the scope of a class. Thus, if you changed the declaration of comparetwopoints to read static bool comparetwopoints(const Point &one, const Point &two)... - 3 -

The call to sort would work since comparetwopoints would no longer have a this pointer. Because static member functions don't have a this pointer, you cannot access or modify any instance variables inside a static member function. However, you may refer to any static data members of the class, since they exist independently of any specific class instance. Let's return to our earlier example about tracking the number of instances of an object currently in use. While it's nice that the destructor prints out a message when the last instance has been cleaned up, we'd prefer a more robust model where we can call a member function to check how many more copies of the class exist. Since this function should be independent of any class instance (that is, you don't need to have an object to check how many more remaining objects of that type exist), we'll make the function getremaininginstances a static member function, as shown here: class MyClass /* Constructor, destructor, etc. */ static int getremaininginstances(); static int numinstances; ; int MyClass::numInstances = 0; Then the implementation of getremaininginstances might look something like this: void MyClass::getRemainingInstances() return numinstances; As with static data, note that when defining static member functions, you omit the static keyword. Only put static inside the class declaration. You can invoke static member functions either using the familiar object.method syntax, or you can use the fully qualified name of the function. For example, with the above example, we could check how many remaining instances there were of the MyClass class by calling getremaininginstances as follows: cout << MyClass::getRemainingInstances() << endl; const and static Unfortunately, the const and static keywords do not always interact intuitively. One of the biggest issues to be aware of is that const member functions can modify static data. That is, even if you're working with a const object, it is still possible that that object will change state between member function calls. For example, consider the following class: - 4 -

class ConstStaticClass void constfn() const; static int staticdata; ; int ConstStaticClass::staticData = 0; Then the following implementation of constfn is completely valid: void ConstStaticClass::constFn() const ++staticdata; Although you might think that this code is invalid since you're modifying the class's data inside a const member function, the above code will compile and run without any problems. The reason has to do with what const literally means. To see this, we'll have to revisit the this keyword. Recall that this is a pointer to the current object in the context of a member function. Thus, whenever you writing code in a member function like myinstancevariable = 137, the compiler treats it as though you wrote this->myinstancevariable = 137. Inside a const member function, the compiler treats this as a pointer-to-const, so statements like this->myinstancevariable = 137 won't work since you're modifying the data of a pointer-to-const. However, static data members are treated differently than regular instance variables because each instance of the class shares a single instance of the data. This means that access to a static data member doesn't go through the this pointer, so the fact that this is a pointer-to-const won't prevent you from modifying static data members. Again we return to the issue of bitwise versus semantic constness. While it's legal to modify static data members in a const function, you should nonetheless make sure that const code isn't going to change the state of the current object. Additionally, since static member functions don't have a this pointer, they cannot be declared const. In the case of getnuminstances, this means that although the function doesn't modify any class data, we still cannot mark it const. Thus when working with static member functions, make sure that if the function modifies class data, you somehow communicate that information to other programmers. Integral Class Constants There is one other topic concerning the interaction of const and static that can be a bit vexing class constants. Suppose you want to make a constant variable accessible only in the context of a class. Thus, what you'd want is a variable that's const, so it's immutable, and static, so that all copies of the class share the data. It's legal to declare these variables like this: - 5 -

class ClassConstantExample /* Omitted. */ static const int MyConstant; ; const int ClassConstantExample::MyConstant = 137; However, since the double declaration/definition can be a bit tedious, C++ has a built-in shorthand you can use when declaring class constants of integral types. That is, if you have a static const int or a static const char, you can condense the definition and declaration into a single statement by writing; class ClassConstantExample /* Omitted. */ static const int MyConstant = 137; // Condense into a single line ; This shorthand is common in professional code. Be careful when using the shorthand, though, because some older compilers won't correctly interpret it. Also, be aware that this only works with integral types, so you cannot initialize a static const double or static const float this way. More to Explore While this handout discusses static in relation to classes, there are three other meanings of static. The first is static linkage specification, which means that the specified member function or global variable can only be accessed by functions defined in the current file. Another is static local variables, local variables whose values are preserved between function calls. Also, there are static class definitions, a way to declare a class that cannot be instantiated except in one location. These techniques are common in practice, so you should be sure to check a reference text for some more info on their subtleties. Practice Problems 1. Explain why static member functions cannot be marked const by explaining exactly what the two terms mean and why their interaction is undefined. 2. Write a class UniquelyIdentified such that each instance of the class has a unique ID number determined by taking the ID number of the previous instance and adding one. The first instance should have ID number 1. Thus the third instance of the class will have ID 3, the ninetysixth instance 96, etc. Also write a const-correct member function getuniqueid that returns the class's unique ID. Don't worry about reusing older IDs if their objects go out of scope. - 6 -