C++の最上位constと最上位constおよびアナログスマートポインタ.
7967 ワード
#include <iostream>
#include <memory>
/* const :
Node<int> = const Node<int>& , Node<int> = Node<int>&.
: Node(const Node<int>&) operator=(const Node<int>&).
Node(Node<int>&) operator=(Node<int>&) .
*/
template<typename T>
class Node{
private:
T* key_ptr;
mutable unsigned int counter_; // . mutable, Node const .
public:
template<typename Ty>
explicit Node(const Ty& key_); //explicit: .
Node();
Node(const Node<T>& other_node_);
template<typename Ty>
Node(Node<Ty>&& other_node_);
Node<T>& operator=(const Node<T>& other_node_);
template<typename Ty>
Node<Ty>& operator=(Node<Ty>&& other_node);
T* get_key_ptr()const noexcept; // const.
operator T*()const noexcept;
~Node();
};
template<typename T>
Node<T>::Node()
:key_ptr(nullptr),
counter_(1)
{
//default constructor.
}
template<typename T>
template<typename Ty>
Node<T>::Node(const Ty& key_)
:key_ptr(new Ty(key_)),
counter_(1)
{
//constructor.
}
template<typename T>
template<typename Ty>
Node<T>::Node(Node<Ty>&& other_node_)
{
if(this->counter_ == 1){
delete key_ptr;
this->key_ptr = nullptr;
}
this->key_ptr = other_node_.key_ptr;
this->counter_ = other_node_.counter_;
other_node_.counter = 0;
}
template<typename T>
Node<T>::Node(const Node<T>& other_node_)
{
if(--(this->counter_) == 0){
delete key_ptr;
this->key_ptr = nullptr;
}
other_node_.counter_ += 1;
this->counter_ = other_node_.counter_;
}
template<typename T>
template<typename Ty>
Node<Ty>& Node<T>::operator=(Node<Ty>&& other_node_)
{
if(--(this->counter_) == 0){
delete key_ptr;
this->key_ptr = nullptr;
}
this->key_ptr = other_node_.key_ptr;
this->counter_ = other_node_.counter_;
other_node_.counter_ = 0;
other_node_.key_ptr = nullptr;
return *this;
}
template<typename T>
Node<T>& Node<T>::operator=(const Node<T>& other_node_)
{
if(--(this->counter_) == 0){
delete key_ptr;
this->key_ptr = nullptr;
}
other_node_.counter_ += 1;
this->key_ptr = other_node_.key_ptr;
this->counter_ = other_node_.counter_;
return *this;
}
template<typename T>
T* Node<T>::get_key_ptr()const noexcept
{
return this->key_ptr;
}
template<typename T>
Node<T>::operator T*()const noexcept
{
return this->key_ptr;
}
template<typename T>
Node<T>::~Node()
{
if(this->key_ptr = nullptr){
return;
}
--(this->counter_);
if(this->counter_ == 0){
delete key_ptr;
this->counter_ = 0;
this->key_ptr = nullptr;
}
}
template<typename T>
void function(const Node<T>& node) // const : node key_ptr T* const.
{
T* ptr = node.get_key_ptr(); // get_key_ptr .
std::cout<<"The contents of key_ptr: "<<*ptr;
//delete ptr; // delete node key_ptr .
}
template<typename T>
class Edge{
private:
int number_;
public:
template<typename Ty>
Edge(const Ty& number);
Edge();
const int& get_mem()const;
~Edge()=default;
};
template<typename T>
template<typename Ty>
Edge<T>::Edge(const Ty& number)
:number_(number)
{
//
}
template<typename T>
const int& Edge<T>::get_mem()const // const, (const int&) const. const.
{
return this->number_;
}
int main()
{
Node<int> first_(10);
Node<int> second_;
second_ = first_; //first key_ptr delete .
//function(first_); // .
const Node<int> third_(30); //third_ key_ptr :T* const.
int* ptr = third_.get_key_ptr();
std::cout<<*ptr<<std::endl;
int* const first_ptr = new int(2);
int* second_ptr = first_ptr; //ok. int* = int* const.
second_ptr = nullptr;
delete first_ptr;
const int* third_ptr = new int(3);
//int* forth_ptr = third_ptr; // : const int* = int*.
delete third_ptr;
Node<int> forth_(40);
if(forth_ != nullptr){ // operator T*().
std::cout<<"successfully!"<<std::endl;
}
Edge<int> edge_one(1);
int one = edge_one.get_mem(); // : int& = const int&.
const int& two = 0; //const int& = int
const int& three = one; //const int& = int
int four = three; //int = const int&
// :Node<int> = const Node<int>&
// Node<int> = Node<int>&
Node<int> fifth_(50);
const Node<int>& sixth_ (Node<int>(60)); // .
Node<int>& seventh_ = fifth_;
Node<int> eighth_ = sixth_;
Node<int> ninth_ = seventh_;
return 0;
}
2016/3/24:
より良いソリューション
#include <iostream>
#include <memory>
template<typename T>
class Node{
private:
std::shared_ptr<T> key_ptr_;
public:
Node()=default;
template<typename Ty>
explicit Node(const Ty& key_);
Node(const Node<T>& other_node_);
template<typename Ty>
Node(Node<Ty>&& other_node_);
Node<T>& operator=(const Node<T>& other_node_);
template<typename Ty>
Node<Ty>& operator=(Node<Ty>&& other_node_);
void print()const;
~Node();
};
template<typename T>
template<typename Ty>
Node<T>::Node(const Ty& key_)
:key_ptr_(std::make_shared<Ty>(key_))
{
//
}
template<typename T>
Node<T>::Node(const Node<T>& other_node_)
:key_ptr_(other_node_.key_ptr_)
{
//
}
template<typename T>
template<typename Ty>
Node<T>::Node(Node<Ty>&& other_node_)
:key_ptr_(other_node_.key_ptr_)
{
(other_node_.key_ptr_).reset(nullptr); // key_ptr_ +1, reset(nullptr) -1.
}
template<typename T>
Node<T>& Node<T>::operator=(const Node<T>& other_node_)
{
this->key_ptr_ = other_node_.key_ptr_;
return *this;
}
template<typename T>
template<typename Ty>
Node<Ty>& Node<T>::operator=(Node<Ty>&& other_node_)
{
this->key_ptr_ = other_node_.key_ptr_;
(other_node_.key_ptr).reset();
return *this;
}
template<typename T>
Node<T>::~Node()
{
if(this->key_ptr_ == nullptr){
return;
}
std::cout<<"counter: "<<(this->key_ptr_).use_count();
(this->key_ptr_).reset();
}
template<typename T>
void Node<T>::print()const
{
std::cout<<*(this->key_ptr_)<<std::endl;
}
template<typename T>
void function(Node<T> node) //copy node.
{
node.print();
}
int main()
{
Node<int> first_(10);
Node<int>& second_ = first_;
function(second_);
return 0;
}