交通大學資訓工程學系 蔡文能 1 Some other issues in C++ 蔡文能...

Post on 18-Jan-2016

285 views 0 download

Transcript of 交通大學資訓工程學系 蔡文能 1 Some other issues in C++ 蔡文能...

交通大學資訓工程學系 蔡文能

1

Some other issues in C++

蔡文能tsaiwn@csie.nctu.edu.twtsaiwn@cs.nctu.edu.tw

交通大學資訊工程學系2006/08/23

交通大學資訓工程學系 蔡文能

2

Agenda

• Namespace

• static ?

• const ?

• cast in C++

• C++ Class Library

• STL – Standard Template Library

• Exception handling

http://tsaiwn.net/cpp/

http://www.csie.nctu.edu.tw/~tsaiwn/cpp

交通大學資訓工程學系 蔡文能

3

Namespaces• variables with same name and different scopes can overlap

– need to distinguish them

• a namespace defines a scope for local and global identifiers.– body delimited by braces {}– use (::) to access namespace members: namespace_name::member

– or, a using statement must occur before name is usedusing namespace namespace_name;

-members of the namespace do not need a prefix

– not guaranteed to be unique

– can be nested

using namespace std; //for STL

例如 std::cout

交通大學資訓工程學系 蔡文能

4

神奇的 “ static” On a global variable or a function

static long myData[38]; //information hidingstatic void myFunction(float);– Tells the linker not to export the variable or function. – Makes the identifier “file scope,” as the linker will not use it fulfill

dependencies from other files. On a local variable in a function

void someFunc(void) {static int array[4000];

}Places the variable off the stack. This has the side-effect that it retain

s it value across calls. It is often used when a variable is too large to be put on the stack. (auto 變數則在 stack)

On a class member data or member function (next slide)

交通大學資訓工程學系 蔡文能

5

Static Global 變數 #include <stdio.h>

#define BUFSIZE 100

static char buf[BUFSIZE];

int bufp = 0;

int getch( ) {

/* . . . */

}

void ungetch(int c) {

/* . . . */

}

參考 K&R 課本 4.6節

也參考 stack 的 push 和 pop 寫在同一獨立 file 中 , push 和 pop 共享 data

別的檔案中任何 function 都看不見這個 static 的變數

交通大學資訓工程學系 蔡文能

6

再談 Static Global 變數 #include <stdio.h>

#define RAND_MAX 65535

static unsigned long seed=0;

int rand( ) {

seed = seed * 1103515245 + 12345;

return seed % (RAND_MAX+1);

}

void srand(int newseed) {

seed = newseed;

}

參考 K&R 課本 4.6節

Pseudo random number

交通大學資訓工程學系 蔡文能

7

Static Local 變數 #include <iostream.h>

int fa( ) { int x = 1;

return x++; /* 先取其值 , 再做 ++ */ }

int fb( ) { static int x = 1; /* 注意 static int x = 1; */

return x++; }

int main( ) {

cout << "fa( )=" << fa( )<<fa( )<<fa( ) << endl;

cout << "fb( )=" << fb( )<<fb( )<<fb( ) << endl;

return 0; /* 0 in main( ) means OK */

} return x++; 和 return ++x; 不同 !

(1/2)

交通大學資訓工程學系 蔡文能

8

Static Local 變數 int fa( ) {

int x = 1;

return x++; /* 先取其值 , 再做 ++ */

}

int fb( ) {

static // 把 static 寫在下列左方也一樣 int x = 1; // 注意 static int x = 1;

return x++;

}

(2/2)

交通大學資訓工程學系 蔡文能

9

Static Local 變數 , evaluation 順序 #include <stdio.h> int fa( ); /* 宣告 */ int fb( ); int main( ) { /* 不同系統可能不同答案 */ printf( "fa( )=%d %d %d \n",

fa( ), fa( ), fa( ) ); printf( "fb( )=%d %d %d \n",

fb( ), fb( ), fb( ) ); return 0; /* 0 in main( ) means OK */ } // int fa( ) … 也可以寫在另一個檔案內

