• No results found

ClassC/Elaine: a multiple inheritance object oriented C language

N/A
N/A
Protected

Academic year: 2019

Share "ClassC/Elaine: a multiple inheritance object oriented C language"

Copied!
99
0
0

Loading.... (view fulltext now)

Full text

(1)

Rochester Institute of Technology

RIT Scholar Works

Theses

Thesis/Dissertation Collections

9-12-1988

ClassC/Elaine: a multiple inheritance object

oriented C language

Paul Kirkaas

Follow this and additional works at:

http://scholarworks.rit.edu/theses

This Thesis is brought to you for free and open access by the Thesis/Dissertation Collections at RIT Scholar Works. It has been accepted for inclusion

in Theses by an authorized administrator of RIT Scholar Works. For more information, please contact

[email protected].

Recommended Citation

(2)

Rochester Institute of Technology

School of Computer Science and Applied Technology

ClassC /Elaine:

A Multiple Inheritance Object Oriented C Language

by

Paul Kirkaas

A thesis submitted to the faculty of the School of Computer Science and

Technology

in

partial fulfillment of the requirements for the degree of Master of

Science

in

Computer Science.

Approved by:

James Heliotis

Dr James Heliotis

Andrew Kitchen

Dr Andrew Kitchen

Peter G. Anderson

(3)

Class C

/

Elaine:

A Multiple Inheritance Object Oriented C Language

by Paul Kirkaas

I, Paul Kirkaas, hereby grant permission to the Wallace Memorial Library of RIT

to reproduce my thesis in whole or in part provided the source is credited. Any

reproduction will not be commercial use or profit.

Paul Kirkaas

Paul Kirkaas

(4)

-

1

ABSTRACT

Object

oriented

programming is

a

way

of

abstracting

information

and

operations

to

make

programming

more

efficient

and

reliable.

C

is

a

non object

oriented

programming

language

that

has become

a

de facto

language

standard

in

academic

and

industrial

applications

because

of

its

power

and

flexibility.

ClassC

is

an

attempt

to

add

object

orientation

on

the

existing

framework

that

C

provides.

Specifically,

ClassC

adds

the

new

data

type

object

,

and

the

new

aggregate

declaration,

class.

ClassC

differs from

other

C-based

object

oriented

languages

such

as

C++

Objective-C in

three

points:

1)

ClassC

provides

true

multiple

inheritance,

which

is

very

commonly

discussed in

the

description

of object oriented

languages,

but

very rarely

actually

implemented.

2)

ClassC

provides

both

strict

type

checking

on

objects

as

well

as

typeless

dynamic

binding

a variable of

type

object

may

be

assigned

any

class

instantiation.

Dynamic

binding

is

typical

of

interpreted

languages like

lisp

and

Smalltalk,

but

rare

in

compiled

languages like

C

and

Pascal,

etc.

3)

ClassC

offers

automatic

garbage

collection

of

memory

no

longer

referenced

by

any

object variables.

ClassC/Elaine

is intended

to

be

a

flexible

system

that

allows

programmers

to

explore

different

qualities

of

object

oriented

programming,

including

strong

and

weak

type checking,

and single and multiple

inheritance. This

thesis

is

a

description

of

the

background,

design,

and

implementation

of

the

ClassC language.

Keywords

Object Oriented

Programming, C++,

Objective-C, Smalltalk,

ClassC

Computing

Review

Subject Codes

Primary

Code:

D.3.2

Language Classifications

(5)

CONTENTS

1.

Introduction

1.1

ClassC/Elaine

1.2

Motivation

1.3

Background

.

1.4

System Description

1.5

Language Description

1.6

Functional Overview

2.

Functional

Specification

ClassC/Elaine

Programming

Guide

10

2.1

Introduction

to

ClassC/Elaine

10

2.2

Overview

11

2.3

Defining

classes

13

2.4

Defining

class

functions

15

2.5

Declaring

and

Initializing

Objects

16

2.6

Deleting

Objects

18

2.7

Using

Objects

19

2.8

Use

of

Member

Functions

21

(6)

2.10

Using

the

-G

Garbage Collection Option

22

2.11

Using

ClassC/Elaine

23

2.12

Keywords

and special symbols

24

2.13

Examples

of

ClassC

programs

24

3.

Implementation

25

3.1

Statement/Declaration

Mixing

25

3.2

Inline Comments

25

3.3

Class

Definition

26

3.4

Inheritance Mechanism

31

3.5

Object

Table

38

3.6

Objects

38

3.7

Object

39

3.8

Runtime

Library

Functions

41

3.9

The Problem

of

Non-Idempotentcy

49

4.

Implementation

52

4.1

Statement/Declaration

Mixing

52

4.2

Inline Comments

52

(7)

4.4

Inheritance

Mechanism

58

4.5

Object

Table

65

4.6

Objects

65

4.7

Object

66

4.8

Runtime

Library

Functions

68

4.9

The Problem

of

Non-Idempotentcy

76

5.

Appendicies

Sample ClassC Programs

79

5.1

ChessMovs.e

79

(8)

1.

Introduction

Object

oriented

programming

is

a

way

of

abstracting

information

and operations

to

make

programming

more efficient and reliable.

G is

anon object oriented

programming

language

that

has

become

a

de facto language

standard

in

academic and

industrial

applications

because

of

its

power

and

flexibility.

ClassC is

an attempt

to

add object orientation on

the existing

framework

that

C

provides.

1.1

ClassC/Elaine

ClassC

is

a

C-based

object oriented

programming language.

The language

adds object oriented

capabilities

to the

C programming

language.

Specifically,

ClassC

adds

the

new

data

type

object ,

and

the

new aggregate

declaration,

class.

Class

definitions

are

like C

structures except

they

may

contain

function

declarations,

and

they

may inherit

components

from

multiple

ancestors;

objects are

instances

of aparticularclass.

An

object variable

may

be

declared

by

a class

name,

in

which case

it

must represent

only

objects of

that

class or

descendants

of

that class,

or an object variable

may

be

declared

by

the

keyword

object,

in

which case

it

can

be

used

to

represent

any type

of object

in

the

system with no

