Download presentation
Presentation is loading. Please wait.
Published byShannon Underwood Modified over 8 years ago
1
Department of Computer Science and Engineering, HKUST 1 HKUST Summer Programming Course 2008 Using Member Functions and Data Members
2
2 Overview Accessing member functions Inspector Function (Accessor) Mutator Function Function Overloading Friend Functions/Class Static Member Functions Static Data Member Data Sharing - extern Changing Constant Objects - mutable
3
3 Accessing member functions Use member access operator (.) Word vowel(“a”, 12); vowel.addfreq(3);// call a member function // in Word class Use dereference member access operator (->) // a pointer to a Word object Word* boy = new Word(“boy”, 2); vowel->addfreq(1); It is equal to a deference operator plus a member access operator, i.e. (*boy).addfreq(1);
4
4 Inspector Function (Accessor) An inspector function allows programmers to read (but not modify) data members of the class. It has another name called “ accessor ” or “ gettor ”. Usually it has a “ get ” as prefix and declared as a constant function. int Word::getfreq() const { return frequency; } char* Word::getword() const { if (str != NULL) { char *temp = new char [strlen(str)+1]; strcpy(temp, str); return temp; } else { return NULL; } }
5
5 Mutator Function A mutator function (or called “ settor ” ) modifies data members of the class. Usually it has a “ set ” as prefix. You can use “ const ” and pass-by-reference(&) to avoid unnecessary copying and prevent accidental change of parameter content. int Word::setfreq(const int& new_freq) { frequency = new_freq; return frequency;// return the new frequency // but it is not necessary, // you can use “void” instead }
6
6 Function Overloading We can define a few functions using the same name with different kinds of argument. That will increase the usability of your class. E.g. void Word::setword(const char* new_word) { … } void Word::setword(const string& new_word) { … } Both of them has the name “setword” but accept different argument. User can use “char*” or “string” in this function.
7
7 Function Overloading When overloading functions, we have to pay attention to their signature. A function’s signature includes its parameter list and const-ness of function (except its return type), i.e. int Word::addfreq(int amount); int Word::addfreq(float amount); int Word::addfreq(int amount) const; All of the above are valid overloaded functions. Be careful, const function and non-const function are considered different. (1 st and 3 rd example)
8
8 Friend Functions/Class A friend function of a class is an ordinary (nonmember) function except that it has access to the private members of the objects. We usually place friend function prototypes in the “public” section. General guidelines: Use a nonmember/friend function only if the task being performed involves multiple objects. Whether an ordinary nonmember function or a friend function should be used is a matter of efficiency and personal taste.
9
9 Friend Functions/Class void print_date(const Date& today, const Clock& time) { cout << today.day << “-” << today.month << “-” << today.year; cout << “ “ << time.hour << “:” << time.minute << endl; } To let the above function work, we can put its prototype to both Date and Clock class. class Date { public: friend void print_date(const Date&, const Clock&); … }; // class Clock is similar
10
10 Friend Function/Class Friend class is similar to friend functions. You can put the declare of a class as friend class in another class. Usually when a class is controlled by another class, it will let the controller class to touch its private members, e.g. In a linked-list, the Node class can friend the List class to let it touch its data. class Node { public: friend class List; … }; One important thing: If you friend a class, that class can access all your private data, but not in reverse.
11
11 Static Member Functions For example, we have a clock class like this, class Clock { private: int hour, minute; public: Clock(int h = 0, int m = 0) : hour(h), minute(m) { } void tick(); void print(); }; // Global functions that will call the clock constructor Clock make_clock_hhmm(int hhmm) { return Clock(hhmm/100, hhmm%100); } Clock make_clock_minutes(int min) { return Clock(min/60, min%60); }
12
12 Static Member Functions In order to let user have two ways to create a clock (in hhmm or in minutes, both are int type), we created two global functions to help our user. It seems good, but it has some drawbacks, They are not belong to class, so it is easy to forget them when we update the codes in the class. They are global functions, so they can’t access private data of a class. (or we can use friend functions.)
13
13 Static Member Functions A better solution is to use static member functions. class Clock { … public: static Clock HHMM(int hhmm) {…} static Clock minutes(int i) {…} }; Static methods of a class are really global functions with a “funnyname”. They belong to the class, and can access private data. NO object is required to invoke them, they exist whenever the class exists.
14
14 Static Member Functions class Clock { private: int hour, minute; Clock(int h, int m) : hour(h), minute(m) { } public: Clock() : hour(0), minute(0) { } void tick(); void print(); static Clock HHMM(int hhmm) { return Clock(hhmm/100, hhmm%100); } static Clock minutes(int i) { return Clock(i/60, i%60); } }; // Now we can set clocks Clock c1; // 0:00 Clock c2 = Clock::HHMM(120);// 1:20 Clock c3 = Clock::minutes(120); // 2:00
15
15 Static Data Member Classes can also have static data members. Static data members are really global variables with a funny name. They also follow access control (public and private), just like normal variables. class Car { private: static int num_cars; // count total number of // Car objects produced int total_km; public: Car():total_km(0) { ++num cars; } ~Car() { --num cars; } static int cars_produced() { return num_cars; } };
16
16 Static Data Member #include "car.h" int Car::num cars = 0; // definition of static member int main() { cout << Car::cars_produced() << endl; // prints 0 Car vw; Car bmw; cout << Car::cars_produced() << endl; // prints 2 return 0; } /* It can count the number of objects produced. But remember, if you don’t provide your own copy constructor and assignment operator(=), the counting will be wrong. Because the default copy constructor don’t know how to count objects. */
17
17 Static Data Member Static variables are shared among all objects of the same class. They do not take up space inside an object. Static variables, though act like global variables, cannot be initialized in the class definition. Instead, they must be defined outside the class definition. Usually the definitions of static variables are put in the class implementation (.cpp) file.
18
18 Static Data Member Static member functions can only use static data members of the class. Because static methods do not have the implicit this pointer like regular member functions, e.g. A regular member function of Car like void drive(int km) { total_km += km; } after compilation becomes: void Car::drive( Car* this, int km){ this->total_km+=km; } On the other hand, a static method of Car like static int cars_produced() { return num_cars; } after compilation becomes: int Car::cars_produced() { return num_cars; }
19
19 Data Sharing - extern Extern means a variable (or function) has an external linkage with a variable (or function) in another file. External variable declaration: extern int global_var; External function declaration extern void reverse_print(const char* s); The above two are declaration only, they are not the real variable. They don’t have memories assigned. The actual variable (or function) is defined in another file.
20
20 Data Sharing - extern // main.cpp extern int global_var; extern void rev_print(const char* s); int main(int argc, const char* argv[]) { cout << “global var = “ << global_var << endl; cout << “input string backwards = “; rev_print(argv[1]); } // Output: // global var = 23 // input string backwards = … // otherfile.cpp // compile it with main.cpp int global_var = 23; void rev_print( const char* s){ for (int j = strlen(s)-1; j >= 0; --j) { cout<< s[j]; } cout<< endl; } // Actual variables and functions // are defined here
21
21 Changing Constant Objects - mutable The concept is easy: when a variable is declared as mutable, its content can be changed even if the object is a constant. class Word { public: char* str; mutable int frequency; // can be changed }; const Word movie(“Superman”, 0);// const object movie.frequency += 1;//it is ok
Similar presentations
© 2024 SlidePlayer.com Inc.
All rights reserved.