交通大學資訓工程學系 蔡文能

10

Static class member• static member 不需要透過任何的 object 存取,在無任何

object 時可透過 member selection operators ( 就是 :: 或 Java 仍用 . ) 來存取 .

• Static member functions – Also known as class function (class methods)– Can be called without any instance, for example:

m = Mankind::howmany( ); – Can NOT access instance variables

• Static member data– Also known as class variable– All objects of a class share one copy of a static data member (non-static member data = instance variable)– Usage example: x = Mankind::data_which_is_static;– They are not global variables; they have class scope

All member functions are shared between objects, even the non-static member functions

交通大學資訓工程學系 蔡文能

11

神奇的 “ const” Const object is NOT modifiable const x = 3.14159; // 在 C 與較舊 C++ compile 會過 ; 問題在哪裡 ?

Const parameter can NOT be modified in the functionReturnType FunctionName(long x, const Student y){ /*… to modify y is NOT allowed! 即 y 不可當左值 */ };

Const member function can NOT modify the objectReturnType FunctionName(param1,param2…) const; ReturnType FunctionName(param1,param2…) const { /*… */};

Constructors / Destructors cannot be const- They need to initialize variables (therefore modifying them)

const 是不准變的變數 ! 也佔一塊記憶體 ! 那 #define nsize 99 呢 ?

交通大學資訓工程學系 蔡文能

12

Review: Constants 常數

• #define MAX_LOOP 500– 此稱 define macro 巨集– 是 C 的前處理器之句子 , 結尾不必有分號– 之後用到 MAX_LOOP 會被換成 500

• const double delta = 0.0001;

^^^^^^^^^^^^^^^^ 不可變的變數叫 const

• const PI = 3.14159; /* Error result? PI 為 3*/

交通大學資訓工程學系 蔡文能

13

Character Literal

• 單引號夾住是 char– 'A' 相當於 65 (assume using ASCII)– 'a' 相當於 97 (assume using ASCII)– '0' 相當於 48 (assume using ASCII)

• Wide character ?• Escape Sequence 逃脫序列串

– '\n' == '\012 ' – '\101' == 'A' – '\x41' == 'A'

交通大學資訓工程學系 蔡文能

14

Escape Sequence 逃脫序列串• '\a' == '\007' == CTRL_G == Alert (Bell)

• '\b' == '\010' == CTRL_H == BackSpace

• '\f' == '\014' == CTRL_L == FormFeed

• '\n' == '\012' == CTRL_J == NewLine

• '\r' == '\015' == CTRL_M == Carriage RETURN

• '\t' == '\011' == CTRL_I == TAB (Horizontal Tab)

• '\v' == == Vertical Tab

• ' \\' == == backslash 反斜線• '\?' == == question mark

• '\' ' == == single quote ( apostrophe )

• '\" ' == == double quote (quote)

參考 K&R 課本 2.3節

'\060'

'\x30'

交通大學資訓工程學系 蔡文能

15

Cast in C++• C++ has 4 more separate, specific casts

– Conventional static cast (C-Style): (type)expression

static_cast - conversion between types• type checking at compile time• standard conversions: void* to char*, int to float, etc.• base class pointers to derived class pointers• Format: static_cast<type to convert to>(object to convert)

const_cast - cast away const or volatile • cannot be used directly to cast away const-ness; use pointers

dynamic_cast – for safe navigation of an inheritance hierarchy. • Can be used only for pointer or reference types

reinterpret_cast - for nonstandard casts • one pointer type to another pointer type, void* to int*, etc.• cannot be used for standard casts (int to double, etc.).

交通大學資訓工程學系 蔡文能

16

<algorithm> <bitset> <complex> <deque>

<exception> <fstream> <functional> <iomanip>

<ios> <iosfwd> <iostream> <istream>

<iterator> <list> <locate> <limits>

<map> <memory> <new> <numeric>

<ostream> <queue> <streambuf> <string>

<set> <sstream> <stack> <stdexcept> <typeinfo> <utility> <valarray> <vector>

