Class Definitions
Object-Oriented C++ Basics
Classes vs. Structs
- Classes are an extension to structs and the two are nearly identical
- Only difference between C++'s structs and classes:
- class members are private by default
- struct members are public by default
- Standard coding convention:
- use stucts for "dumb data" with no methods
- use classes for anything else
Organization of program
- Header files contain class declarations (interface)
- Program files contain class (function) definitions (implementation)
-
main()function still needed for execution starting point
Object oriented (OO) programming language features
- Generally objects = fields + methods but C++ terminology is "objects = data members + member functions"
- public interface, private implementation
- Multiple polymorphism forms in OO
- object polmorphism via subclassing
- templates/generics
- function & operator overloading
- inheritance
- abstract base classes
OO Abstraction & modelling
- data members (properties) - can be of different types or classes
- function members (behaviors)
-- can be defined there or elsewhere
-- assume full access to data members
Class Components
Information hiding of class members
- public parts - anybody can access
- private parts - access by same class members only
- declared via
public:andprivate:in .h file
Member functions
- Defined with
MyClass::myfunc(args) { ... code ... } - Can be implemented independently of class declaration, interspersed with other non-class functions
Syntax for class interface (in *.h file)
class classname {
// complete member list
}; // semicolon is very important
Constructors and destructors
Constructors are used to initialize objects and each class can have many:
- Default constructor - no parameters; primitive fields are not initialized, object fields are initialized with their default constructors
- Conversion constructor - takes only one parameter, compiler then uses for type conversions from values of that parameter type to the class type
- Copy constructor - has parameter of the class type; default version is shallow copy of data fields (similar to default assignment operator)
- Alternate constructors - have any combination of parameters different from those above
C++ automatically provides a default constructor and a (shallow) copy constructor for every class if you don’t explicitly create any constructors. However, if you define any constructor, default ones are not created automatically for the class.
Copy constructors are invoked
- explicitly when initializing an object in declaration
- implicitly when passing an object call by value
- implicitly when returning an object by value
Initializer lists for data members
- Special syntax for initializing fields
-
Point :: Point () : x(0), y(0) { }initializes x and y to 0 - initialization happens in the order of declaration, not list order above (doesn't usually matter though)
- All data members initialized even if not listed explicitly
- Body of constructor can be used to change or do more initializations
- May need to do this for members of other class types, particularly if they don't have default constructors
Constructors using default values
- Can leave off certain arguments if they have a default value listed
- Defaults only declared in the header, not in the definition!
- Function implementation is as before
- Must be defaulted from right to left when used, as in
Point (int xy=0, int yv=0)- calling options are only to leave out right-most params
Point p1(3, 4); // use both
Point p2(3); // use x; y defaults to 0
Point p3; // both default to 0
Destructors
- Named by prepending
~to the class name -MyClass::~MyClass() { ... } - Destructor code invoked when object lifetime ends
- Destruction is shallow (no destruction of objects referenced) unless code
...does more - Locally declared objects are destroyed at function return - their destructors are called right before their memory is freed
- C++ provides a destructor for your class if you don't explicitly write one.
Other C++ class definition features
Inline function definitions
- Code is not a function call, its inlined by compiler for speed
- Since its like a macro its OK to put this code in
.hfile - Need semicolon:
int Myclass::getX() { return x ; } ;
Instance variables (data members)
- They are like struct fields
- They are not automatically references, as in Java - use
&varto make a reference - The class constructor should set their initial value
The this pointer to current object
- Can use
this->datamemberinstead of justdatamemberfor clarification - Can use
*thisas name for current object - Like
thisin Java, you don't often need to use it
Constant member functions
- Use
constat end of function header to say that it can't modify any data members of itself (the current object) - Must use
constin both prototype and implementation header - Can be applied to
constand non-constqualified objects - A non-
constfunction cannot be applied toconstqualified object - violates spirit ofconst
static class members
- Class-wide info, shared by all objects
- Similar to
staticin Java classes - Declare data:
static int sharedint; - Can be accessed through class object or globally via
classname::(if public) - Declare functions: static int changeshared (int);
- Function can only be static if it only accesses static data
- No
thisfor static members
Class composition - objects in classes
- Class data members are constructed in order of declaration and before the class constructor is executed
- May need to initialize member objects with constructor initializer list if they don't have default constructors
Friend classes
- Declare another class B to be a friend of the current class A
- Friend class B can directly access all members (private and public) of class A
- Friendship is one-way (anti-symmetric) unless explicitly declared both ways
- Friendship is not transitive
- eg for Rectangles/Points:
// in Point.h
private x, y;
friend class Rectangle;
// in Rectangle.cpp
Rectangle :: Rectangle (int x1, int y1, int x2, int y2)
{
p1.x = x1; p1.y = y1; // allowed due to friend declaration above
p2.x = x2; p2.y = y2;
}
Remember: Friends violate the principle of data encapsulation - use as little as possible!!
Misc points about classes
Operators = and == on objects:
-
=assignment operator - memberwise assignment is provided by default (not deep copy) -
==equality operator is not provided automatically for your class objects, you have to define it explicitly (see Overloading)
Explicit constructor call creates constant temporary object:
- Syntax:
Classname(params) - eg:
Rational r2 = 3 + Rational(3,4);- 3/4 never put in variable so temporary object
More on storage, lifetimes, scope and references
If a function returns non-reference value, it is a temporary object. If a function returns reference value, it is a name for something else that must have a lifetime outside the function. This list shows what could and could not be returned through a reference return type, with an example below.
- global variables
- static variables
- class members w/suitable lifetime
- reference function parameters
- NOT a local [automatic] function variable
- NOT a passed by value function parameter
Example:
#include <iostream>
int globalint;
int & mult(int & x, int y)
{
int z;
static int s;
z = x * y;
s = z;
x = z;
y = z;
globalint = z;
// return z; // bad, would be a reference to (popped) stack element
// return y; // bad, same reason
// return x * y; // bad
return x; // ok, was a reference argument so not popped
return s; // ok, static so not on stack
return globalint; // ok, also not on stack
}
int main ()
{
int m, x = 3, y = 5;
m = mult(x, y);
globalint = 0;
std::cout << "m=" << m << " gi=" << globalint << std::endl;
}
Could have function/method return something by reference but constant so that it can’t be changed - particularly useful for classes:
class Point {
public:
void display() const;
void setX(int);
...
};
class Rectangle {
public:
const Point & getTL() { return topleft; };
private:
Point topleft;
};
// in main
Rectangle r1(1,1,4,4);
Point p1;
r1.getTL().setX(3); // not allowed
p1 = r1.getTL(); // ok
r1.getTl().display(); // ok because display is const