type

checking.

Elaine

is

the programming

environment

for ClassC.

Initially

it

consists of

the

runtime

library

functions

necessary to

implement

ClassC;

enhancements will

be

addedover

time.

There

are other

C-based

object oriented

languages,

such as

C++

and

Objective-C,

but ClassC

differs

from

these

other

languages

in

three

points.

1)

ClassC

provides

true

multiple

inheritance,

which

is

very commonly

discussed in

the

description

ofobject oriented

languages,

but

very

rarely actually

implemented.

2)

ClassC

provides

both

strict

type checking

on objects as well as

typeless

dynamic

binding

-a

variable of

type

object

may

be

assigned

any

class

instantiation.

Dynamic

binding

is

typical

of

interpreted

languages like

Lisp

and

Smalltalk,

but

rare

in

compiled

languages like Cand Pascal.

(9)

1-ClassC/Elaine

Paul Kirkaas

3)

ClassC

offers automatic garbage collection of

memory

no

longer

referenced

by

any

object

variables.

1.2

Motivation

Object

oriented

programming

provides a

way

to

abstract

data

and control.

It

allows

the

programmer

to

create models

that

are

internally

complex and

sophisticated,

yet which present a

simple and uniform

interface

to

the

user.

There

are

two

broad

arguments

for

Object

Oriented

programming.

The first

is

that

Object

Oriented programming

improves

productivity

and

reliability

by

allowing the

reuse ofcode and

the

standardization ofcommon

data

types

and operations.

The

second argument

is

that

by

allowing

greater

abstraction,

object oriented

languages

are

continuing the trend

in

programming

languages

towards

a more

human like

and

less

machine

like

meansof

expressing

concepts.

This implies

that

object oriented

programming

can

facilitate

not

only

bigger

programs,

but

clevererones as well.

This is

my primary

interest.

The C

language

was

designed

with a particular

philosophy

as

well;

and one which often conflicts

with

many

of

the

common arguments

for

object oriented programming.

In

general,

C

is designed for

efficiency

and enforces

fairly

casual

type

checking.

C

allows

the

programmer unusual

intimacy

with

the

data

representation and

the

machine.

There is

no

information

hiding

with

C.

These

characteristics give

the

programmer

flexibility

and

the

ability

to

coerce

the

language

in

unusual ways.

This is

valuable,

but

can also

be

dangerous

for

unsophisticated users.

Object

oriented

languages

emphasize much more

information

hiding

and abstraction.

The

user

is

isolated from

the

machine and

data

representation asmuchas possible.

Both

these

philosophies

have

merit.

The

task

of

combining

these

features into

a single

language is

to

some

degree

a subjective

one,

and one which always makes some compromise

for

every

decision

(10)

ClassC/Elaine

paul

Kirkaas

For

example,

in most object oriented

languages,

the

data

components can not

be

accessed

directly.

The

user can

only

change

the

data

component

through

a member

function

(

or

"message").

This

preserves

abstraction,

but

is

less

efficient,

more

time

consuming

to write,

and

irritating.

The

choice

made

for ClassC

was

to

allow

the

programmer

direct

access

to

data

components ofobjects.

The

goal of

ClassC/Elaine,

then,

is

to

provide ausable

C

based

object oriented

language

that

offers

an alternative

to

previous

implementations.

Most

of

the

code executed

in

any

program

is

straight

forward

and

does

not

benefit

from

an object oriented approach

(

e.g,

for-loops,

arithmetic

operations,

etc).

This

code should

be

implemented

as

efficiently

as possible

for

rapid execution.

This

is

the

motivation

for using C

as

the

base language.

Object

type

data

manipulations should

be

used

for

operations which are

conceptually

intricate,

where use of object oriented

techniques

could

give

both

the

programmer and

the

program more

clarity

and expressiveness.

This is

the

motivation

for enhancing

C

withobject oriented

features;

moreover, this

is

the

reason

for

giving

ClassC

a

higher

level

of abstraction

that

C++

or

ObjectiveC

through

multiple

inheritance

and untypedobjects.

In

order

to

be

genuinely useful,

ClassC

was made compatible with

existing C language facilities.

It is

compatible with all

existing

standard

^include

files,

as well as all

library

packages.

It

allows

separate compilation and

linking

of

ClassC

modules,

as well as

the

creation of

individual ClassC

libraries.

l.S Background

The

foundations

of

Object Oriented

programming

were

laid

by

the

programming language

Simula,

which was

developed

in

Norway

in

the early

1960's

[DAH66].

It introduced

the

concept of user

defined

classes,

and was

developed

as a simulation

language for

modeling

complex systems.

The

power of

this

concept was not

widely

recognized until

Alan

Kay

and

the

research

group

at

Xerox

PARC developed

the

Smalltalk interactive

environment.

It

evolved

from Dr. Kay's

concept of a

computercalled

the

Dynabook,

which would

be

very

user

friendly

and

suitable

as a

learning

aid

for

(11)

-3-ClassC/Elaine

paul Kirkaaa

children