<cmath>

C ++ class Library

交通大學資訓工程學系 蔡文能

17

C++ classes for I/O

交通大學資訓工程學系 蔡文能

18

再談 C Language 程式庫

• 程式庫裡除了 sqrt (double); 之外 , 還有許多常用的函數 ( 函式 ), 有許多其實都很簡單

• printf, scanf, getchar, fopen, … 這些與 I/O 有關的函數被宣告在 stdio.h, 所以要在程式中

#include<stdio.h>用 < > 夾起來表示在系統某個目錄之下 , 例

如 /usr/include/• 所有 Library function 參看 K&R 附錄 B

交通大學資訓工程學系 蔡文能

19

Standard C Library<stdio.h> <math.h> <stdlib.h><string.h> <ctype.h> <time.h><assert.h> <float.h> <limits.h><stdarg.h> <stddef.h> <errno.h><locale.h> <signal.h> <setjmp.h>• open, read, write, close 等不是 standard C Lib

rary, 而是 system call• C Library 在 UNIX 手冊第三章 , System call

在 UNIX 手冊 第二章 ( 用 man 會看到 (2) )• 所有 Library function 參看 K&R 附錄 B

交通大學資訓工程學系 蔡文能

20

The C++ String Class

• The C-style strings (arrays of char) that you’ve been using are not the only way of managing character data.

• C++ allows you to work with a string class that eases many of the problems you’ve encountered with C-style strings.

• In particular, you don’t have to worry about managing memory for the string data.

交通大學資訓工程學系 蔡文能

21

C++ String Basics• The basic character template class is basic_string<>.• It has two specializations (generated using typedefs), strin

g and wstring.• string corresponds to the C-style string (I.e., const *char).• wstring is an extension for languages that use characters.• You can copy, assign, and compare strings just like you w

ould copy, assign, and compare primitive types (int, double)

string a = “Hello”; string b = string(a); string c = a; bool d = (a==b);

交通大學資訓工程學系 蔡文能

22

using the String types• In the header file <string>

– (Note, no .h)

• All such functions and other names are in the namespace std.

• The basic class name is a template class, basic_string<>.• String constructors

string( ) // emptystring(string s) // copy of sstring(string s, int start) // substringstring(string s, int start, int len) // substringstring(char* a) // C-stringstring(int cnt, char c) // one or more charsstring(char* beg, char* end) // [beg, end)

交通大學資訓工程學系 蔡文能

23

Accessing Individual Characters

• It’s almost like for a C-string.

string s = “Harry”;

s[0] is ‘H’

s[1] is ‘a’

s[5] is undefined!!!! – no ‘\0’ at the end

交通大學資訓工程學系 蔡文能

24

C++ string Operations• = is used to assign a value (char, C-string, or string) to a st

ring.• += is used to append a string, character, or C-string to a str

ing.• + is used to concatenate two strings or a string with somet

hing else• Boolean operations do a dictionary order comparison• << and >> are used for input and output. On input, leading

whitespace is skipped, and the input terminates with whitespace or end of file.

交通大學資訓工程學系 蔡文能

25

Other C++ string Operationsswap(a, b); // swap the guts of a with bs.append(s2); // append s2 to ss.c_str( ); // return a C-strings.push_back(c); // append a chars.erase(various); // erases substringss.insert(various); // inserts substringss.clear(); // removes all contentss.resize(cnt); // change the size of s to cnts.replace(various); // replaces characterss.size(); // how many characters?s.length(); // how many characters?s.max_size(); // maximum number of char?s.empty(); // is s empty?s.capacity(); // size without reallocations.reserve(cnt); // reserves memory

交通大學資訓工程學系 蔡文能

26

Using c++ string

string s = "Harry ";

s.data() // returns s as a data array, no '\0' .

s.c_str() // returns s as a C-string with '\0'int i = atoi(s.c_str()); // conversion

char *carray = new char[80];

s.copy(carray, 79); // copies up to 79 char

交通大學資訓工程學系 蔡文能

