Presentation is loading. Please wait.

Presentation is loading. Please wait.

Cstring Library Access with #include Or the C way, #include Provides two sets of functions for dealing with strings.

Similar presentations


Presentation on theme: "Cstring Library Access with #include Or the C way, #include Provides two sets of functions for dealing with strings."— Presentation transcript:

1 cstring Library Access with #include Or the C way, #include Provides two sets of functions for dealing with strings

2 C-Style String Functions The str* functions work with C-style strings A few examples –strcpy - copies strings –strcat - concatenates two strings –strcmp - compares two strings

3 strlen The most used of the str* functions Returns the length of a string It is declared as: size_t strlen(const char *str);

4 strcpy and strncpy Copies a string char* strcpy(char *dest, const char *src); char* strncpy*char *dest, const char *src, size_t n); If the length is unknown use strncpy

5 strcat and strncat Concatenates two strings char* strcat(char *dest, const char *src); char* strncat(char *dest, const char *src, size_t n); Again, use strncat if you don’t know the length

6 strcmp and strncmp Compares two strings int strcmp(const char *s1, const char *s2); int strncmp(const char *s1, const char *s2, size_t n); Use strncmp to compare just the first n characters Returns 0 (false) if the strings are the same!

7 #include int main() { const char *s1 = “The first string”; const char *s2 = “The second string”; if (std::strcmp(s1,s2) == 0) std::cout << “Strings the same\n”; else if (std::strcmp(s1,s2) < 0) std::cout << “s1 less than s2\n”; else std::cout << “s2 less than s1\n”; }

8 memory functions The mem* functions work with known length strings (arrays of chars) Instead of using a nul terminator A few examples: –memcpy - copies an array –memchr - find a char in an array –memcmp - compares two arrays

9 memcpy Copies a memory area void* memcpy(void *dest, const void *src, size_t n); Can be used to copy any memory area int array1[] = {1,2,3,4}; int array2[10]; std::memcpy(array1,array2,sizeof(int)*4);

10 strlen implementation size_t strlen(const char *str) { size_t count = 0; while (str[count] != ‘\0’) count++; return count; } size_t strlen(const char *str) { const char *s; for(s=str;*s;s++) /*nothing*/; return s - str; }

11 Structures A struct is an heterogeneous aggregate of types struct person { char name[80]; char phone[20]; unsigned short age; }; int main() { Person p; std::strcpy(p.name,”Johhny”); std::strcpy(p.phone,”99999999”); p.age = 30; }

12 Object Oriented C++ C++ is hybrid language - it allows Object Oriented Code, Procedural Code, and Generic Code We’ll look at the OO style of C++ OO in C++ is just classes and objects

13 Class Syntax A class is just like a struct. class Person { public : Person(string name); Person(const Person&); Person& operator=(const Person&); ~Person(); string get_name(); private: string name; };

14 Classes in C++ C++ is a reasonably low level OO object You have to do more to write a class than in a language like Java There are three basic functions you need to provide: –A way to create objects of the class –A way to copy objects of the class –A way to discard objects of the class

15 Constructors Objects are created from classes by constructors Constructors are defined like methods –they have no return type –they have the same name as the class Constructors are often used by the compiler to create objects implicitly

16 Default Constructor The default constructor is a constructor that takes no arguments If you do not write any constructors the compiler will create a default constructor –it will set members to their ‘default’ values Default constructors are used by the C++ libraries so it is wise to have one if possible Write it yourself - unless efficiency is vital

17 Copy Constructor The copy constructor is a constructor which is passed an object of the class If you don’t write a copy constructor the compiler will provide one –it will just copy the values of the members Used by the compiler and libraries so if possible one should be provided Write it yourself - unless efficiency is vital

18 Destructor Objects are discarded by the destructor It is defined just like a method –it has no return type –it has the name of the class prefixed with ~ The destructor should free any resources the object is using The compiler will provide a do nothing destructor if you don’t write one

19 Assignment Operator We’ll look at operator overloading later Most classes should have an assignment operator written Foo& operator=(const Foo&); It is called whenever an object is assigned to another (Foo a; Foo b; a = b;) Writing one is usually a mechanical process we’ll look at soon

