The University of Iowa
The College of Liberal Arts and Sciences
Department of Computer Science

Programming Languages and Tools:

CS:3210:0001

Lecture/Lab #12

Programming with C++

Member access control, friends, inheritance

Warm up

  • What's the difference between enum and enum class?

  • How do you define a class member function outside of the class definition itself?

struct point
{
    // how to define this outside of the class?
    void move_by( point const& offset )
    {
    	this->x += offset.x;
    	this->y += offset.y;
    }

    int x = 0;
    int y = 0;
};

Exercise 1

Define a stream output operator for an enumeration type that prints out a name of the corresponding enum value

  • Open the exercise template

  • Write your code, press Run to test

  • When you're done, grab your Repl's link and send it as a direct message to me (agurtovoy)

  • Click on the corresponding option in the "Lab12 exercises" poll in #general

Member access control

  • Public members define the interface of the type and are accessible to all parts of the program.
  • Private members are considered to be implementation details and are accessible to the member functions of the type only.
  • A class may contain zero or more access specifiers, and there are no restrictions on how often an access specifier may appear. 
  • Each access specifier specifies the access level of the succeeding members
  • The specified access level remains in effect until the next access specifier or the end of the class body.

Member access control (cont.)

class point():
    def __init__( self, x, y ):
        self.__x = x
        self.__y = y

    def x( self ): 
        return self.__x

    def y( self ):
        return self.__y

def main():
    p = point( 1, -1 )
    print( p.x(), p.y() )

main()
struct point {
    point( int x, int y )
        : x_( x ), y_( y ) {}

    int x() const { return x_; }
    int y() const { return y_; }

private:
    int x_;
    int y_;
};

int main() {
    point p( 1, -1 );
    std::cout 
    	<< p.x() << " " 
    	<< p.y() << "\n";
}

Python

C++

class vs struct

class point {
// private by default
    int x;
    int y;

public:
    point();
    point( int x, int y );
};
struct point {
// public by default
    point();
    point( int x, int y );

private:
    int x;
    int y;
};

The only difference between class and struct keywords is the default access level.

Recommendation: Use struct to define types where all members are public, use class to define types with private members.

Exercise 2

  • Open the exercise template

  • Write your code, press Run to test

  • When you're done, grab your Repl's link and send it as a direct message to me (agurtovoy)

  • Click on the corresponding option in the "Lab12 exercises" poll in #general

Modify a rational number implementation according to the exercise comments

friend(s)

  • Allows designated non-member functions and classes to access private class members.
  • friend declarations may appear only inside a class definition.
  • friend declarations are not affected by the access control of the section in which they are declared.
  • Friendship is not transitive (a friend of your friend is not your friend).
  • Friend declaration can define a non-member function and makes it a friend at the same time.
  • If a friend function was not explicitly declared at the namespace scope, it's only accessible through  argument-dependent lookup (ADL).

Inheritance 101

  • Public inheritance establishes is-a relationship between base and derived classes.

  • A reference to a derived class is implicitly convertible to a reference to a base class.

  • Base class constructor is always called (implicitly or explicitly) as a part of the derived class constructor.

  • Base class constructor is called before other data members of the derived class are initialized.

  • An instance of a base class can be explicitly cast to a derived class using static_cast; if the cast instance isn't in fact a part of the derived object, the cast results in undefined behavior.

Inheritance 101 (cont.)

class car():
    def __init__( self, 
                  make_n_model, 
                  year ):
        self.make_n_model \
            = make_n_model
        self.year = year


class truck( car ):
    def __init__( self, 
                  make_n_model, 
                  year, 
                  capacity ):
        super().__init__( 
            make_n_model, 
            year )
        self.capacity = capacity
struct car {
    car( string make_n_model, 
    	 int year )
        : make_n_model( make_n_model )
        , year( year )
    {}

    string make_n_model;
    int year;
};

struct truck : car { // truck is-a car
    truck( string make_n_model, 
    	   int year, double capacity )
        : car( make_n_model, year )
        , capacity( capacity )
    {}

    double capacity;
};

Python

C++

Programming with C++, Spring 2020, Lecture #12

By Aleksey Gurtovoy

Programming with C++, Spring 2020, Lecture #12

Member access control, friends, inheritance

  • 587