[GOL83J.

Smalltalk

remains

to this

day

the

prototypical example of an object oriented

language.

It

is arich and complex environment

that

shows

the

power of

the

object oriented concept.

Yet

this

richness and

complexity

has

a price.

Smalltalk

is

big,

slow, expensive,

and available on

very

few

machines.

Its

primary

drawback from

a systems

development

perspective

is its

slowness.

Smalltalk

runs on a virtual machine

/

interpreter,

which

is inappropriate

for large

software systems.

This

is unfortunate,

because

software systems are classic candidates

for

the productivity

benefits

of

object oriented programming.

Concepts like

queues, stacks,

hash tables,

etc. are

ideal

abstraction

types.

But

an

operating

system written

in

Smalltalk

running

on conventional

hardware

would

be

very

slow.

Enter

C++ [STR86].

C++

was

developed

at

AT&T Bell

Laboratories,

home

of

Unix, C,

Kernighan

and

Ritchie.

It

was

developed

by

Bjarne

Stroustrup

with

the

intent

of

giving

as much object

oriented structure

to

C

as

possible,

while

sacrificing

none of

the efficiency

of pure

C

code.

It

is

therefore

perhaps

the

best

system

development

language

available

today.

The C++

compiler

translates

C++

code

into

standard

C.

Thus,

C++

must

implement its

object

oriented

features

in

a

C format.

It

does

this

by

using

standard

C

structures.

An

object

in

C++

is

implemented

in

two

ways.

The

function

components of

the

class are given unique names and

written

to

the

output

file.

The

function

members are associated with

the

classrather

than

with

the

object.

This

means

that

all

instances

of a class

have

unique private

data

but

share

the

same

component

functions.

The data

portion of a

C++

object

is

implemented in

a standard

C

structure,

with all

the

data

components of

the

object as elements of

the

generated structure.

Inheritance

is

implemented

by

copying the

parent object structure and

concatenating the

new elements of

the

derived

class after

the

elements of

the

parent class.

The

component sequence of

the

parent and

derived

classes are

therefore

identical

up to

the

end of

the

parent class.

Consequently,

the

address of an

instance

of a

derived

class can

be

assigned

to

an object pointer of a parent class and

the

standard

C

structure
(12)

ClassC/Elaine

paul Kirkaas

This

makes object

dereference

easy

and

efficient,

but

makes multiple

inheritance difficult for

reasons

discussed later.

Objective-C is

a

language developed

by

Dr.

Brad Cox

at

Productivity

Products

International

and

seems much

like

C++

with a

different

syntactic structure.

The

two

languages

offer similar

features

[COX86].

1.4

System

Description

The

ClassC/Elaine

compiler was

be

developed

under

Unix

using the

Unix lexical

analyzer

Lex

and

the

Unix

parser generator

Yacc,

and uses

the

standard

Unix/C libraries.

The

running

system

consists of

three

files-1.

The

parser

efront-The

ClassC/Elaine front

end

parser,

written

in C.

The

parser

translates

ClassC/Elaine

.e

source

files

into

".c"

C language files.

2.

The Unix

Shellscript

ce-The

shellscript ce

is

the

compiler command

invoked

by

the

user.

It

parses

the

command

line

options and source

files,

applies

the

appropriate versionof

the

parser andruntime

library,

and

calls

the

C

compiler cc on

the

result.

3.

The

ClassC/Elaine

runtime

routines,

libce.a.

libce.a

contains runtime

functions

suchas_new(),_deref(),etc.

1.5

Language

Description

The

concept

for

ClassC differs from

those

of other

C-based

object oriented

languages.

ClassC

was

developed

as a

learning

tool

for data

abstraction andobject oriented

programming

concepts.
(13)

ClassC/Elaine

Paul Kirkaas

philosophy

is

reflected

in

the

decision

to

provide multiple

inheritance

and

dynamic

binding

of

objects.

There

is

some runtime cost

to

provide

these

features,

mainly function

call overhead.

ClassC is

asuperset of

C;

that

is,

all

C

operations are supported

by

ClassC,

and

pre-existing

library

and object

files

as well as standard

header

files

are all compatible with

ClassC.

The

language

was

developed

in

a

Unix

operating

system

environment, using the

Unix language development

tools.

The

parser acceptsstandard

C

code and passes

it

to the

output

file

unchanged.

It

maintains symbol

tables

and

scoping

information

while

building

the

parse

tree.

In

addition

to

standard

C,

the

parser accepts and processes

the

following:

1.

The

aggregate

definition

class-PL

class

declaration

is

much

like

a standard

C

structure

declaration.

A

class

is

composed of

Members;

of which

there

are

two types:

a.

Variable

members-which are passive

data

components of

the

class

instances.

b.

Function

members-which are

functions

that

act on

the

private member variables of class

instances.

In

addition,

aclass

definition may

contain a

list

of parent classes

from

which components are

inherited.

2.

The

class member

function

definition-Different

classes

may have

member

functions

with

the

same

name; e.g.,

print.

To distinguish

them,

class member

functions

are

defined using

the

class name and a

scoping

operator.

3.

Objects-All

objects are

dynamically

allocated at runtime

by

explicit

calls

to

a 'newQ'

function.

A

variable of

type

object

is

really

an

index into

an object

table.

An

object

may

be

declared

in

(14)

ClassC/Elaine

paul Kirkaag

1.

With

a class

name-Class

names are used

to

declare

object variables.

Object

variables

declared

this way

can

only

represent objects of

that

particularclass

type

or

its descendants.

2.

With

the type

specifier

object-A

variable

declared

with

the type

specifier object can

be

used

to

represent

any type

of

object

instance

at all.

4.

The

object member

dereference-The

member

dereferencing

operator used

in

ClassC

is

":>".

C++

uses

the

ordinary

C

structure

dereferencing

operators

for

object

dereferencing,

but

the

dereferencing

mechanism

in

ClassC is

implemented

differently

and suggests

the

use of aseparate symbol.

5.

Variable

declarations-Variable

declarations

can

be

made anywhere

in

a

block.

This is intended

to

more

closely

associate

the

variable

declaration

with

its

use.

Every

variable must still

be declared before its

first

use.

1.6

Functional Overview

Classes:

A

class

is

declared

as

follows:

class

Class_name

:

SuperClass_l

:

SuperClass_2

: ...

{

type

declarator,

type

declarator,

type

declarator,

type

declarator,

};

where

Superclasses

areoptional and separated

by

the

inheritance

operator

":";

and where

declarator

(15)

ClassC/Elaine

Paul Kirkaa3

Two

special

types

of

functions

that

may be

declared

asa class member are

initQ

and

deletef).

initf)

is

that

class's

initializer

function.

The

initf)

function

is

defined

by

the

user and

is

automatically

invoked

when an object of

that

class

is

created.

Otherwise,

if

initf)

is

not

declared,

uninitialized

memory

space will

be

allocated.

deletef)

is

the

class

delete function.

It

should

be defined

by

the

user

to

clean

up

any

special

memory

resources which objects of

that

class

may

allocate

to themselves

(through

mallocf),

for

instance).

Objects:

Objects

are created

dynamically

from

the

heap;

there

are no static objects.

Each

object

is

an

instance

of a specific class.

