I am currently in the process of expanding my knowledge in C++. For this, I am coding a template Network. (The actual exercise is Project Euler's problem 107, if someone is interested.)
Now reading up about pointers in C++11, the following design for my class looks plausible:
template< typename T, size_t D >
class Network<T,D>
{
public:
Network();
~Network();
bool add_edge( size_t, size_t, T );
bool remove_edge( size_t, size_t );
struct Node;
struct Edge;
private:
vector<Node> network;
};
with the following preliminary implementation
template< typename T, size_t D >
struct Network<T,D>::Edge
{
pair<shared_ptr<Node>,shared_ptr<Node>> vertices;
T weight;
}
template< typename T, size_t D >
struct Network<T,D>::Node
{
Node( size_t idx )
index = idx;
size_t index;
vector<shared_ptr<Edge>> connections;
};
template< typename T, size_t D >
Network<T,D>::Network( )
{
network.reserve( D );
for( size_t s = 0; s <= D; s++ )
network.push_back( Node(s) );
}
template< typename T, size_t D >
Network<T,D>::~Network() {}
Please be aware, this is just preliminary code; i haven't compiled anything yet.
However, the following questions arise:
std::shared_ptr
? Using it to count references from Edge
s to Node
s would make it easy to determine whether a node is isolated.In my model, might it be possible to exchange std::shared_ptr
with std::weak_ptr
?
As far as I understand, no. In Edge
, the shared_ptr<Node>
is necessary to actually be able to count references, in my Node
s the shared_ptr<Edge>
is necessary to actually keep referring to an Edge and not lose it.
To a lesser extent, does using size_t D
make sense for my template? (Apart from the small likelihood of using this model with multi-terabyte computers for addressing huge networks...)
Even if this might attract opinionated answers, I'd be open to design alternatives.
I would say shared_ptr
or any other smart pointer is a wrong tool here. Because:
shared_ptr
involves allocating the control block (where the reference counter and the deleter are stored) on the heap. shared_ptr
size is that of two pointers. Reference counter maintenance involves atomic instructions, which introduce unnecessary latency in single-threaded use-cases. In other words, shared_ptr
is one of the most expensive pointers available.