Sie sind auf Seite 1von 13

From Procedural to Object-oriented Programming

Procedural programming
Functions have been the main focus so far
Function parameters and return values
Exceptions and how the call stack behaves

We have viewed data and functions as being


separate abstractions, for the most part

Object-oriented (a.k.a. OO) programming


Allows us to package data and functions together
Makes data more interesting (adds behavior)
Makes functions more focused (restricts data scope)

This module will start to look at OO programing


Classes/structs, member operators/functions/variables
Well cover inheritance, polymorphism, substitution later
CSE 332: C++ Classes

From C++ Functions to C++ Structs/Classes


C++ functions encapsulate behavior
Data used/modified by a function must be passed in via parameters
Data produced by a function must be passed out via return type

Classes (and structs) encapsulate related data and behavior


Member variables maintain each objects state
Member functions (methods) and operators have direct access to
member variables of the object on which they are called
Class members are private by default, struct members public by default

When to use a struct


Use a struct for things that are mostly about the data
Add constructors and operators to work with STL containers/algorithms

When to use a class


Use a class for things where the behavior is the most important part
Prefer classes when dealing with encapsulation/polymorphism (later)

CSE 332: C++ Classes

Using Structs and Operators with STL Containers


#include <vector> // standard template library
#include <iostream>
using namespace std;
#include point2d.h // using user-defined code
// main function definition
int main (int, char *[]) {
vector<Point2D> v; // must give a type here
v.push_back(Point2D(2,3));
v.push_back(Point2D(1,4));
for (size_t s = 0; s < v.size(); ++s) {
cout << v[s] << endl; // needs Point2D <<
}
return 0;
}
CSE 332: C++ Classes

Using Structs and Operators with STL Algorithms


// same as before, and add algorithm library
#include <vector>
#include <algorithm>
using namespace std;
#include point2d.h
int main (int, char *[]) {
vector<Point2D> v;
v.push_back(Point2D(2,3));
v.push_back(Point2D(1,4));
// reorders the points in the vector
// note that you dont give a type here!
sort (v.begin(), v.end()); // needs Point2D <
return 0;
}
CSE 332: C++ Classes

Declaring and Defining C++ Structs/Classes


// struct declaration (in point2d.h)
struct Point2D {
also may need ==
Point2D (int x, int y);
bool operator< (const Point2D &) const;
int x_;
promises not to
int y_;
modify object on
};
also may need << (outside struct)
// method definitions (in point2d.cpp)
Point2D::Point2D (int x, int y)
: x_(x), y_(y) {}

which its called

base class/struct and


member initialization list

bool
scoping operator
Point2D::operator< (const Point2D & p2d) const
{
return (x_ < p2d.x_) ||
((x_ == p2d.x_) && (y_ < p2d.y_));
}
CSE 332: C++ Classes

Structure of a Simple C++ Class Declaration


class Date {
public: // member functions, visible outside the class

operators
can be
member
functions
as well

The compiler
defines these
4 if you dont*

Date (); // default constructor


Date (const Date &); // copy constructor
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_;
*Compiler omits default
int y_;
};

Dont forget semicolon at the


end of the class declaration

CSE 332: C++ Classes

constructor if any
constructor is declared

Constructors
class Date {

public:
Date ();

Date (const Date &);


Date (int d, int m, int y);
// ...
private:
int d_, m_, y_;

};
// default constructor base class /
Date::Date ()
member
: d_(0), m_(0), y_(0)
initialization
{}
list
// copy constructor
Date::Date (const Date &d)
: d_(d.d_), m_(d.m_), y_(d.y_)
{}
// another constructor
Date::Date (int d, int m, int y)
: d_(d), m_(m), y_(y)
{}
constructor body

CSE 332: C++ Classes

A constructor has the same


name as its class
Establishes invariants for the
class instances (objects)
Properties that always hold
Like, no memory leaks

Passed parameters are used in


the base class /member
initialization list
You must initialize const and
reference members there
Members are constructed in the
order they were declared
List should follow that order

Set up invariants before the


constructor body is run
Help avoid/fix constructor failure
More on this topic later

A Bit More About Default Constructors


Default constructor takes no arguments
Compiler synthesizes one if no constructors are provided
Does default construction of all class members (a.k.a member-wise)

If you write a default constructor


Can initialize default values via base/member list
Must do this for const and reference members

Default construction of built-in types


Default construction does nothing (leaves uninitialized)
Its an error (as of C++11) to read an uninitialized variable

CSE 332: C++ Classes

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

A struct is the same as a class, except


Access control for a struct is public by default
Usually used for things that are mostly data
E.g., if initialization and deep copy only, may suggest using a struct

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
CSE 332: C++ Classes

Issues with Encapsulation in C++


Sometimes two classes are closely tied

For example, a container and its iterators


One needs direct access to the others internal details
But other classes shouldnt have such direct access
Can put their declarations in the same header file
Can put their definitions in the same source file

Poses interesting design forces


How should iterator access members of container?
Making container members public violates encapsulation
Any class, not just iterator could modify them

Make protected, derive iterator from container?


Could work: inheritance for implementation
But, may prove awkward if lots of classes/dependences are involved

Could have lots of fine-grain accessors and mutators


Functions to get and set value of each member variable
But may reduce encapsulation, clutter the interface for other classes
CSE 332: C++ Classes

Friend Declarations
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

Keyword friend is used in class declaration

Properties of the friend relation in C++


Friendship gives complete access
Friend methods/functions behave like class members
public, protected, private scopes are all accessible by friends

Friendship is asymmetric and voluntary


A class gets to say what friends it has (giving permission to them)
But one cannot force friendship on a class from outside it

Friendship is not inherited


Specific friend relationships must be declared by each class
Your parents friends are not necessarily your friends

CSE 332: C++ Classes

Friends Example
// in Foo.h
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:
Can now print Foo like a built-in type
int baz;
Foo foo;
};
cout << foo << endl;
ostream &operator<<(ostream &out, const Foo &f);
// in Foo.cpp
ostream &operator<<(ostream &out, const Foo &f) {
out << f.baz; // f.baz is private so need to be friended
return out;
}

CSE 332: C++ Classes

Operators let a Struct/Class Work with Entire STL


#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#include "point2d.h
int main (int, char *[]) {
vector<Point2D> v;
v.push_back(Point2D(2,3)); v.push_back(Point2D(1,4));
v.push_back(Point2D(8,7)); v.push_back(Point2D(5,9));
vector<Point2D> t(v); // can copy construct a vector
do { // next_permutation needs Point2D <
next_permutation(v.begin(), v.end());
for (size_t s = 0; s < v.size(); ++s) {
cout << v[s] << " "; // needs Point2D <<
}
cout << endl;
} while (v != t); // needs Point2D == for vector<T> !=
return 0;
}

CSE 332: C++ Classes

Das könnte Ihnen auch gefallen