Effective C++: 探智能指针(std::shared_ptr)和左值引用.

如果一个变量是以左值引用的形式引用的另外一个变量,那么当前变量的析构函数是不会执行的,只有被引用的变量的析构函数才会执行.

看代码:

 #include <iostream>
#include <memory>
template<typename T>
class Node{
 public:
  T key_;
  
  template<typename Ty>
  Node(const Ty& key);
  
  Node()=default;
  
  template<typename Ty>
  Node(Node<Ty>* node_ptr_);
  
  ~Node(){ std::cout<<"destroy"<<std::endl; }
};
template<typename T>
template<typename Ty>
Node<T>::Node(const Ty& key)
        :key_(key)
{
 std::cout<<"constructor"<<std::endl;
}
template<typename T>
template<typename Ty>
Node<T>::Node(Node<Ty>* node_ptr_)
        :key_(node_ptr_->key_)
{
 std::cout<<"for shared_ptr"<<std::endl;
}
template<typename T>
class Edge{
 private:
  std::shared_ptr<Node<T>> start_;
  std::shared_ptr<Node<T>> end_;
  
  public:
   template<typename Ty>
   Edge(const Ty& first_, const Ty& second_);
   
   template<typename Ty>
   Edge(const Node<Ty>& node_first_, const Node<Ty>& node_second_);
   
   Edge(const Edge<T>& other_);
   
   Edge<T>& operator=(const Edge<T>& other_);
   
   Edge()=default;
   
   void get_count()const
   {
    std::cout<<"start_: "<<this->start_.use_count()<<std::endl;
    std::cout<<"end_: "<<this->end_.use_count()<<std::endl;
   }
   
   ~Edge();
};
template<typename T>
template<typename Ty>
Edge<T>::Edge(const Ty& first_, const Ty& second_)
        :Edge(Node<Ty>(first_), Node<Ty>(second_))
{
 std::cout<<"entrust"<<std::endl;
}
template<typename T>
template<typename Ty>
Edge<T>::Edge(const Node<Ty>& node_first_, const Node<Ty>& node_second_)
        :start_(std::make_shared<Node<Ty>>(node_first_)),
         end_(std::make_shared<Node<Ty>>(node_second_))
{
 std::cout<<"make_shared"<<std::endl;
}
template<typename T>
Edge<T>::~Edge()
{
 std::cout<<"before: "<<std::endl;
 std::cout<<"start_count: "<<this->start_.use_count()<<std::endl;
 std::cout<<"end_count: "<<this->end_.use_count()<<std::endl;
 
 this->start_.reset();
 this->end_.reset();
 
 std::cout<<"out of destroy"<<std::endl;
}
template<typename T>
Edge<T>::Edge(const Edge<T>& other_)
        :start_(other_.start_),
         end_(other_.end_)
{
 //
 std::cout<<"ccccccccccccccc--------ccccccccc"<<std::endl;
}
template<typename T>
Edge<T>& Edge<T>::operator=(const Edge<T>& other_)
{
 this->start_ = other_.start_;
 this->end_ = other_.end_;
 
 std::cout<<"o---------------------------ccccc"<<std::endl;
 return *this;
}
void test_function() //注意这里. 
{
 //这个里面有两个Edge而且first是拷贝的second,一次其中的shared_ptr的引用计数为2
 //但是在该函数结束的时候first先执行析构函数引用计数变成1,
 //然后second再执行引用计数变成了0,内存也就被释放了! 
 Edge<int> first(10, 20);
 Edge<int> second;
 second = first;
 std::cout<<"out of test_function"<<std::endl;
 std::cout<<"-------------------"<<std::endl;
}
Edge<int> function()
{
 Edge<int> edge(30, 40);
 std::cout<<"before return"<<std::endl;
 return edge;
}
Edge<int> refence(const Edge<int>& ref)
{
 std::cout<<"enter refence"<<std::endl;
 ref.get_count();
 
 return ref;
}
int main()
{
 test_function(); //析构函数执行了2次 因为函数内的两个edge是拷贝的关系. 
 
 /*std::cout<<".................................."<<std::endl;
 Edge<int> first = function();
 std::cout<<".................................."<<std::endl;*/
 
 /*std::cout<<"开始"<<std::endl;
 Edge<int> second(50, 60);
 Edge<int> third = refence(second);
 third.get_count();*/
 
 //Edge<int> forth(70, 80);
 //Edge<int>& fifth = forth; //析构函数只执行了一次。因为fifth是引用的forth所以只有forth的析构函数执行了. 
 
 return 0;
}

转载于:https://my.oschina.net/SHIHUAMarryMe/blog/637855

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值