1 / 19

Why Use Namespaces?

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

joyce
Download Presentation

Why Use Namespaces?

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

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 • 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. #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’) … C++ string Class

  6. #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. Using C++ vs. C-style Strings

  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 • Can index positions directly 0 1 2 3 4 X X 0 1 2 3 4 X

  8. 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 Likeint * 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 Pointers and Arrays int arr [3] 0 1 2 0xefffdad0 0xefffdad0 int *p int *q

  9. 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] } 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 Pointer Arithmetic With Arrays int arr [3] 0 1 2 0xefffdad0 0xefffdad0 int *p int *q

  10. int main (int argc, char *argv[]) { // could declare char **argv for (int i = 0; i < argc; ++i) cout << argv[i] << endl; } 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’ Arrays of (and Pointers to) Pointers t e s t \0 h e l l o \0 0xefffa0d0 0xefffaad0 char * argv[] 2 int argc

  11. int main (int argc, char **argv) { int arr [3] = {0, 1, 2}; int * p = & arr[0]; int * q = p + 1; return 0; } 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 Rules for Pointer Arithmetic int arr [3] 0 1 2 0xefffdad0 0xefffdad0 int *p int *q

  12. 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? } 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 Watch out for Pointer Arithmetic Errors int arr [3] 0 1 2 0xefffdad0 0xefffdad0 int *p int *q

  13. 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 delete [] this->array_ptr; } 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 Arrays, Pointers, and Dynamic Allocation

  14. A Quick Look at Vectors • Goals • 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. #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 C++ Input/Output Stream Classes

  17. #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 C++ File I/O Stream Classes

  18. #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 Wrap string in a stream Push formatted values into stream Output formatted string to file C++ String Stream Classes

  19. #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; } 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? Using C++ String Stream Classes

More Related