Presentation is loading. Please wait.

Presentation is loading. Please wait.

Why Use Namespaces? Classes encapsulate behavior (methods) and state (member data) behind an interface Structs are similar, but with state accessible Classes.

Similar presentations


Presentation on theme: "Why Use Namespaces? Classes encapsulate behavior (methods) and state (member data) behind an interface Structs are similar, but with state accessible Classes."— Presentation transcript:

1 Why Use Namespaces? Classes encapsulate behavior (methods) and state (member data) behind an interface Structs are similar, but with state accessible Classes and structs are used to specify self-contained, cohesive abstractions Can say what class/struct does in one sentence What if we want to describe more loosely related collections of state and behavior? Could use a class or struct But that dilutes their design intent

2 Namespaces C++ offers an appropriate scoping mechanism for loosely related aggregates: Namespaces Good for large function collections E.g., a set of related algorithms and function objects Good for general purpose collections E.g., program utilities, performance statistics, etc. Declarative region Where a variable/function can be declared Potential scope Where a variable/function can be used From where declared to end of declarative region

3 Namespace Properties Declared/(re)opened with namespace keyword
namespace Foo {int baz_;} namespace Foo {int fxn() {return baz_;}} Access members using scoping operator :: std::cout << “hello world!” << std::endl; Everything not declared in another namespace is in the global (program-wide) namespace Can nest namespace declarations namespace Foo {namespace Err {…}}

