#include <iostream>
#include <memory>
struct C { int * data; };
int main()
{
std::shared_ptr<int> p1;
std::shared_ptr<int> p2(nullptr);
std::shared_ptr<int> p3(new int);
std::cout << "p1: " << p1.use_count() << "\n"; // 0
std::cout << "p2: " << p2.use_count() << "\n"; // 0
std::cout << "p3: " << p3.use_count() << "\n"; // 1
std::shared_ptr<int> p4(new int, std::default_delete<int>());
std::shared_ptr<int> p5(new int, [](int*p) {delete p; }, std::allocator<int>());
std::shared_ptr<int> p6(p5);
std::cout << "p4: " << p4.use_count() << "\n"; // 1
std::cout << "p5: " << p5.use_count() << "\n"; // 2
std::cout << "p6: " << p6.use_count() << "\n"; // 2
std::shared_ptr<int> p7(std::move(p6));
std::cout << "p7: " << p7.use_count() << "\n"; // 2
std::cout << "p6: " << p6.use_count() << "\n"; // 0
std::shared_ptr<int> p8(std::unique_ptr<int>(new int));
std::shared_ptr<C> obj(new C);
std::shared_ptr<int> p9(obj, obj->data);
std::cout << "p8: " << p8.use_count() << "\n"; // 1
std::cout << "p9: " << p9.use_count() << "\n"; // 2
return 0;
}
use_count() 应该就是返回指向该内存的指针的数量。
获取指针的值
#include <iostream>
#include <memory>
int main()
{
int * p = new int(10);
std::shared_ptr<int> a(p);
if (a.get() == p)
{
std::cout << "a and p point to the same location\n";
}
std::cout << *a.get() << "\n";
std::cout << *a << "\n";
std::cout << *p << "\n";
return 0;
}
/*
output:
a and p point to the same location
10
10
10
*/
如果 use_count() == 1 返回true。否则返回false。
#include <iostream>
#include <memory>
int main()
{
std::shared_ptr<int> foo;
std::shared_ptr<int> bar(new int);
std::cout << "1 foo: " << foo.unique() << "\n"; // 0
std::cout << "1 bar: " << bar.unique() << "\n"; // 1
foo = bar;
std::cout << "2 foo: " << foo.unique() << "\n"; // 0
std::cout << "2 bar: " << bar.unique() << "\n"; // 0
bar = nullptr;
std::cout << "2 foo: " << foo.unique() << "\n"; // 1
std::cout << "2 bar: " << bar.unique() << "\n"; // 0
return 0;
}
重载bool运算符
#include <iostream>
#include <memory>
int main()
{
std::shared_ptr<int> foo;
std::shared_ptr<int> bar(new int(34));
if (foo) std::cout << "foo points to " << *foo << "\n";
else std::cout << "foo is null\n";
if (bar) std::cout << "bar points to " << *bar << '\n';
else std::cout << "bar is null\n";
return 0;
}
重载取值运算符
#include <iostream>
#include <memory>
int main()
{
std::shared_ptr<int> foo(new int);
std::shared_ptr<int> bar(new int(100));
*foo = *bar * 2;
std::cout << "foo: " << *foo << "\n"; //200
std::cout << "bar: " << *bar << "\n"; //100
return 0;
}
It returns the same value as get().
#include <iostream>
#include <memory>
struct C { int a; int b; };
int main()
{
std::shared_ptr<C> foo;
std::shared_ptr<C> bar(new C);
foo = bar;
foo->a = 10;
foo->b = 20;
std::cout << "foo: " << foo->a << " " << foo->b << "\n";
std::cout << "bar: " << bar->a << " " << bar->b << "\n";
return 0;
}
#include <iostream>
#include <memory>
int main()
{
std::shared_ptr<int> foo;
std::shared_ptr<int> bar(new int(10));
foo = bar; //copy
bar = std::make_shared<int>(20); //move
std::unique_ptr<int> unique(new int(30));
foo = std::move(unique); //move from unique_ptr
std::cout << "*foo: " << *foo << '\n'; //30
std::cout << "*bar: " << *bar << '\n'; //20
return 0;
}
#include <iostream>
#include <memory>
int main()
{
std::shared_ptr<int> sp;
sp.reset(new int);
*sp = 10;
std::cout << *sp << '\n'; //10
sp.reset(new int);
*sp = 20;
std::cout << *sp << '\n'; //20
sp.reset();
return 0;
}
#include <iostream>
#include <memory>
int main()
{
std::shared_ptr<int> foo(new int(10));
std::shared_ptr<int> bar(new int(20));
foo.swap(bar);
std::cout << "*foo: " << *foo << '\n'; //20
std::cout << "*bar: " << *bar << '\n'; //10
return 0;
}
#include <iostream>
#include <memory>
int main()
{
int * pInt = new int[100];
std::shared_ptr<int> sp1(pInt);
std::shared_ptr<int> sp2(pInt); //会Crash,因为内存被释放了两次。
return 0;
}
#include <iostream>
#include <memory>
class tester
{
public:
tester(){}
~tester() {}
std::shared_ptr<tester> getTester()
{
return std::shared_ptr<tester>(this);
}
};
int main()
{
tester t;
std::shared_ptr<tester> sp = t.getTester(); //会crash,析构函数释放了一次,shared_ptr释放了一次。
return 0;
}
要用enable_shared_from_this
Possible implementation in C++
#define NULL 0
//since C++11
#define NULL nullptr
Notes
In C, the macro NULL may have the type void*, but that is not allowed in C++.
#ifndef NULL
#ifdef __cplusplus
#define NULL 0 //c++中定义为0
#else
#define NULL ((void *)0) //c语言中定义为void*
#endif
#endif
NULL 问题
#include <cstddef>
#include <iostream>
void test(int i)
{
std::cout << "int i\n";
}
void test(int * i)
{
std::cout << "int * i\n";
}
int main()
{
test(0); //int i
test(NULL); //int i,在这里会被当做0来使用。
return 0;
}
#include <cstddef>
#include <iostream>
template<class F, class A>
void Fwd(F f, A a)
{
f(a);
}
void g(int * i)
{
std::cout << "Function g called\n";
}
int main()
{
g(NULL); //Function g called
g(0); //Function g called
Fwd(g, nullptr); //Function g called
//Fwd(g, NULL); //“void (int *)”: 无法将参数 1 从“int”转换为“int *”
}
#include <cstddef>
#include <iostream>
using namespace std;
void f(int* pi)
{
std::cout << "Pointer to integer overload\n";
}
void f(double* pd)
{
std::cout << "Pointer to double overload\n";
}
void f(std::nullptr_t nullp)
{
std::cout << "null pointer overload\n";
}
int main()
{
int* pi = NULL;
double* pd = NULL;
f(pi);
f(pd);
f(nullptr); // would be ambiguous without void f(nullptr_t)
// f(0); // ambiguous call: all three functions are candidates
// f(NULL); // ambiguous if NULL is an integral null pointer constant
// (as is the case in most implementations)
}
class nullptr_t
{
public:
template<class T>
inline operator T*() const //定义类型转换操作符,使nullptr_t 可转为任意非类成员指针类型
{ return 0; }
//重载类型转换操作符,使 nullptr_t 可以转换为类 C 中任意的指针类型(数据成员指针/函数成员指针)
//对类中数据成员的指针,T 将被推导为数据成员的类型 eg: int (X::*); 此时 T 为 int,C 为 X
//对类中函数成员的指针,T 将被推导为函数成员的类型 eg: int (X::*)(int); 此时T 等效于: typedef int (T)(int)
template<class C, class T>
inline operator T C::*() const
{ return 0; }
private:
void operator&() const;
};
const null_ptr nullptr = {}
#include <iostream>
#include <boost/array.hpp>
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
int main(int argc, char * argv[])
{
try
{
if (argc != 2)
{
std::cerr << "Usage: client <host>" << std::endl;
return 1;
}
boost::asio::io_service io_service;
tcp::resolver resolver(io_service);
tcp::resolver::query query(argv[1], "daytime");
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
tcp::socket socket(io_service);
boost::asio::connect(socket, endpoint_iterator);
for (;;)
{
boost::array<char, 128> buf;
boost::system::error_code error;
size_t len = socket.read_some(boost::asio::buffer(buf), error);
if (error == boost::asio::error::eof)
{
break;
}
else if (error)
{
throw boost::system::system_error(error);
}
std::cout.write(buf.data(), len);
}
}
catch (std::exception e)
{
std::cerr << "catch error: " << e.what() << std::endl;
}
return 0;
}
#include <ctime>
#include <iostream>
#include <string>
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
std::string make_daytime_string()
{
using namespace std;
time_t now = time(0);
return ctime(&now);
}
int main()
{
try
{
boost::asio::io_service io_service;
tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 13));
for (;;)
{
tcp::socket socket(io_service);
acceptor.accept(socket);
std::string message = make_daytime_string();
boost::system::error_code ignored_error;
boost::asio::write(socket, boost::asio::buffer(message), ignored_error);
}
}
catch (std::exception & e)
{
std::cerr << "catch error: " << e.what() << std::endl;
}
return 0;
}
#include <ctime>
#include <iostream>
#include <string>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
std::string make_daytime_string()
{
using namespace std;
time_t now = time(0);
return ctime(&now);
}
class tcp_connection
: public boost::enable_shared_from_this<tcp_connection>
{
public:
typedef boost::shared_ptr<tcp_connection> pointer;
static pointer create(boost::asio::io_service & io_service)
{
return pointer(new tcp_connection(io_service));
}
tcp::socket & socket()
{
return socket_;
}
void start()
{
message_ = make_daytime_string();
boost::asio::async_write(
socket_,
boost::asio::buffer(message_),
boost::bind(
&tcp_connection::handle_write,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
));
}
private:
tcp_connection(boost::asio::io_service & io_service)
: socket_(io_service)
{
}
void handle_write(const boost::system::error_code &, size_t)
{
}
tcp::socket socket_;
std::string message_;
};
class tcp_server
{
public:
tcp_server(boost::asio::io_service & io_service)
: acceptor_(io_service, tcp::endpoint(tcp::v4(), 13))
{
start_accept();
}
private:
void start_accept()
{
tcp_connection::pointer new_connection =
tcp_connection::create(acceptor_.get_io_service());
acceptor_.async_accept(
new_connection->socket(),
boost::bind(
&tcp_server::handle_accept,
this,
new_connection,
boost::asio::placeholders::error
)
);
}
void handle_accept(tcp_connection::pointer new_connection,
const boost::system::error_code & error)
{
if (!error)
{
new_connection->start();
}
start_accept();
}
tcp::acceptor acceptor_;
};
int main()
{
try
{
boost::asio::io_service io_service;
tcp_server server(io_service);
io_service.run();
}
catch (std::exception & e)
{
std::cerr << "catch error: " << e.what() << std::endl;
}
return 0;
}
项目右键点击–>属性–> C/C++ –> 常规 –> 附加包含目录
C:\local\boost_1_64_0
#include <boost/lambda/lambda.hpp>
#include <iostream>
#include <iterator>
#include <algorithm>
int main()
{
using namespace boost::lambda;
typedef std::istream_iterator<int> in;
std::for_each(
in(std::cin), in(), std::cout << (_1 * 3) << " "
);
}
项目右键点击–>属性–> C/C++ –> 常规 –> 附加包含目录
C:\local\boost_1_64_0
项目右键点击–>属性–> VC++ 目录 –> 库目录
C:\local\boost_1_64_0\lib32-msvc-14.0
#include <iostream>
#include <boost/asio.hpp>
#include <boost/thread/thread.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
class printer
{
public:
printer(boost::asio::io_service & io)
: strand_(io),
timer1_(io, boost::posix_time::seconds(1)),
timer2_(io, boost::posix_time::seconds(1)),
count_(0)
{
timer1_.async_wait(strand_.wrap(boost::bind(&printer::print1, this)));
timer2_.async_wait(strand_.wrap(boost::bind(&printer::print2, this)));
}
~printer()
{
std::cout << "Final count is " << count_ << std::endl;
}
void print1()
{
if (count_ < 10)
{
std::cout << "Timer 1: " << count_ << std::endl;
++count_;
timer1_.expires_at(timer1_.expires_at() + boost::posix_time::seconds(1));
timer1_.async_wait(strand_.wrap(boost::bind(&printer::print1, this)));
}
}
void print2()
{
if (count_ < 10)
{
std::cout << "Timer 2: " << count_ << std::endl;
++count_;
timer2_.expires_at(timer2_.expires_at() + boost::posix_time::seconds(1));
timer2_.async_wait(strand_.wrap(boost::bind(&printer::print2, this)));
}
}
private:
boost::asio::io_service::strand strand_;
boost::asio::deadline_timer timer1_;
boost::asio::deadline_timer timer2_;
int count_;
};
int main()
{
boost::asio::io_service io;
printer p(io);
boost::thread t(boost::bind(&boost::asio::io_service::run, &io));
io.run();
t.join();
return 0;
}
http://www.boost.org/doc/libs/1_64_0/doc/html/boost_asio/tutorial/tuttimer5.html
项目右键点击–>属性–> C/C++ –> 常规 –> 附加包含目录
C:\local\boost_1_64_0
项目右键点击–>属性–> VC++ 目录 –> 库目录
C:\local\boost_1_64_0\lib32-msvc-14.0
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
class printer
{
public:
printer(boost::asio::io_service & io)
: timer_(io, boost::posix_time::seconds(1)),
count_(0)
{
timer_.async_wait(boost::bind(&printer::print, this));
}
~printer()
{
std::cout << "Final count is " << count_ << std::endl;
}
void print()
{
if (count_ < 5)
{
std::cout << count_ << std::endl;
++count_;
timer_.expires_at(timer_.expires_at() + boost::posix_time::seconds(1));
timer_.async_wait(boost::bind(&printer::print, this));
}
}
private:
boost::asio::deadline_timer timer_;
int count_;
};
int main()
{
boost::asio::io_service io;
printer p(io);
io.run();
return 0;
}
http://www.boost.org/doc/libs/1_64_0/doc/html/boost_asio/tutorial/tuttimer4.html