A

member of an object

(the

member can

be

either variable or

function)

is

dereferenced

by

the

object

dereferencing

operator

":>".

The

general

form

of

the

object

dereference is:

"

objectExpression:> member

Name;";

where

"objectExpression"

is

usually

just

a variable name.

In

general,

however,

an object expression

can also

be

the

result of a pointer

dereference,

a return value

from

a

function,

etc.

The

type

of

the

entity

returned

by

the

object

dereferencing

operator

is

determined

by

the

type

of

the

object

expression.

If

the

class

to

which

the

object expression

belongs

can

be

determined

at compile

time,

the type

of

the

returned

dereferenced

element

is determined

by

its

type

as

declared in

the

class

definition.

If

however

the

object expression evaluates

to

an

instance

of

the

generic class

object,

its

true

class

cannot

be

determined

at compile

time.

In

this

case

the type

of

the

result of

the

dereference is

defaults

to

objectas well.

The

programmer can cast

the

result

to

be

of

any type

and override

the

default.

Member Functions:

Member functions

are

defined

with

the

class

name,

scoping

operator

"::",

and

the

function

name

-e.g

*Son::print()\

Arguments

are

declared just

like in

an

ordinary

C function definition.

An

(16)

ClassC/Elaine

Paul Kirkaas

with no special

dereferencing

or

casting

required.

A

reference

to

"self"

is

passed

automatically

on a

call

to

a member

function,

and

may

be

used

explicitly

by

the

programmer

in

an object's member

function definition

to

reference

the

object

itself.

Examples:

Declare

class

Son

to

be

a

descendant

of classes

Papa

and

Mama.

class

Son

:

Papa

:

Mama

{

int

a;

char *

b;

initf);

/*

Optional

initialization function

*/

void print

();

};

Define

member

function

initf)

of class

Son:

Son::initfx,y)

int

x;

char *

y;

{

b

=

(char

*)

malloc(strlen(y) +

1);

strcpy

(b,y);

a=

x;

}

Declare

anobject

& initialize

to

be

ofclass

Son:

Son

xmpl =

Son:>new(5, "Hello");

Send

the

message

"print"

to

xmpl:

xmpl:>print();

Reset

member element "b"

of xmpl:

xmpl:>b =

(17)

ClassC/Elaine

paul Ki_kaa3

2.

Functional

Specification

-ClassC/Elaine

Programming

Guide

2.1

Introduction

to

ClassC/Elaine

ClassC is

an object oriented

programming language based

on

C,

and

it is

assumed

the

user

has

a

both

a solid

knowledge

of

the

C language

and a conceptual

understanding

of object oriented

programming.

Like

C++

and

ObjectiveC,

ClassC

is

really

a

preprocessor,

converting

ClassC

source code

into

C,

then

into

assembly

language,

and

finally

into

machinecode.

ClassC

is

asuperset of

the

C

language,

and all

C

constructs except enum are accepted and

semantically

unchanged

(

enum was not

implemented because

it

differs

from

other aggregate

types.

It

would require a special symbol

table,

and

is

not

widely

used

in C.

It

would

be

a

tedious

but

not

difficult

feature

to

add).

ClassC/Elaine has

the

following

features:

ClassC's

objectoriented extensions

to

C

1.

Class Definition:

A

class

is defined like

a

C

structure,

except

that

it

may

inherit

components

from

an

arbitrary

list

of ancestor

classes,

and

may

include

functions

as components.

2.

Objects:

An instance

ofa class as

defined

above

is

an object.

Objects

can

be

declared in

one

of

two

ways.

A

class

definition

is

like

a

typedef

in C.

This

means

that

a variable can

be

declared

by

using

a class name as a

type

declaration.

Variables

so

declared

can

only

be

assigned objects of

that

same

type

or ancestor

types.

In

addition,

a new

data

type

object

is

introduced,

whichcan

be

used

to

declare

variables which represent

any

class

type.

3.

Garbage Collection Option:

Invoking

the

"ce"

compile command with

the

option "-G"

results

in

the

inclusion

of

the

ClassC

garbage collection mechanism.

ClassC's

non-object orientedextensions

to

C

(18)

ClassC/Elaine

Paul Kirkaas

Following

C++,

any

text

between

"//"

and

the

newline

is ignored.

2.

Statement/Declaration

Mixing:

Statements

and variable

declarations

can

be intermixed

in

the

body

of a

block,

as

long

as each

variable

is declared before its

use.

The distinction between

classes, objects,

and object variables

in

ClassC

should

be

understood.

A

class

type

definition

is

used

to

define

the

valid

data

components and operations

(methods,

messages)

for

objects of

that

class.

An

object

is

an

instance

of a particular

class,

created

dynamically

from

the

heap

at runtime

by

explicit calls

to

"className

:> new()".

An

object variable

is

implemented

as an

integer

index

into

an object

table.

Since

the type

(class)

of each object

is kept in its

object

table

entry,

it

need not

be

a characteristic of

the

object variable

itself.

This

allows

dynamic

binding

of

object variables

to

objects.

In

other

C based

object oriented

languages,

the type

of

the

object variable must

be declared

to

be

of

a specific

class,

and can

be

used represent

only

objects of

that

particular

class,

or classes

derived

from

that

class.

In

ClassC,

type checking

is

performed

only

on

those

objects

declared

to

be

of a

particular class.

The

declaration

object can

be

used as a catch-all

to

hold

any

system object

type

withno

compatibility

checking.

This is

useful

for

collectionclassessuch as sets which should

be

able

to

contain allobject

types.

2.2

Overview

This

section

introduces

the

flavor

of

programming

in

ClassC.

More detailed

explanations can

be

found in

the

following

sections.

Objects

in ClassC

are much

like

structureswhich can

have function

components.

The

":>"

operator

is

used

to

dereference

a component of an object.

If

the

component

is

a

data/variable

type

component,

it

can

be

used as an

l-value

-

that

is,

it

can appear on

the

left

side of an assignment

expression.

There is

no conceptof

"private"

components

in

ClassC.

(19)

ClassC/Elaine

paul

Kirkaas

A function

component

in

ClassC

is