27

STL Algorithms - <algorithm>

• binary_search• sort• count: count(list.begin(),

list:end(), val, num);• equal: compares containers• for_each: applies ftn to each element• copy: copies container• reverse• min/max• Some in <numeric>

交通大學資訓工程學系 蔡文能

28

Vectors again•

Signature Description Capacity capacity() current capacity reserve(n) allocate space for n elements resize(n, t = T()) If n>size then add new n-size

elements; otherwise decrease the size Accessors reference operator[] const reference operator[]

unchecked access

reference at()throw(out_of_range) const reference at()throw(out-of_range)

checked access

Modifiers push_back() Insert a new element at the end; expand

vector if needed pop_back() remove the last element; undefined if vector

is empty

交通大學資訓工程學系 蔡文能

29

vector <int> v;

v.reserve (100); // allocate space for 100 integers

// capacity 100, size 0

int i;

while (cin >> i) // read from the standard input

v.push_back (i); // will expand v if needed

for (i = 0; i < v.size (); ++i)

cout << v[i];

try { // use checked access

cout << v.at (100); // may throw

} catch (std::out_of_range&) {

cout << "doesn't have 101 elements" << endl;

}

for (int i = 0; i < v.size () / 2; ++i)

v.pop_back (); // remove second half

vector <int> v1 (v); // copy to v1

v1.insert (v1.begin ()+1, 117); // insert after first

Using vector

交通大學資訓工程學系 蔡文能

30

Utilities: pair• a helper class template std::pair, used a lot by the standard library template <typename T1, typename T2> // simplified

struct pair {

T1 first;

T2 second;

pair () : first (T1()), second (T2()) {} // init

pair (const T1&, const T2&);

... // etc.

};

• provides a full range of comparison operations: ==, <, etc.

• a related helper function template to make pairs:

std:pair <int, double> w = std::make_pair (1, 1.2);

交通大學資訓工程學系 蔡文能

31

Sequences

• There are several kinds of sequences; choose vectors when

– there are random access operations,– most insertions and removals are at the end of the container

deques when– there are frequent insertions and deletions at either end, – there are random access operations

lists when– there are frequent insertions and deletions at positions other than at

the end – there are few random access operations– want to guarantee iterators are valid after modifications

交通大學資訓工程學系 蔡文能

32

Deques

• deques are similar to vectors

• deque iterators are random access• additionally two operations to insert/remove elements in front:

push_front () add new first element

pop_front () remove the first element

  

• deques do not have operations capacity () and reserve ()

交通大學資訓工程學系 蔡文能

33

Linked Lists

list <char> s; // empty list

s.insert (s.end (), 'a');

s.insert (s.end (), 'b') // s has (a, b)

list <char> s1; // empty list

// copy s to s1:

s1.insert (s1.end (), s.begin (), s.end ());

s.clear ();

cout << s1.front ();

s1.erase (s1.begin ()); // remove first element

交通大學資訓工程學系 蔡文能

34

Linked Lists (cont.)

Modifiers push_front(t) insert at back pop_front() delete from front Auxiliary (specialized for lists) sort() sort(cmp)

to sort the list to sort the list using the comparison cmp

reverse() to reverse a list remove(const T& value) remove_if(pred)

uses == to remove all elements equal to v uses the predicate pred

unique() unique(pred)

remove consecutive duplicates using == using the predicate pred

head.splice(i_head, head1) move the contents of head1 before iterator i_head, which must point to a position in head, and empty the list head1

head.splice(i_head, head1, i_head1) move the element pointed to by i_head1, which must point to a position in head1, before iterator i_head, which must point to a position in head

head.splice(i_head, head1, i_head1, j_head1)

move the range [i_head1, j_head1), which must be a valid range in head1, before iterator i_head, which must point to a position in head

head.merge(list& head1) merge two sorted lists into head, empty the list head1.

交通大學資訓工程學系 蔡文能

35

Iterators again

• an iterator provides access to objects stored in a container (points to an element); every iterator it has to support:

*it to access the element currently pointed to by the iterator