20 A Linked List We’ll look at a simple linked list class to see how classes are written If you actually need a list you are much better off using the one provided by the STL

21 struct Node; //we’ll define this later class List { public: List(); // Default constructor List(const List&); // copy constructor List& operator=(const List&); //assign operator ~List(); // destructor int length(); void insert_at_front(int value); bool insert_after_current(int value); void delete_first(); void delete_after_current(); void set_current_to_front(); void advance_current(); int get_current_value(); bool check_current_in_list(); private: Node *head; Node *current; };

22 Default Constructor Should construct a default valued list We’ll make that an empty list List::List() { head = 0; current = 0; } Can also write it inside the class definition: List() : head(0), current(0) {}

23 Copy Constructor List::List(const List& o) { if (o.head == 0) { head = current = 0; } else { head = new Node(*(o.head)); current = 0; for (Node *c1=head,*c2=o.head; c2->next;c1=c1->next;c2=c2->next) { c1->next=new Node(*(c2->next)); if (o.current == c2) current = c1; } };

24 Destructor List::~List() { Node *current = head; while (current) { Node *remove = current; current = current->next; delete remove; }

25 Assignment Operator Normally an assignment operator does the following: –Check for equivalence –destroy the current object –copy the object across –return a reference to the object (to allow chaining)

26 List& List::operator=(const List &o) { if (this == &orig) return *this; Node *current = head; while (current) { Node *remove = current; current = current->next; delete remove; } if (o.head == 0) { head = current = 0; } else { head = new Node(*(o.head)); current = 0;

27 for (Node *c1=head,*c2=o.head; c2->next;c1=c1->next;c2=c2->next) { c1->next = new Node(*c2->next); if (o.current == c2) current = c1; } return *this; }

28 Member Functions Also known as methods Perform operations on the object Must always leave the object in a consistent state

29 length int List::length() { int len = 0; for(Node *c=head;c;c=c->next) count++; return count; }

30 insert_at_front void List::insert_at_front(int value){ Node *node = new Node; node->number = value; node->next = head; head = node; }

31 insert_after_current bool List::insert_after_current(int value) { if (current == 0) return false; Node *node = new Node; node->number = value; node->next = current->next; current->next = node; return true; }

32 delete_first void List::delete_first() { if (head==0) return; Node *remove = head; head = head->next; if (current == remove) current = 0; delete remove; }

33 delete_after_current void List::delete_after_current() { if (current==0 || current->next==0) return; Node *remove = current->next; current->next = current->next->next; delete remove; }

34 set_current_to_front void List::set_current_to_front() { current = head; }

35 advance_current void List::advance_current() { if (current == 0) return; current = current->next; }

36 get_current_value int List::get_current_value() { if (current == 0) return 0; return current->number; }

37 check_current_in_list bool List::check_current_in_list() { return current != 0; }

38 The Node Struct In writing the List class some assumptions about the Node struct were made Now we have to write the Node struct so that those assumptions are met

39 Node struct Node { int number; Node *next; Node() : number(0),next(0){}; Node(const Node &o) : number(o.number),next(0) {}; };

40 Memory Management C++ does not have a garbage collector The programmer much manually manage memory Memory needs to be allocated when needed It must be deallocated when not needed Not managing memory correctly is a major source of bugs in C++ code

41 C++ Memory Model Memory can be allocated from the stack or the heap Variables are allocated on the stack That memory is automatically deallocated Objects can be created on the heap with new That memory can be deallocated with delete

42 Allocating Memory new creates an object on the heap The appropriate constructor is called new[] creates an array on the heap The default constructor is called for each element of the array int *i_array = new int[100]; string *a_string = new string(“fred”);

43 Deallocating Memory delete calls an objects destructor The memory used is then released delete[] calls the destructor of each element of an array The memory used is then released Every object created with new must be deleted Every array created with new[] must be delete[]ed

44 More of the story new and delete don’t just manage memory They also call constructors and destructors Other resources are also allocated and released File handles, network connections, and file locks must be released along with memory

45 More about main() main can be passed arguments int main(int argc, char **argv); int main(int argc, char *argv[]); This allows a program to access the command line arguments So a text editor can know what file to open

46 main() example #include int main(int argc, char **argv) { for(int i=0;i<argc;i++) std::cout << argv[i] << std::endl; }

47 Functions You can have many functions with the same name They just need different arguments This is very useful, but can get confusing

48 Example Functions void foo(int val) { std::cout << “int\n”; } void foo(char c) { std::cout << “char\n”; } int main() { int I; char c; long l; foo( i ); foo( c ); foo( l ); }

49 Function Resolution C++ will often call functions implicitly in order to compile your code This is very useful since it means you can often write simpler code It is also dangerous since sometimes you don’t get what you meant It can also make code hard to understand

50 An Example class Complex { public:Complex(int re=0, int im=0); }; int distance( const Complex &a, const Complex &b); int main() { distance(1,2); }

51 Classes as Types C++ allows you to create classes which act like built-in types Operator overloading is the tool for this It can be used for both good and evil Do not overuse it Do use it for output via ostream objects

52 Output via operator overloading class List { friend ostream& operator<<(ostream &os, const List &list); }; ostream& operator<<(ostream &os, const List &list) { for (Node *c=list.head;c;c=c->next) os number << ‘ ‘; }

53 Inheritance Inheritance in C++ is a little complicated The default behaviour is often not what you want The default behaviour is usually the most efficient behaviour not the most useful

54 class Warning_Indicator { public: void turn_on() { std::cout << “Indicator on\n”; } }; class Warning_Buzzer { public: void turn_on() { std::cout << “Buzzer on\n”; } }; void alarm(Warning_Indicator wi) { wi.turn_on(); } int main() { Warning_Buzzer buzzer; alarm(buzzer); }

55 A problem What does alarm(buzzer) do? It is known as slicing - it is usually an error The compiler creates a Warning_Indicator object via it’s Copy Constructor from the Warning_Buzzer The fix is to pass a reference instead of an Object: void alarm(const Warning_Indicator &wi);

56 More Problems The program will still output “Indicator on” Now the problem is due to binding C++ defaults to compile time binding wi.turn_on() becomes a call to the turn_on member function of Warning_Indicator Even when a Warning_Buzzer is used, the Warning_Indicator member is called

57 The Solution The solution is to use run time binding In C++ that is done with the keyword virtual class Warning_Indicator { public: virtual void turn_on(); };

58 Virtual A virtual function takes more time to call An object with virtual functions takes up more memory The actual function to call is looked up at run time Looking up takes time Storing the function in the object takes space

59 Accessibility and Inheritance private members can only be accessed by the class itself (and friends) protected members can also be accessed by classes that inherit from the class That is almost always a bad thing It prevents implementation changes later - the main benefit or OO programming

60 class Base { public : i; protected : j; private : k; }; class Child : public Base { public: void test() { i = 1; // legal j = 1; // illegal k = 1; // illegal } };

61 Constructors and Inheritance If a base class has a constructor then it must be called By default the default constructor is called If you want to call a different constuctor then you need to use an initialiser

62 class Person { public: Person(const string& name); }; class Student : public Person { public: Student(const string& name, const string& sid) : Person(name) { } };

63 Destructors and Inheritance Destructors are automatically called However, if a class is to inherited from its destructor must be declared virtual Not doing so can result in resource leaks Person *p = new Student(”Sam”,”9222194”); delete p;

64 Abstract Classes Seperating interface and implementation is often wise In C++ you can do this with abstract classes An abstract class is one with at least one pure virtual function

65 An Abstract Example class Security_Device { public: virtual turn_on() = 0; virtual turn_off() = 0; virtual is_on() = 0; };

66 Multiple Inheritance C++ supports multiple inheritance Sometimes useful, but leads to problems Problems occur with diamond inheritance trees Multiple inheritance will not be needed for this course

67 Non-public Inheritance class B : private A –public and protected members of A are treated as private –this applies to users of B, but not B itself class B : protected A –public members of A are treated as protected This allows implementation inheritance without interface inheritance


Download ppt "Cstring Library Access with #include Or the C way, #include Provides two sets of functions for dealing with strings."

Similar presentations


Ads by Google