like

a message

in

Smalltalk.

Messaging

could

have

been

implemented

with a

Smalltalk like

syntax, but

one goal of

ClassC

was

to

be

as

C-like

as possible

while

providing

object oriented extensions.

Hence,

messages arguments are passed

like

regular

function

arguments

in C.

Thus

the

expression:

"thisObj

:>

message(argl,arg2);"

applies

the

member

function

"messagef)"

to the

object

"thisObj"

with

the

arguments

"argl" and

"arg2".

In

ClassC,

classes are

defined

by

the

inheritance

of components

from

parent classes and an

additional

declaration

section

for

components unique

to the

class

being

defined.

A

classname

may be

used

to

declare

an object

variable,

which

then

represents a pointer

to

an object

of

that

class

type.

However,

the

object

itself is

not created until an explicit

initialization

call

is

made.

For

example, the

declaration

"MyClass

declares

"objVariable"

to

be

a pointer

to

an object of

type

"MyClass";

but

it is initialized

to the

NULL

pointer

(0).

To

create a new object of

type

"MyClass",

send

the

message

"newf)"

to

"MyClass"

"MyClass:>new()

".

It is

possible

to

declare

an object variable and

initialize

the

object

in

one step:

"MyClass

objVariable =

MyClass:>new();"

Class

names are also used when

defining

member

functions.

Since

several classes

may

have

member
(20)

ClassC/Elaine

Paul Kirkaas

identify

it.

2.3

Defining

classes

A

class

in ClassC

is defined

much

like

a structure

in

C.

A

class

definition is indicated

by

the

keyword

"class",

followed

by

the

name of

the

class

to

be

defined,

an optional

inheritance list

of

previously

defined

classes,

and

the

body

of

the

class

definition.

The

definition

body

is just

a

sequence of

declarations in

a standard

C

format.

This declaration

set

may

include function

and

object

declarations.

The

form

of aclass

definition is

thus:

class

Class_name

:

SuperClass_l

:

SuperClass_2

: ...

{

type

declarator,

type

declarator,

type

declarator,

type

declarator,

};

Three

things to

bear

in

mind about classes

-1.

Class

Definitions-No

other

classes,

structures or

typedefs

may

be

defined

within a class

definition,

although

previously

defined

typedefs

and structures

may

be

used within a

definition,

and other classes

which are

defined

elsewhere within

the

file

(earlier

or

later)

may

be

used

to

declare

member

components.

2.

Class

Names-The

"class*

keyword

is

used

only

on

definition.

Thereafter

the

defined

class name

is

used

like

a new

type

name.

This

means

that

unlike

structures,

you cannot

have

a variable with

the

(21)

13-ClassC/Elaine

Paul

Kirkaas

same name as aclass.

3.

No Unnamed

Classes-Unlike

struct

in

C,

all classes must

be

given a

name;

furthermore,

it is impossible

to

declare

an

object

instance

of aclass

in

the

same statement as

the

class

definition.

Class Inheritance

Classes

may inherit

components

(data

and

methods) from

an

arbitrary

number ofantecedents.

This

implies

a potential conflict when

the

same component name

is

used

in

more

than

one ancestor.

This

conflict

is

resolved as

follows:

1.

If

the

conflict

involves

two

componentsof

the

same name

but

of

different

declared

type

in

two

or more

different

ancestors, this

is declared

to

be

a semantic

error,

compilation

is

aborted and

an appropriate error message

is

reported.

2.

If

the

conflict

involves

components of

the

same name and

the

same

declared

type

in

each

ancestor, then the

component

from

the

parent earliest

in

the

list is defaulted.

This

default inheritance

of

the

component

is irrelevant

for

data

components,

but

critical

for

function

components.

That

is,

if

the

same

function

name and

type

is declared in

several

ancestors, the

first

definition

encountered when

traversing

the

list

of ancestors

is

the

function

definition

used

for

the

newclass.

3.

If

the

conflict

involves

a component

explicitly

declared

in

the

body

of

the

current class

definition

and an ancestor of

that

new

class, the

new

definition

is

used,

which supersedes all

ancestor

definitions.

This is

the

case even

if

the

type

of

the

new component

declaration

conflicts with

the type

declaration

of acomponent of

the

samename

in

an ancestorclass.

Note

that

if

the

user wants

to

supersede a

function definition

from

a parent

class, that

function

must

be

declared

in

the

body

of

the

new class as well as

being

redefined as
(22)

ClassC/Elaine

Paul Ri_kaa3

2.4

Defining

class

functions

1)

Declaration

Different

classes

may

have

member

functions

with

the

same name.

Similarly,

a

derived

class

may

redefine a

function

which was

defined

previously

in

an ancestor class.

It

is

therefore necessary to

have

a means

to

distinguish

whichof

the

several possible member

functions is

being

defined.

This is

done

with

the

class name and

the

function

name

joined

with

the

scoping

operator

"::".

So

to

define

the

member

function

"printQ"

of class

"Bishop"

which

takes

a char * argument

"str"

and returns

an

integer

int

Bishop::print(

str

)

char *

str;

{

(Body

of

definition)

}

2) Body

The

body

of a member

function definition

is like

the

body

of an

ordinary

function

body

in

ClassC,

except

in

the treatment

of

the

components of

the

object

to

which

the

message/function

is

being

sent.

Specifically,

the

body

ofa member

function definition

can refer

to

other elements of

the receiving

object without

explicitly

dereferencing

them.

The

appropriate

dereferences

are

implicit

in

the

function

itself.

For

example:

class

Piece

{

char*

name;

object

position;

int

checkPositionf);

int

showf);

void

movef);

void report

();

/*

Send

message

to

coordinator

*/

};

(23)

15-ClassC/Elaine

Paul Kirkaas

is

a

declaration for

the

class piece.

The

member

function

"movef)"

of class

Piece

might

be defined

as

follows:

void

Piece::move(

newPosition, board

)

object

newPosition;

object

board;

