Академический Документы
Профессиональный Документы
Культура Документы
We have viewed data and functions as being separate for the most part
Date (int d, int m, int y); // another constructor virtual ~Date (); // (virtual) destructor Date & operator= (const Date &); // assignment operator int d () const; int m () const; int y () const; // accessors void d (int); void m (int); void y (int); // mutators string yyyymmdd () const; // generate a formatted string
private: // member variables, visible only within functions above int d_; int m_; int y_; };
Access Control
Declaring access control scopes within a class
private: visible only within the class protected: also visible within derived classes (more later) public: visible everywhere Access control in a class is private by default
but, its better style to label access control explicitly
Versus classes, which are expected to have both data and some form of non-trivial behavior
E.g., if reference counting, etc. probably want to use a class
Friends
Offer a limited way to open up class encapsulation C++ allows a class to declare its friends
Give access to specific classes or functions
A controlled violation of encapsulation
Friends Example
class Foo { friend ostream &operator<<(ostream &out, const Foo &f); public: Class declares operator<< as a friend Foo(int) {} Notice operator<< is not a member of class Foo ~Foo() {} Gives it access to member variable baz private: int baz; };
ostream &operator<<(ostream &out, const Foo &f) { out << f.baz; return out; }
Constructors
class Date { public: Date (); Date (const Date &); Date (int d, int m, int y); // ... private: int d_, m_, y_; };
Date::Date () : d_(0), m_(0), y_(0) {}
A constructor has the same name as its class Establishes invariants for the class instances (objects)
Properties that always hold Like, no memory leaks
Set up invariants before the constructor body is run Date::Date (int d, int m, int y) Help avoid/fix constructor failure : d_(d), m_(m), y_(y) More on this topic later constructor body {} CSE 332: C++ classes
Destructors
class Calendar { public: Calendar (size_t s); virtual ~Calendar (); // etc ... private: size_t size_; Date * dates_; };
Calendar::Calendar (size_t s) : size_(s), dates_(0) { if (size_ > 0) { dates_ = new Date[size_]; } } Calendar::~Calendar () { delete [] dates_; }
Destructor is implicitly called when an object is destroyed Can make destructor private, call it from a public member function
e.g., a public one called destroy() Only allows heap allocation
Watch out for what can happen if an exception can leave a constructor
No guarantee destructor will be called in that case Need to avoid having a partially initialized (zombie) object Two kinds of approaches can be used (1st is often preferred)
Keep the object in a safe default state at all times so it doesnt matter Use try/catch within the constructor and reset object to safe state
Self Reference
All non-static member functions are invoked with an implicit pointer to object on which function was called
non-const member function: X * const this const member function: const X * const this
Use of the this pointer is also implied when member variables are accessed from within a member function If you are passed a pointer or reference as a parameter
May want (or need) to compare against this (see assignment, next)
Use this to return a reference to the object on which a member function (or operator) was called
e.g., cout
<< i << j;
or i = j = k;
Date & Date::add_year(int n) { if () {} // check for leap year _y += n; // this-> implied return *this; } // allows Date d; d.add_year(3).add_year(5);
Assignment Operator
class Date { public: Date & operator= (const Date &); // ... private: int d_, m_, y_; };
Date & Date::operator= (const Date &d){ d_ = d.d_; m_ = d.m_; y_ = d.y_; return *this; } int main (int, char *[]) { Date a; // default constructor Date b(a); // copy constructor Date c = b; // copy constructor a = c; // assignment operator }
May want to give limited access to some of the private class members Accessors (a.k.a. get methods)
Member functions to read values Return by value or by const reference Functions often const (see next slide)
Const member functions can be called on both const and non-const objects
Cant call non-const member functions on const objects
From inside class methods, can either just use the variable or function name or use the scope operator version thats used outside the class
A Quick Review
What four member functions/operators does the compiler automatically define for you? When/how are they invoked? What if you dont want one of them to be used?