码迷,mamicode.com
首页 > 其他好文 > 详细

a review at operator overloading(3)

时间:2021-01-08 11:22:07      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:cat   delete   struct   成员   rev   目的   ons   share   code   

终于到了shared ptr

首先看一下std::make_shared

  • 可能有人不知道std::pair是什么,接下来的例子是和std::pair有关系的, first和second是第一个成员和第二个成员,然后我们可以发现,第一个first和第二个second竟然可以不一样
// make_pair example
#include <utility>      // std::pair
#include <iostream>     // std::cout

int main () {
  std::pair <int,int> foo;
  std::pair <int,int> bar;

  foo = std::make_pair (10,20);
  bar = std::make_pair (10.5,‘A‘); // ok: implicit conversion from pair<double,char>

  std::cout << "foo: " << foo.first << ", " << foo.second << ‘\n‘;
  std::cout << "bar: " << bar.first << ", " << bar.second << ‘\n‘;

  return 0;
}
// pair::operator= example
#include <utility>      // std::pair, std::make_pair
#include <string>       // std::string
#include <iostream>     // std::cout

int main () {
  std::pair <std::string,int> planet, homeplanet;

  planet = std::make_pair("Earth",6371);

  homeplanet = planet;

  std::cout << "Home planet: " << homeplanet.first << ‘\n‘;
  std::cout << "Planet size: " << homeplanet.second << ‘\n‘;
  return 0;
}
  • 我们发现里面有 std::shared_ptr foo = std::make_shared (10); same as: std::shared_ptr foo2 (new int(10)); 这个东西,也就是说我们要注意两种形式的构造
// make_shared example
#include <iostream>
#include <memory>

int main () {

  std::shared_ptr<int> foo = std::make_shared<int> (10);
  // same as:
  std::shared_ptr<int> foo2 (new int(10));

  auto bar = std::make_shared<int> (20);

  auto baz = std::make_shared<std::pair<int,int>> (30,40);

  std::cout << "*foo: " << *foo << ‘\n‘;
  std::cout << "*bar: " << *bar << ‘\n‘;
  std::cout << "*baz: " << baz->first << ‘ ‘ << baz->second << ‘\n‘;

  return 0;
}

接下来是 allocate_shared

  • 文档里有说 This function uses alloc to allocate storage for the object. A similar function, make_shared uses ::new to allocate the storage instead. 这个是用alloc分配的
// allocate_shared example
#include <iostream>
#include <memory>

int main () {
  std::allocator<int> alloc;    // the default allocator for int
  std::default_delete<int> del; // the default deleter for int

  std::shared_ptr<int> foo = std::allocate_shared<int> (alloc,10);

  auto bar = std::allocate_shared<int> (alloc,20);

  auto baz = std::allocate_shared<std::pair<int,int>> (alloc,30,40);

  std::cout << "*foo: " << *foo << ‘\n‘;
  std::cout << "*bar: " << *bar << ‘\n‘;
  std::cout << "*baz: " << baz->first << ‘ ‘ << baz->second << ‘\n‘;

  return 0;
}

接下来是std::static_pointer_cast

// static_pointer_cast example
#include <iostream>
#include <memory>

struct A {
  static const char* static_type;
  const char* dynamic_type;
  A() { dynamic_type = static_type; }
};
struct B: A {
  static const char* static_type;
  B() { dynamic_type = static_type; }
};

const char* A::static_type = "class A";
const char* B::static_type = "class B";

int main () {
  std::shared_ptr<A> foo;
  std::shared_ptr<B> bar;

  foo = std::make_shared<A>();

  // cast of potentially incomplete object, but ok as a static cast:
  bar = std::static_pointer_cast<B>(foo);

  std::cout << "foo‘s static  type: " << foo->static_type << ‘\n‘;
  std::cout << "foo‘s dynamic type: " << foo->dynamic_type << ‘\n‘;
  std::cout << "bar‘s static  type: " << bar->static_type << ‘\n‘;
  std::cout << "bar‘s dynamic type: " << bar->dynamic_type << ‘\n‘;

  return 0;
}
  • 输出:
