C++ Lecture 2

[Previous Lecture] [Lecture Index] [Next Lecture]

Intro to C++ Classes

Instance Methods

Access Control

public:
allows things outside the class to access the following entities
private:
prevents things outside the class from accessing the following entities

class xyz
starts in `private mode'
struct xyz
starts in `public mode'
class Xyz {
	int a;		// private by default
    public:
	int b;
	int foo() {
	    return a + b + c + bar();
	}
    private:
	int c;
	int bar() { return a * b * c; }
};

int
test()
{
    Xyz x;
    return x.b + x.foo()	// ok
	+ x.a		// NOT allowed
	+ x.c		// NOT allowed
	+ x.bar();	// NOT allowed
}

Creating Header Files

Header files typically contain: General form of header file:
    #ifndef FILENAME_H
    # define FILENAME_H

    // Declaration of simple types
    // Definition of symbolic constants
    // Forward declaration of classes

    # include "others.h"

    // Definition of classes
    // Global variables
    // Function prototypes

    #endif /* FILENAME_H */
Goal is to avoid problems caused by multiple inclusions, and to deal with circular dependencies.

grow-3.h

#ifndef GROW_H
# define GROW_H

class Growing_buffer {
    enum { INITIAL_SIZE = 16 };

    char *buf;
    int n_used;
    int size;

public:
    // Default constructor
    Growing_buffer();
    // Specifies initial size of buffer
    Growing_buffer(int isize);
    // Specifies initial contents of buffer
    Growing_buffer(const char *str);

    // Add a character to the buffer
    void addc(char c);

    // Empty the buffer
    void reset();

    // Return buffer length
    int getlen() const { return n_used; }
    // Return buffer contents
    const char * getbuf() const { return buf; }

    ~Growing_buffer();
};
#endif /* GROW_H */

grow-3.cc

#include <string.h>
#include "grow-3.h"


Growing_buffer::Growing_buffer()
{
    size = INITIAL_SIZE;
    n_used = 0;
    buf = new char[size];
}

Growing_buffer::Growing_buffer(int isize)
{
    size = isize;
    n_used = 0;
    buf = new char[size];
}

Growing_buffer::Growing_buffer(const char *str)
{
    size = strlen(str) + 1;
    n_used = size;
    buf = new char[size];
    strcpy(buf, str);
}

void
Growing_buffer::addc(char c)
{
    if (n_used >= size) {
        char *nbuf;

        size *= 2;
        nbuf = new char[size];
        memcpy(nbuf, buf, size / 2);
        delete [] buf;
        buf = nbuf;
    }
    buf[n_used++] = c;
}

void
Growing_buffer::reset()
{
    n_used = 0;
}

Growing_buffer::~Growing_buffer()
{
    delete [] buf;
}

grow-3-main.cc

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include "grow-3.h"

int
readline(FILE *fp, Growing_buffer *gb)
{
    int c;

    gb->reset();
    while ((c = fgetc(fp)) != EOF) {
        gb->addc(c);
        if (c == '\n')
            break;
    }
    gb->addc('\0');
    return gb->getlen() - 1;
}

int
main(int argc, char **argv)
{
    int i;
    int lineno;
    int ecode = 0;
    FILE *fp;
    Growing_buffer gbuf;

    for (i = 1; i < argc; i++) {
        fp = fopen(argv[i], "r");
        if (!fp) {
            fprintf(stderr, "can't open %s - %s\n",
                argv[i], strerror(errno));
            ecode = 1;
            continue;
        }
        lineno = 1;
        while (readline(fp, &gbuf) > 0) {
            printf("%d %s", lineno, gbuf.getbuf());
            lineno++;
        }
        fclose(fp);
    }
    return ecode;
}

Some Differences from C


Stream Input

#include <iostream.h>
cin
global variable associated with standard input
>>
handles input of most types (char, int, double, etc.)
Skips any white space before reading
get(char &)
read a character - does not skip white space
get(char *, int size, char delim = '\n')
read up to the delimiter character - does not skip white space
does not read the delimiter
read(void *, int size)
used to read arbitrary data (such as structures, etc., equivalent to fread()).
peek()
like get(char &), but doesn't consume the character
fail()
test if last operation failed
    int i;
    float f;
    char c;
    char buf[1024];

    cin >> i;
    cin >> f;
    cin >> c;

    cin.get(c);

    c = cin.peek();

    cin.get(buf, sizeof(buf), '\n');
    if (cin.fail()) { // or   if (!cin) {
	cerr << "Couldn't read buffer\n";
	exit(1);
    }

Stream Output

cout, cerr
global variables associated with standard output and standard error
<<
handles output of most types (char, int, double, etc.)
put(char &)
write a character
write(char *str, int n)
write a n characters
flush()
flush any buffered output (e.g., actually write to the file)
fail()
test if last operation failed
    int i;

    cout << "Processing output";
    for (i = 0; i < 8291; i++) {
	// a slow function
	process_data(i);
	cout << '.';
	cout.flush();
    }
    cout << "done\n";

    char *s = "hi there folks";

    // print whole string
    cout << s;
    // print first n characters
    cout.write(s, 8);

    if (!cout)
	cerr << "problem writing to output\n";

References


[Previous Lecture] [Lecture Index] [Next Lecture]