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 |