{

if

(checkPosition (newPosition

) )

{

board:>atput(newPosition,

self);

position =

newPosition;

}

else report

("Illegal

Move");

}

Note

the

use of

the

identifier

self

in

the

definition

above.

Self is

an object variable which

is

automatically

generated

by

the

parser as an argument

to the

member

function.

It

represents

the

target

object

to

which

the

function/message is

being

sent.

The

variable name

"position"

used

in

the

definition

of

"Piece:

above

is known

to

be

a component of class

Piece,

and

is

therefore

assumed

to

refer

to the target

object.

The

statement

"position

=

could

have

been

equivalently

rewritten

"self

:>position =

In

general, the

"self"

variable

is

used when

the

member

function

manipulates

the

entire object

rather

than the

components of

that

object.

In

this case,

for

example,

it is

used

to

register

the

instance

of

the

Piece

class

to

its

new position with

the

object

"board".

2.5

Declaring

and

Initializing

Objects

Objects

can

be declared in

one of

two

ways:
(24)

ClassC/Elaine

Paul

Kirkaa3

2) By

the

name of aclass

defined

elsewhere

in

the

file.

When

an object variable

is

declared

by

a class

name,

all operations

subsequently

performed on

that

variable are checked

for

conformance at compile

time.

That

is,

operations are checked

to

ensure

that

they

are compatible with

the

object's

declared

class or ancestor

classes,

and

the

returned result

of

the

message

is

cast

to the

appropriate

type.

Variables

that

are

just

declared

to

be

of

type

object are not subject

to

any

class conformance

checking

until runtime.

Thus,

any

object operation

may

be

applied

to

variables

declared

to

be

of

type

object.

This

gives

the

user more

flexibUity

in

the

manipulation of

the object,

but

at

the

risk of

runtimeerrors

if

the

user

has

used

the

object

incorrectly.

It

is

suggested

that

use of

the type

name object

be

restricted

to

such applications as collection

classes,

where

it is desirable

to

allow objects of all

types

to

be

stored.

These

object

type

names are

syntactically

equivalent

to

standard

C

scalar

type

names

like

"int",

"char", "float",

etc.

This

means

that

they

can

be

used not

only to

declare

variables of

type object,

but

arrays

of,

pointers

to,

and

functions

returning

object as well.

So

some possible object

declarations:

object

x;

MyClass

y[4];

object

(*i)[3j|7);

Bishop funcf);

A

new object variable

is

essentially

an

empty

slot

into

which an object

may

be

placed.

Objects

themselves

are created

dynamically

from

the

heap

at runtime

by

a special call or message called

"newO".

The

message

"newQ"

is

sent

to

a class name

to

create a new

instance

of

that

class.

This

new

instance

may then

be

assigned

to

anobject variable

(be

put

in

the

slot).

Note: Classes

in ClassC

are not

themselves

objects,

but

are

syntacticly treated

as such with

the

(25)

17-ClassC/Elaine

Paul Kirkaag

"new()"

message.

So,

for

example,

to

make a newobject of class

Bishop

you write

"Bishop:>new()"

where

the

symbol

":>"

is

the

message

passing

or

dereferencing

operator of

ClassC.

An

object variable

may

be initialized

on

its declaration line like

any

other

C

variable.

So,

to

assign

the

new

instance

of

Bishop

to the

object variable mypiece we could write either:

Bishop

mypiece;

mypiece =

Bishop:>new();

or

Bishop

mypiece =

Bishop

:>new();

It is

also possible

to

create a special

"initf)"

function

for

aclass which

is

automatically

called when a

new object of

that

clas3

is

created.

The

"initf)"

function is declared

and

defined

like

any

other class

member

function

except

that

it

must not

be

declared

to

be

of

any type

or return

any

value.

An

"initf)"

function

may

be defined

to take arguments,

in

which case

the

call

to

"

C/a.37Vame:>new(argl,arg2,...)

"

is

made with

the

appropriate arguments.

New

objects created

from

classes

that

have

no

"initf)"

function

associated with

them

are created

with uninitialized memory.

2.6

Deleting

Objects

Garbage

collection

is

performed

automatically

when

the

ClassC

"-G"

compiler option

is

used.

The

user can also

explicitly

delete

unwanted objects andrelease

their memory

space

to the

heap.

An

object

is deleted

by

sending

it

the

message

"deletef)

"

(26)

ClassC/Elaine

Paul

Kirkaas

The function

"deletef)"

does

not

have

to

be

declared

as a component of an object

to

be

used

to

delete

an object.

It

can

be

used

to

delete

any

object,

and

just

releases

the

memory specifically

allocated

to

that

object

by

the

call

to

"newQ".

It is

possible,

however,

that

some objects

may

have

acquired additional

memory

resources.

For

instance,

an object

may

contain a pointer

to

a

dynamically

allocatedstring.

If

the

object

is deleted

without

freeing

the string, the

string

will

remain, uncollected,

floating

in

memory.

It is

thus

possible

to

explicitly

define

a member

function

"deletef)"

as part of a class

definition.

This

member

"deleteQ"

function

is

defined

like

any

class member

function,

and

the

user

is

responsible

for

cleaning up

any

additional

memory

allocated

to the

object

here.

When

the

message

"deletef)"

is

sent

to

an object

(possibly

with

arguments)

the

user

defined

member

"deletef)"

function is

called

to

clean

up

user allocated

memory, then the

system

"_deleteQ"

function is

called

to

delete

the

object

itself.

2.7

Using

Objects

There

are

three

different

ways

in

which object variablescan

be

used.

1.

They

can

be

used with

the

dereferencing

(component

selection)

operator ":>"

-e.g.,

"mypiece:>position

= or

"mypiece:>set

(newPosition);"

2.

They

can

be

used

in

assignmentstatements withother objects or

functions

returning objects;

e.g., "objl

= obj2;".

3.

They

can

be

passedas arguments

to

functions;

e.g.

"newobj

=

transform(oldobj);".

Dereferencing

Objects

Member Data:

The

operator ":>"

is

used

to

dereference

or select components of an object.

If

this

component

is

a

data

component, the

expression
(27)

19-ClassC/Elaine

Paul Kirkaas

"

object_name :> component

name"

is

an

1-value;

that

is,

the

expression can

be

used on either sideof

the

"= "

(assignment)