4 Using Namespaces Can also declare unnamed namespaces
The using keyword makes elements visible Only applies to the current scope Can add entire namespace to current scope using namespace std; cout << “hello, world!” << endl; Can introduce elements selectively using std::cout; cout << “hello, world!” << std::endl; Can also declare unnamed namespaces Elements are visible after the declaration namespace {int i_; // i_ is now visible }

5 C++ string Class #include <iostream> #include <string>
using namespace std; int main (int, char*[]) { string s; // empty s = “”; // empty s = “hello”; s += “, ”; s = s + “world!”; cout << s << endl; // prints: hello, world! return 0; } <string> header file Various constructors Assignment operator Overloaded operators += + < >= == [] The last one is really useful: indexes string if (s[0] == ‘h’) …

6 Using C++ vs. C-style Strings
#include <string> #include <iostream> using namespace std; int main (int, char*[]) { char * w = “world”; string sw = “world”; char * h = “hello, ”; string sh = “hello, ”; cout << (h < w) << endl; // 0: why? cout << (sh < sw) << endl; // 1:why? h += w; // illegal: why? sh += sw; cout << h << endl; cout << sh << endl; return 0; } C-style strings are contiguous arrays of char Often accessed through pointers to char (char *) C++ string class (template) provides a rich set of overloaded operators Often C++ strings do “what you would expect” as a programmer Often C-style strings do “what you would expect” as a machine designer Suggestion: use C++ style strings any time you need to change, concatenate, etc.

7 Storing Other Data Types Besides char
There are many options to store non-char data in C++ Differ in complexity, ease of use Native C-style arrays Can not add or remove positions Can index positions directly Not necessarily zero-terminated (why?) STL list container (bi-linked list) Add/remove positions on either end Cannot index positions directly STL vector container (“back stack”) Can add/remove positions at the back 1 2 3 4 X X 1 2 3 4 X

8 Pointers and Arrays int main (int argc, char **argv) { int arr [3] = {0, 1, 2}; int * p = & arr[0]; int * q = arr; // p, q, arr point to same place } An array holds a contiguous sequence of memory locations Can refer to locations using either array index or pointer notation E.g., *arr vs. arr[0] E.g., *(arr+1) vs. arr[1] Array variable essentially behaves like a const pointer Like int * const arr; Can’t change where it points Can change locations unless declared array-of-const E.g., const int arr[3]; Can initialize other pointers to the start of the array Using array name, or using address of 0th element int arr [3] 1 2 0xefffdad0 0xefffdad0 int *p int *q

9 Pointer Arithmetic With Arrays
Adding or subtracting int n moves a pointer by n of the type to which it points I.e., by n array positions E.g., value in q is increased by sizeof(int) by ++q Can move either direction E.g., --q, ++p Can jump to a location E.g., p+=2, q-=1 Remember that C++ (only) guarantees that sizeof(char)==1 But compiler figures out other sizes for you int main (int argc, char **argv) { int arr [3] = {0, 1, 2}; int * p = & arr[0]; int * q = arr; // p, q now point to same place ++q; // now q points to arr[1] } int arr [3] 1 2 0xefffdad0 0xefffdad4 int *p int *q

10 Arrays of (and Pointers to) Pointers
Can have pointers to pointers Can also have an array of pointers (like a const pointer to a pointer type) E.g., argv parameter in main Array of pointers to character strings Could also declare as a pointer to the first pointer Notice array dimension is not specified Instead a special argument (argc) holds array size By convention, character strings are zero terminated Special char is ‘\0’ not ‘0’ int main (int argc, char *argv[]) { // could declare char **argv for (int i = 0; i < argc; ++i) cout << argv[i] << endl; } t e s t \0 h e l l o \0 0xefffa0d0 0xefffaad0 char * argv[] 2 int argc

11 Rules for Pointer Arithmetic
You can subtract (but not add, multiply, etc.) pointers Gives an integer with the distance between them You can add/subtract an integer to/from a pointer E.g., p+(q-p)/2 is allowed but (p+q)/2 gives an error Note relationship between array and pointer arithmetic Given pointer p and integer n, the expressions p[n] and *(p+n) are both allowed and mean the same thing int main (int argc, char **argv) { int arr [3] = {0, 1, 2}; int * p = & arr[0]; int * q = p + 1; return 0; } int arr [3] 1 2 0xefffdad0 0xefffdad4 int *p int *q

12 Watch out for Pointer Arithmetic Errors
Dereferencing a 0 pointer will crash your program Accessing memory location outside your program can Crash your program Let you read arbitrary values Let you modify that location Last two: hardest to debug Watch out for Uninitialized pointers Failing to check pointer for 0 Adding or subtracting an uninitialized variable to a pointer Errors in loop initialization, termination, or increment int main (int argc, char **argv) { int arr [3] = {0, 1, 2}; int * p = & arr[0]; int * q = arr; // p, q now point to same place int n; q+=n; // now where does q point? } int arr [3] 1 2 0xefffdad0 0xefffdad4 int *p int *q

13 Arrays, Pointers, and Dynamic Allocation
We’ve talked mainly about stack variables so far Arrays, like individual objects, can be allocated (new) and de-allocated (delete) dynamically more details in later lectures Arrays have a particular syntax with [ ] in the new and delete calls Ensures constructors and destructors of elements are called automatically Don’t leak, destroy safely Requires careful attention to details of memory management More about this in next lectures Foo * baz (){ // note the array form of new int * const a = new int [3]; a[0] = 0; a[1] = 1; a[2] = 2; Foo *f = new Foo; f->reset(a); return f; } void Foo::reset(int * array) { // ctor must initialize to 0 delete [] this->array_ptr; this->array_ptr = array; void Foo::~Foo() { // note the array form of delete

14 A Quick Look at Vectors Goals Vectors: nicer than arrays
Give you a good basic data structure to use for now Cover its correct usage Start understanding why Vectors: nicer than arrays Less to manage/remember Harder to get things wrong (but still need to be careful) Example to the left prints v[0] is 1 v[1] is 2 v[2] is 4 #include <iostream> #include <vector> using namespace std; int main (int, char *[]) { vector<int> v; // This would be asking for trouble.... // v[0] = 1; v[1] = 2; v[2] = 4; // ... but this works fine... v.push_back (1); v.push_back (2); v.push_back (4); // ... and now this is ok ... for (size_t s = 0; s < v.size(); ++s) { cout << "v[" << s << "] is " << v[s] << endl; } return 0;

15 Why to Use STL Vectors Instead of C++ Arrays
#include <iostream> #include <vector> using namespace std; int main (int, char *[]) { vector<int> v; // This would be asking for trouble.... // v[0] = 1; v[1] = 2; v[2] = 4; // ... but this works fine... v.push_back (1); v.push_back (2); v.push_back (4); // ... and now this is ok ... for (size_t s = 0; s < v.size(); ++s) { cout << "v[" << s << "] is " << v[s] << endl; } return 0; Vectors do a lot of (often tricky) memory management for you Use new[] and delete[] internally Resize, don’t leak memory Easier to pass to functions E.g., can tell you their size Don’t have to pass a separate size variable Don’t need a pointer by reference in order to resize Still have to pay some attention E.g., push_back allocates more memory but operator [] won’t E.g., vectors copy and take ownership of objects they contain

16 C++ Input/Output Stream Classes
#include <iostream> using namespace std; int main (int, char*[]) { int i; // cout == std ostream cout << “how many?” << endl; // cin == std istream cin >> i; cout << “You said ” << i << “.” << endl; return 0; } <iostream> header file Use istream for input Use ostream for output Overloaded operators << ostream insertion operator >> istream extraction operator Other methods ostream: write, put istream: get, eof, good, clear Stream manipulators ostream: flush, endl, setwidth, setprecision, hex, boolalpha

17 C++ File I/O Stream Classes
#include <fstream> using namespace std; int main () { ifstream ifs; ifs.open (“in.txt”); ofstream ofs (“out.txt”); if (ifs.is_open () && ofs.is_open ()) int i; ifs >> i; ofs << i; } ifs.close (); ofs.close (); return 0; <fstream> header file Use ifstream for input Use ofstream for output Other methods open, is_open, close getline seekg, seekp File modes in, out, ate, app, trunc, binary

18 C++ String Stream Classes
#include <iostream> #include <fstream> #include <sstream> using namespace std; int main (int, char*[]) { ifstream ifs (“in.txt”); if (ifs.is_open ()) string line_1, word_1; getline (ifs, line_1); istringstream iss (line_1); iss >> word_1; cout << word_1 << endl; } return 0; <sstream> header file Use istringstream for input Use ostringstream for output Useful for scanning input Get a line from file into string Wrap string in a stream Pull words off the stream Useful for formatting output Use string as format buffer Push formatted values into stream Output formatted string to file

19 Using C++ String Stream Classes
Program gets arguments as C-style strings But let’s say we wanted to input floating point values from the command line Formatting is tedious and error-prone in C-style strings (sprintf etc.) iostream formatting is friendly Can we get there from here? #include <string> #include <cstring> #include <sstream> using namespace std; int main (int argc, char *argv[]) { if (argc < 3) return 1; ostringstream argsout; argsout << argv[1] << “ ” << argv[2]; istringstream argsin (argsout.str()); float f,g; argsin >> f; argsin >> g; cout << f << “ / ” << g << “ is ” << f/g << endl; return 0; }


Download ppt "Why Use Namespaces? Classes encapsulate behavior (methods) and state (member data) behind an interface Structs are similar, but with state accessible Classes."

Similar presentations


Ads by Google