++it to move to the next element of the container

it = = it1 to compare two iterators for pointer equality

it ! = it1 to compare two iterators for pointer inequality

• every container type provides one or more iterators in a uniform way as standardized type names:

std::vector <string>::iterator

std::vector <string>::const_iterator

  begin () returns an iterator pointing to the first element

end () returns an iterator pointing past the end;

serves as a sentinel, i.e., end marker.

交通大學資訓工程學系 蔡文能

36

Iterators again (cont.)

• the iterator operations are sufficient for iterating over any Container: Container c; ...

Container::iterator it;

for (it = c.begin (); it != c.end (); ++it) {

.. *it .. it->op () ..

}

• a sequence of consecutive values in the container is determined by an iterator range, defined by two iterators, [first, last) 

• last is assumed reachable from first by using the ++ operator, and all iterators, including first but excluding last can be dereferenced

• two iterators can be compared for equality and inequality

交通大學資訓工程學系 蔡文能

37

Associative Containers • STL associative containers:

– represent sorted collections

– have keys, and are sorted on these keys

• A map is a mapping from keys to values:– it stores pairs (key, value)

– there may be at most one pair with the same key– e.g.: (123, "Bush") and (124, "Kerry")

• A multimap:– may have more than one pair with the same key– e.g., (123, "Bush") and (123, "Kerry")

交通大學資訓工程學系 蔡文能

38

// map: string to doubles map <string, double> salaries; // map: string to doubles sorted by greater <string> map <string, double, greater <string> > salaries1; • to access an element of a map, you can use an overloaded index operator op

erator [] (key):

salaries1 ["John"] = 10000; salaries1 ["Mary"] = 20000;

• operator [] can not be used for multimaps; for example multimap <string, string> mm; mm ["color"] = "blue"; // compile-time error• instead, you have to use insert (): mm.insert ("color", "blue"); mm.insert ("color", "green");

map usage

交通大學資訓工程學系 蔡文能

39

STL e.g.: using map

• Goal: store grades for group of students– ordered set of assignments

– maybe students with same name

• For each student, have grades– want fast access to each grade

– use vector of chars– typedef vector<int> Grades;

• First, create map of students:

• map<string, Grades> roster;

交通大學資訓工程學系 蔡文能

40

Using map: add a student to map• map represents a function: key maps to value• map, basically: set of ordered pairs

– pair<x,y> template• void Roster::addStudent(const string &name) {

//check if already exists

if (roster.find(name) != roster.end())return;

//check for roomif (roster.size() == MAX) waitList.push_back(name);else { Grades grades; roster.insert( pair<string,Grades>(name,grades));

}

交通大學資訓工程學系 蔡文能

41

Using map: drop a student• void Roster::dropStudent(String &name) {

if (roster.find(name) == roster.end())return;

roster.erase(name);if (waitList.size() > 0) {

string wait = waitList.pop_front();waitList.pop();Grades grades;roster.insert(

pair<string,Grades>(name,grades));}

}

交通大學資訓工程學系 蔡文能

42

Using map: set a grade• void Roster::setGrade(const &string name,

const int assign, const char grade) {map<string,Grades> stud =

roster.find(name);if (stud == roster.end()) {

cerr << “not found\n”;return;

}if (stud->second().size() <= assign) stud->second().resize(assign+1);

stud->second[assign] = grade;}

交通大學資訓工程學系 蔡文能

43

Associative Containers (cont.)

• set is a map for which the key and the value are identical - therefore it stores logically single elements rather than pairs

• multisets are sometimes called bags; they are like sets except there may be more than one occurrence of an element with the same key

• elements in associative containers are sorted by the value of a key

• associative containers use a binary predicate less <Key>, which compares two Key elements, using Key::operator<.

• the less predicate also determines the meaning of two keys being equivalent: two keys of an associative container are equivalent if neither is less than the other

交通大學資訓工程學系 蔡文能

46

Container Traits