operator.

Components

of a class can

be

of

any

legal C

type,

or aclass

C

object.

If

the

object variable

has

been

declared

with a class

name,

component

type

interpretation is done

automatically.

This

means

that

if

object

"objl"

has been declared

to

be

of class

SampClass

andcomponent

"mycomp"

is

an

array

of

floats,

the

assignment

"objl:>mycomp

[6]

= 2.718;"

has

the

expected result.

But

as

discussed

above,

object variables

declared

to

be

of

type

objectare

dynamically

bound

and

their type

cannot

be determined

at compile

time.

Thus,

there

is

no

way to

determine

the

type

of component

"mycomp"

at compile

time.

Example:

Consider

two

classes,

ClassA

and

ClassB.

Each

class

has

a component named

"size".

The

declaration

of

"size"

for

class

ClassB "int

for ClassA it is "float

size;".

If

the

object variable

"objVar"

is declared

to

be

of

type object,

it is

not

bound

to

any

class

type

at compile

time

and

the

compiler

has

no

way to

know

the type

of

the

expression

"objVar:>size".

This

is

resolved

in

the

following

way:

1.

The

default

return

type

of

the

":>"

operator

is

type

"object".

Thus,

if

an object

is

expected,

nospecial

treatment

is

required.

2

If

an abstract

declaration

appears

between

the

component selector and

the component, the

type

of

the

expression

is

cast

to the type

of

the

abstract

declaration.

The

abstract

declaration

is

basically

a

C

cast except

that the

conversion

is

exact.

That

is,

if

the

component

is

an

array

of

6

floats,

the

abstract

declaration

for

that

component

MUST be

(

float

[6]

).

In

C,

the

appropriatecast would

be

(

float

*

);

the

cast

(

float

[6] )

is illegal

in

standard

C.

Similarly,

if

(28)

ClassC/Elaine

Paul

Kirkaas

structure.

So if

the

expected return

type

of

"objVar:>size;"

is

float,

it

must

be

expressed as

"objVar:>(float)size".

This interface is

awkward, but is

provided as an additional

feature for

the

user.

When

an object

variable

is declared

as an

instance

of a particular class rather

than

with

the

keyword

object, these

conversions are performed

automatically

and need not

be

ofconcern

to the

user.

2.8

Use

of Member

Functions

Member

functions

are accessed

through the

same ":>"

selection operator

by

which member

data

are

selected.

A

member

function

can access other member

functions

within

its

body;

in

particular,

member

functions

of a childcan access and call

functions inherited

by

that

child

from its

ancestors.

Similarly,

an

inherited function

that

references

function

components

that

have

been

redefined

in

the

derived

class will call

the

redefined

derived

class

function

rather

than the

function

for

which

it

was

originally

defined.

As

with

data

components,

function

component return values are

automatically

cast

to their

declared

types

for

object variables

declared

by

aclass

name,

and can

be

manually

cast

as

described

above

for

object variables

declared

by

the

keyword "object".

2.9

Object Assignment

Objects

can

be

assigned

to

object variables

through the

standard

C

assignment operator

"=".

This

means a reference

between

the

object variable and

the

object

itself is

established.

No

new objects

are created

by

this

mechanism.

For

example,

if

"a"

and "b"

are

both

object

variables, then the

assignment

"a

= b;"

does NOT duplicate

the

object pointed

to

by

b.

Rather,

both

"a" and

"b" now

reference

the

same object.

Thus,

any

changes made

to

object "b"

will

be

made

to

object "a"

as well.

In

order

to duplicate

an

object, the

user must allocate new

memory

and

initialize it

appropriately,

usually

through

a member

function.

For

example, to

create a

duplicate

of object

"objGen",

one

might write

"ACIass

dupObj

=

where

"copyQ"

(29)

ClassC/Elaine

paul

Kirkaas

object.

2.10

Using

the

-G

Garbage Collection Option

Garbage

collection

is

useful

for large

programs

that

use

large

amounts of

memory,

or programs with

repeating

loops

that

reassign object variables without

explicitly

freeing

old values.

Garbage

collection

is

a

feature

which allows

the

programmer

to

be less

rigorous when

writing

his/her

program,

but is

costly

in

terms

of computer resources andshould

be

used

judiciously.

Note

that

when

the

garbage collection option

is

invoked,

objects are

statically scoped,

and

hence

are

not stacked

in

recursive

function

calls.

Note

also

that

modules compiled with

the

garbage collection

option must not

be

combinedwith other modules compiled without

it.

Garbage

collection

takes

place

only

after a certain number of new objects

have

been

allocated,

and

thereafter

only

at specified

intervals.

Both

the

initial

threshold

and

the

frequency

can

be

modified

from

their

default

values

by

the

user.

The

external

integer

"CEGthreshold"

is

the

numberof newobjects

that

will

be

allocated

before

the

garbage collection mechanism

is

called

for

the

first

time.

On

systems with

large

memory,

it

often

makes sense

to

allow

this

number

to

be

quite

large

before

trying

any

collection.

The

value can

be

changed

in

any function

by declaring

the

variable

"extern

int

CEGthreshold;"

and

setting

it

to the

desired

value.

The

frequency

of

the

collection

is

modifiable as well.

Frequency

of

collection,

CEGfrequency,

is

defined

as

how

many

calls

to

new()

are made

between

collection attempts.

It is

wasteful

to

collect

the

entire object

table every time the

userwants

to

allocate anew object.

After

the threshold

size

CEGthreshold

has

been

reached,

collection

takes

place after each

"CEGfrequency"

calls

to new(),

(30)

ClassC/Elaine

paul ^^

"extern int

CEGfrequency;"

That

is,

the

integer

CEGfrequency

represents

how

many

calls

to

newQ

are made

between

each

attempt at collection of

the

object

table.

Again,

it is

only necessary

to

declare

the

variable

CEGfrequency

if it

is desired

to

modify its

default

value.

The

value

may

be

changed

by

assigning

anew

integer

to

it.

The default

valueof

CEGthreshold

is

1000;

default for

CEGfrequency

is

100.

2.11

Using

ClassC/Elaine

The

class

