new and delete.
const unsigned mu_population = 24000 static personnel_record[mu_population]
struct C {
data * data_ptr;
C() : data_ptr(new data) { }
};
static void t(void) { C c; }

struct C {
data * data_ptr;
C() : data_ptr(new data) { }
~C() { delete data_ptr; }
};

struct C {
data * data_ptr;
C() : data_ptr(new data) { }
~C() { delete data_ptr; }
};
static void t(C & c) { C local_c(c); }

void t(C c) {...}
The call t(c) makes a copy of c.
C::C(const C &).
&.
struct C {
data * data_ptr;
C() : data_ptr(new data) { }
~C() { delete data_ptr; }
C(const C & c)
: data_ptr(new data(*(c.data_ptr))) {...}
};

struct C
data * data_ptr;
C() : data_ptr(new data) { }
~C() { delete data_ptr; }
C(const C & c)
: data_ptr(new data(*(c.data_ptr))) {...}
static void t(C & c) {C local_c; local_c = c;}

local_c.data_ptr is garbage.
local_c.data_ptr and c.data_ptr are sharing storage.
=.
=.
struct C
data * data_ptr;
C() : data_ptr(new data) {...}
C(const C & c)
: data_ptr(new data(*c.data_ptr)) {...}
~C() { delete data_ptr; }
// Bad example.
C & operator = (const C & c) {
delete data_ptr;
data_ptr = new data(*c.data_ptr);
return *this;
}

c = c is a self-assignment.
c = c?

C & C::operator = (const C & rhs) {
delete data_ptr;
data_ptr = copy_data(rhs.data_ptr);
return *this;
}
c = c, *this = rhs.
data_ptr deletes rhs.data_ptr.
*this is different from rhs.
*this and rhs are different,
proceed as normal.
*this and rhs are the same, do nothing.
C & C::operator = (const C & rhs) {
if (this != &rhs) {
delete data_ptr;
data_ptr = new data(*(rhs.data_ptr));
}
return *this;
}
x = y = z = 0.0;
if ((ch = getch()) != EOF) ...
T & operator = (const T & rhs)
*this.
C c2 = c1;
and
c2 = c1;
Or maybe apos(there, s) no difference?
copying constructing defines an undefined instance.
C c2(c1);
class blob {
public:
~blob() { delete(); }
blob(const blob & b) { copy(b); }
blob & operator = (const & blob b)
{ if (&b != this) { delete(); copy(b); } }
private:
void copy(const & blob b) {...}
void delete() {...}
};
If a class implements a destructor, a copy constructor, or an assignment operator, then it needs to implement all three.
A class with pointer instance variables must have a destructor, a copy constructor, and an assignment operator.
template <typename T>
class binary_tree {
public:
void add(const T & value);
binary_tree();
bool find(const T & value);
void remove(const T & value);
};
template <typename T>
class binary_tree {
private:
struct node {
T value;
node * left, * right;
};
node * root;
};
struct node {
T value;
node * left, * right;
};
node is a private class, managed privately.
node n, always node * n.
node * values.
class node {
public:
T value;
node * left, * right;
private:
~node() { }
node(const node &) { }
node & operator = (const node &)
{ return *this; }
};
node * root; node root;
t.cc:27: error: 'binary_tree::node::~node() [with T = int]' is private t.cc:2: error: within this context
template <typename T>
class binary_tree {
private:
class node { . . . };
node * root;
};
template <typename T>
class binary_tree {
private:
node * get_node();
void ret_node(node *);
get_node() and ret_node() explode on errors.
template <typename T>
void binary_tree<T>::
add(const T & value) {
node * const n = get_node();
n→value = value;
n→right = 0;
n→left = root;
root = n;
}
private: static const unsigned node_count = 10000; node nodes[node_count];
get_node() and ret_node() work?
get_node() needs to distinguish between nodes being used and nodes
available for allocation.
struct node {
T value;
node * left, * right;
bool free;
};
for (i = 0; i < node_count; i++) nodes[i].free = true;
get_node()):
for (i = 0; i < node_count; i++)
if (nodes[i].free) { ... }
// explode
ret_node()):
node→free = true;
const unsigned node_count = 10000; node nodes[node_count]; node * free_nodes;

for (i = 1; i < node_count; i++) nodes[i - 1].left = &nodes[i]; free_nodes = nodes; nodes[node_count - 1].left = 0;
get_node()):
if (free_nodes) { ... }
// explode
ret_node()):
n->left = free_nodes; free_nodes = n;
template
<typename T, unsigned node_count = 512>
class binary_tree {
private:
node nodes[node_count];
};
binary_tree<int, 100> ibt; binary_tree<std::string> sbt;
get_node() {
return new node;
}
ret_node(node * n) {
delete n;
}
| int | point | |||
|---|---|---|---|---|
| static | 0.02 | 0.05 | ||
| simple | 0.1 | 0.1 | ||
| free list | 0.03 | 0.07 | ||
| block | 0.02 | 0.05 |