Type name Description iterator type of an iterator (random access for vectors and deques, and

bidirectional for other containers) reverse_iterator type of an iterator to iterate in reverse order (random access for

vectors and deques, and bidirectional for other containers) const_iterator type of a constant iterator const_reverse_iterator type of a constant reverse iterator value_type type of container elements difference_type Signed integral type to represent a difference between two iterators size_type Unsigned integral type, used to represent non-negative values from

above reference Typically value_type&, i.e. reference to value_type const_reference as above but constant

交通大學資訓工程學系 蔡文能

47

Container Operations

Signature Description Access to iterators iterator begin() const iterator begin()

points to the first element

iterator end() const iterator end()

points to the past-the-end value

reverse_iterator rbegin() const iterator rbegin()

points to the first element of the reverse sequence

reverse_iterator rend() const iterator rend()

points to the past-the-end value of the reverse sequence

交通大學資訓工程學系 蔡文能

48

Constructors explicit Container() no-arg constructor to create empty

Container Container(const Container &) copy constructor ~Container() Destructor to empty Container and then

destroy it Container(iterator first, iterator last) create a Container by inserting the range

in another container defined by input iterators first and last

Auxiliary size functions size() number of elements empty() is empty max_size() the size of the largest possible Container swap(Container&, Container&) swap with another Container Comparisons between two Container's ==, !=, <, <=, >, >= Two containers are equal if the have the

same number of elements, and contain the same elements in the same order. These last four operators are based on a lexicographical comparison.

Assignments operator=(const Container&) copy existing Container

交通大學資訓工程學系 蔡文能

49

Signature Description Constructor explicit Sequence(size_type n, const T& v = T())

create n copies of v. If the type T does not have a no-arg constructor, then use explicit call to the constructor

Re-construction assign(first, last) copy the range defined by input iterators

first and last assign(size_type n, const T& v = T()) assign n copies of v Access reference front() const reference front()

first element. A reference type depends on the container; usually it is T&.

reference back() const reference back()

last element

Insertions and deletions iterator insert(iterator p, T t) insert a copy of t before the element pointed to

by p and return the iterator pointing to the inserted copy

void insert(iterator p, size_type n, T t)

insert n copies of t before p

void insert(iterator p, InputIterator i, InputIterator j)

insert copies of elements from the range [i,j) before p

iterator erase(iterator p) remove the element pointed to by p, return the iterator pointing to the next element if it exists; end() otherwise

iterator erase(iterator i, iterator j) remove the range [i,j), return the iterator pointing to the next element if it exists; end() otherwise

clear() remove all elements

交通大學資訓工程學系 蔡文能

50

value_type type of each element key_type the same as Key key_compare the same as Compare value_compare the same as key_compare for sets and multisets;

for maps, multimaps compares pair<Key, T> Constructors AssocContainer() Empty container, with Compare() AssocContainer(const Comparison& c) Container with a specialized comparison c AssocContainer(i, j) Container initially containing the range [i, j) AssocContainer(i, j, c) Container initially containing the range [i, j),

with a specialized comparison c Accessors iterator find(key) const_iterator find(key)

find the element with key and return an iterator pointing to this element

iterator lower_bound(key) const_iterator lower_bound(key)

Return the iterator to the first element with key

iterator upper_bound(key) const_iterator upper_bound(key)

Return the iterator to the element with key greater than key

pair<iterator, iterator> equal_range(key) pair<const_iterator,const_iterator> equal_range(key)

Return the pair of iterators; respectively pointing to the first and to the last element equal to key

size_t count(key) Return the number of elements with the key Insertions and deletions pair<iterator, bool> insert(t) insert element t; return a pair (iterator to the

element, success status); may fail for sets and maps void insert(i, j) insert the range [i, j) void erase(pos) erase element pointed to by pos size_t erase(key) erase element equal to key void erase(i, j) erase the range [i, j)

交通大學資訓工程學系 蔡文能

51

Thank You!Thank You!謝謝捧場

tsaiwn@csie.nctu.edu.tw

蔡文能

http://www.csie.nctu.edu.tw/~tsaiwn/cpp/