Composition
syntax
Actually,
you’ve been using composition all along to create classes. You’ve
just been composing classes using built-in types. It turns out to be almost as
easy to use composition with user-defined types.
Consider
an existing class that is valuable for some reason:
//: C14:Useful.h
// A class to reuse
#ifndef USEFUL_H
#define USEFUL_H
class X {
int i;
enum { factor = 11 };
public:
X() { i = 0; }
void set(int ii) { i = ii; }
int read() const { return i; }
int permute() { return i = i * factor; }
};
#endif // USEFUL_H ///:~
The
data members are
private
in this class, so it’s completely safe to embed an object of type
X
as a
public
object in a new class, which makes the interface straightforward:
//: C14:Compose.cpp
// Reuse code with composition
#include "Useful.h"
class Y {
int i;
public:
X x; // Embedded object
Y() { i = 0; }
void f(int ii) { i = ii; }
int g() const { return i; }
};
int main() {
Y y;
y.f(47);
y.x.set(37); // Access the embedded object
} ///:~
Accessing
the member functions of the embedded object
(referred to as a
subobject)
simply requires another member selection.
It’s
probably more common to make the embedded objects
private,
so they become part of the underlying implementation (which means you can
change the implementation if you want). The
public
interface functions for your new class then involve the use of the embedded
object, but they don’t necessarily mimic the object’s interface:
//: C14:Compose2.cpp
// Private embedded objects
#include "Useful.h"
class Y {
int i;
X x; // Embedded object
public:
Y() { i = 0; }
void f(int ii) { i = ii; x.set(ii); }
int g() const { return i * x.read(); }
void permute() { x.permute(); }
};
int main() {
Y y;
y.f(47);
y.permute();
} ///:~
Here,
the
permute( )
function is carried through to the new class interface, but the other member
functions of
X
are used within the members of
Y.
Go to CodeGuru.com
Contact: webmaster@codeguru.com
© Copyright 1997-1999 CodeGuru