definitions

should

in be

put at

the

beginning

of

the

source

file,

and should occur

before

any

function definitions.

If

a

large

multi-file project

is

being developed,

all class

definitions

should

be

made

in

header

files

which are

^included in

each

file

that

manipulates objects of

those

classes.

The

member

functions

of each class should

be defined

only once,

and can

be defined

in

any

file

and

linked

in

at

load

time.

The

ce command

invokes

the

ClassC

compiler and processes command

line

options.

The

only

option

special

to

ce

is

the

garbage collection option

"-G".

Other

command

line

options

implement

standard ccoptions as

described below:

cecommand

line

options

-O

Invoke

the

C

optimizeron

the

output.

-o name

Call

the

executable

file

"name".

-g

Compile

for

debugging.

(31)

ClassC/Elaine

Paul Kirkaas

Compile for

profiling.

Create

with garbage collection.

-c

Create

object

file;

do

not

link

into

executable.

-llibname

Search

the

library

"lib/tiname.a"

for

unresolvedreferences when

linking.

Use

the

"-c"

option and

the

Unix

"ar"

library

archive command

to

build ClassC libraries.

2.12

Keywords

and special symbols

II

class

object

self

new

delete

Class

dereference

operator

Class

scoping

operator

Inheritance

operator

ClassC inline

comment operator

Class definition keyword

Object

type

name

Target

object

in

member

function

definition

ClassC

library

dereference function

ClassC

library

object creation

function

ClassC

library

object creation

function

ClassC

library

reference count

decrement

ClassC

library

reference count

increment

ClassC

library

delete function

2.13

Examples of ClassC

programs
(32)

ClassC/Elaine

Paul

Ki_kaaa

S.

Implementation

The

ClassC/Elaine

compiler

was

implemented

in

a

Unix System V

environment with

the

Yacc

and

Lex Unix language

development

tools.

The input files

are

first

processed

by

the

C

preprocessor cpp.

This

combines all

the

^include

.h

files,

substitutes all

the

#define's,

strips

the

comments,

and

inserts

appropriate source

file/line

number

information

for

error reporting.

The

output

is

directed

to

a

/tmp

file

which

is

then

parsed

by

the

ClassC

compiler,

which creates a converted x output

file.

Finally,

the

standard

C

compiler

is

invoked

on

the

generated .c

file

to

produce

the

executable code

or

intermediate

.o

files

for

separate compilation.

The first

task

was

to

build

a

C

language

parser

to

make sure

that

the

language

would

be

a proper superset of

C

(the

new

C

type

enum was not

included).

The

the

parser was

then

modified

incrementally

to

add

the

features

of

ClassC.

The

ClassC/Elaine

system was

implemented

as

follows:

S.l

Statement/Declaration

Mixing

In

ClassC,

statements and

declarations

can

be

mixed

together

within a single

block,

as

long

as

variables are

declared

before

being

used.

In

standard

C

all

declarations

are requiredat

the

start ofa

block before

any

executable statements.

In

order

to

convert

the

ClassC blocks into C

format,

the

code within each

block is

separated

into

two

collections a statement

list

and a

declaration list.

This

is

a recursive

procedure,

because blocks

can

be

nested and

blocks

within

blocks

are

themselves

statements.

So

a global variable

"block_number"

is

maintained and

the

block

code

is

partitioned

into

the appropriately

nestedcollection of

block

statements and

declarations.

At

the

end of a

block,

the

statements and

declarations

are

re-merged,

with all

the

declarations

floated

to the

top

of

the

block.

The

orderof

the

declarations

is

maintainedso

that

references

to

previous

declarations

within

the

same

block

arevalid.

3.2 Inline Comments

All

text

between

"//"

and

the

newline character

is

an

inline

comment and

is

removed

from

the

input

file

by

the

lexical

analyzer generated

by

lex.

(33)

2i-ClassC/Elaine

paul Ri_kaas

3.3

Class

Definition

A

class

definition is

written

in

the

form:

class

Classjname

:

SuperClass_l

:

SuperClass_2

:

{

type

declarator,

type

declarator,

type

declarator,

type

declarator,

};

where

Superclasses

are optional ancestor classes and

declarators

may

be

any

legal

ClassC

declaration;

particularly,

they

may be function

declarations

or object

declarations

(not

definitions).

The

parser

is

a

two

pass parser.

The

first

pass

just builds

a

list

of class names

from

the

class

definitions in

the

file.

No kind

oferror

checking

is done

at

this

stage.

The

second pass

is

the true

parse,

but

all

the

classes

defined in

the

file

are now

known

to the

compiler.

Thus,

aclass which

is

defined

anywhere

in

the

file

can

be

used anywhere

in

the

file.

This

allows

forward

referencing

inside

class

definitions,

so

that

class

A

can

be

defined

to

contain objects of class

B

while class

B

can

likewise

be defined

to

contain objects of class

A.

When

the

second pass of

the

parser encounters a class

definition,

it

first

processes all

the

declarations

within

the

body

of

the

definition.

The

variable

declarations

are

treated

just like

structure component

declarations

and are entered

into

a symbol

table

which

is

maintained

for

each

References

Related documents

Because pointer p is defined as a pointer variable which points to the two-dimensional array element, so p only can be assigned a element address, not a row address. I and j that

if suppose display() function is called with the help of class y object objectofy.display() then complier with pop up an error because when you inherit a classes base class

Otherwise, the calculated offset is used instead to index into the local address map for the object, which will contain the correct address of the required field.. The penalty for

The functions are not stored in memory assigned to the Actually, C++ uses the this keyword to access the pointer to the object acted on from inside the member

3: class object created, 4: IFactory interface called, 5: object created, 6: object interface pointer returned, [1],[2],[3]: calls to pIStat,. [4],[5]: calls

application (complete code) has a main features ,C++ provides all the advantages of 'C' and of object oriented programming and is suitable for embedded systems;

- If we want an object to look in the function table for the constructed class, not the variable type (often a base type) we make the function “virtual”. ▪a non-virtual method call

De nition: Refers to the place where a variable or function is created or assigned storage. Each external variable and function must be de ned exactly once in