foo‘s static  type: class A
foo‘s dynamic type: class A
bar‘s static  type: class B
bar‘s dynamic type: class A
  • 首先,const char* a::static_type = ‘class a‘, 静态区成员a::static_type是 ‘class a‘,
  • 然后,const char* b::static_type = ‘class b‘,静态区成员b::static_type是 ‘class b‘,
  • 然后执行 std::shared_ptr< A > foo; std::shared_ptr< B > bar,bar和foo这两个现在是null了
  • 然后执行 foo = std::make_shared< A >() ,构造函数使得foo的:const char* dynamic_type 等于 ‘class a‘,
  • 执行 bar=std::static_pointer< B >(foo), static_cast使得:bar为foo的值,所以bar是foo了
  • 所以foo的值是:一个a::static_type是class a,一个dynamic type是class a
  • bar是foo,bar的dynamic type是foo的dynamic type是a
  • bar的static type没有变,因为bar的static type并不是foo的static type,即使bar变成了foo,也只是非静态区变了,静态区没变
  • 真是太难了。。。

dynamic_pointer_cast 待更

智能指针的const cast

  • 虽然cpp官网上对于普通指针的const cast讲解例子只写了如何去除一个const,但是它有明确的说一点"either to be set or to be removed",所以我们可以猜出,去除 / 添加一个const在智能指针里也是合法的
// static_pointer_cast example
#include <iostream>
#include <memory>

int main () {
  std::shared_ptr<int> foo;
  std::shared_ptr<const int> bar;

  foo = std::make_shared<int>(10);

  bar = std::const_pointer_cast<const int>(foo);

  std::cout << "*bar: " << *bar << ‘\n‘;
  *foo = 20;
  std::cout << "*bar: " << *bar << ‘\n‘;

  return 0;
}
  • 这个例子里,是说如何把一个int* 变成 const int * , c++ 的const cast大部分情况下是可以按照你预期的结果正常工作的,但是也有些许例外,这取决于如何声明、编译器如何优化。上面的例子里,输出结果是10和20

get_deleter

// get_deleter example
#include <iostream>
#include <memory>

struct D {    // a verbose array deleter:
  void operator()(int* p) {
    std::cout << "[deleter called]\n";
    delete[] p;
  }
};

int main () {
  std::shared_ptr<int> foo (new int[10],D());

  int * bar = new int[20];

  // use foo‘s deleter to delete bar (which is unmanaged):
  (*std::get_deleter<D>(foo))(bar);

  return 0;
  // foo‘s deleter called automatically
}
  • 首先这个例子初始化了一个有10单位长度智能指针,由于它声明的是int,然后第一个参数是一个int[],所以普通的std deleter是不管用的,因为只删除首地址,所以要自定义删除器D
struct D {
    void operator()(int* p) {
        std::cout << "";
        delete[] p;
    }
}
  • 注意是谁delete[] p,这是手动构造删除器的目的
  • 但是下面还有一个int * bar = new int [20]这个东西
  • 然后我们用std::get_deleter< D > (foo) 可以删除foo,这个类型是一个删除器指针
  • 于是,我们可以连续指针操作:
(*std::get_deleter<D>(foo)) // 还是一个删除器
  • 于是继续
  (*std::get_deleter<D>(foo))(bar); // 删除bar
  • 网上有很多深刻的讨论关于为什么智能指针有两种获取deleter的方式,我觉得我是看不懂了,大概是unique的要设计成模版,为了保持低内存而不把deleter当作类内的一部分,shared并不太过care内存,所以两种获取方式也就可以理解了。

swap

  • swap是重载的函数
// shared_ptr swap specialization
#include <iostream>
#include <memory>

int main () {
  std::shared_ptr<int> foo (new int(10));
  std::shared_ptr<int> bar (new int(20));

  swap(foo,bar);

  std::cout << "foo: " << *foo << ‘\n‘;
  std::cout << "bar: " << *bar << ‘\n‘;

  return 0;
}

operator <<

// shared_ptr i/o
#include <iostream>
#include <memory>

int main () {
  std::shared_ptr<int> foo (new int (10));

  std::cout << " foo: " << foo << ‘\n‘;
  std::cout << "*foo: " << *foo << ‘\n‘;

  return 0;
}

输出结果是

 foo: 0x920d90
*foo: 10
  • 注:我还没有试过unique ptr是否有 << 的 operator overloading ,反正文档上没有

relational operator

  • 不写了

上述的所有东西统统都不是类函数。待更。。这太难学了

a review at operator overloading(3)

标签:cat   delete   struct   成员   rev   目的   ons   share   code   

原文地址:https://www.cnblogs.com/sjl473/p/14243379.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!