1.A default initialized smart pointer holds a null pointer.
shared_ptr<vector<string>> p; // shared_ptr that can point at a vector of string.
2.Using make_shared function allocates and initializes an object in dynamic memeory and returns a shared ptr hat points to that object.
auto p = make_shared<vector<string>>(10,'9'); // P points to a string with value 9999999999.
3.Initializing a smart ptr from a pointer returned by new.
shared_ptr<int> p1 = new int(1024); // error:must use direct initialization.(not copy initialization) shared_ptr<int> p2(new int(1024)); // ok:uses direct initialization. shared_ptr<int> clone(int p){ return new in(p); // error:implicit conversion to shared_ptr<int>. } shared_ptr<int> clone(int p){ return shared_ptr<int>(new in(p)); // ok:explicitly create a shared_ptr<int> from int*. }
1.We can think of a shared_ptr as if it has an associated counter, usually referred to as a reference count.
Counter incremented when:
Once a shared ptr's counter goes to zero, the shared_ptr automatically frees the object that it manages.
Memory is not freed until the last shared_ptr goes away.
1.Each vector "owns" its own elememts. When we copy a vector, the elements in the original vector and in the copy are separate from one another.
vector<string> v1; { // new scope. vector<string> v2 = {"a", "an", "the"}; v1 = v2; // copies the elements from v2 into v1. } // v2 is destroyed, which destroys the elements in v2. // v1 has three elements, which are copies of the ones originally in v2.
2.Use dynamic memory to allow multiple objects to share the same state(data).
#ifndef MY_STRBLOB_H #define MY_STRBLOB_H #include <vector> #include <string> #include <initializer_list> #include <memory> #include <stdexcept> using namespace std; class StrBlob { public: typedef vector<string>::size_type size_type; StrBlob(); StrBlob(initializer_list<string> il); // initializer_list is a library type that represents // an array of values of the specified type. size_type size() const { return data->size(); } bool empty() const { return data->empty(); } void push_back(const string& t) { data->push_back(t); } void pop_back(); string& front(); string& back(); private: shared_ptr<vector<string>> data; void check(size_type i, const string& msg) const; }; StrBlob::StrBlob(): data(make_shared<vector<string>>()){} StrBlob::StrBlob(initializer_list<string> il): data(make_shared<vector<string>>(il)){} void StrBlob::check(size_type i, const string& msg) const { if (i >= data->size()) throw out_of_range(msg); } string& StrBlob::front() { check(0, "front on empty StrBlob"); return data->front(); } string& StrBlob::back() { check(0, "back on empty StrBlob"); return data->back(); } void StrBlob::pop_back() { check(0, "pop_back on empty StrBlob"); data->pop_back(); } #endif // !MY_STRBLOB_H
#include <iostream> #include "Strblob.h" int main() { StrBlob b1; { StrBlob b2 = { "a","an","the" }; b1 = b2; b2.push_back("about"); cout << b2.size() << endl; } cout << b1.size() << endl; cout << b1.front() << " " << b1.back() << endl; StrBlob b3 = b1; cout << b3.front() << " " << b3.back() << endl; return 0; } // output: // 4 // 4 // a about // a about