拷贝、赋值与销毁(1)
13.1.1拷贝构造函数
/************************************** 13.1.1拷贝构造函数 **************************************/ class Foo1 { public: Foo1(); //默认构造函数 Foo1(const Foo1&); //拷贝构造函数 //... };
注意:拷贝构造函数的第一个参数必须是一个参数
合成拷贝构造函数
/************************************** 合成拷贝构造函数 **************************************/ class Sales_data { friend Sales_data add(const Sales_data&, const Sales_data&); friend ostream &print(ostream&, const Sales_data&); friend istream &read(istream&, Sales_data&); public: // constructors Sales_data(): units_sold(0), revenue(0.0) { } Sales_data(const string &s): bookNo(s), units_sold(0), revenue(0.0) { } Sales_data(const string &s, unsigned n, double p): bookNo(s), units_sold(n), revenue(p*n) { } Sales_data(istream &); // operations on Sales_data objects string isbn() const { return bookNo; } Sales_data& combine(const Sales_data&); double avg_price() const; /* 与合成的拷贝构造函数等价的拷贝构造函数的声明 */ Sales_data(const Sales_data&); Sales_data& operator=(const Sales_data&); //赋值运算符 ~Sales_data(){} private: string bookNo; int units_sold=0; double revenue=0.0; }; //与Sales_data的合成的拷贝构造函数等价 Sales_data::Sales_data(const Sales_data &orig):bookNo(orig.bookNo), units_sold(orig.units_sold),revenue(orig.revenue){} // nonmember Sales_data interface functions Sales_data add(const Sales_data&, const Sales_data&); ostream &print(ostream&, const Sales_data&); istream &read(istream&, Sales_data&); // used in future chapters inline bool compareIsbn(const Sales_data &lhs, const Sales_data &rhs) { return lhs.isbn() < rhs.isbn(); }
这个类其实在前面第七章就说过了,只是前面那个没有拷贝构造函数,拷贝赋值运算符,析构函数数而已
拷贝初始化
/************************************** 拷贝初始化 **************************************/ void fun1() { string dots(10, '.'); //直接初始化 string s(dots); //直接初始化 string s2=dots; //拷贝初始化 string null_book="9-999-99999-9"; //拷贝初始化 string nines=string(100, '9'); //拷贝初始化 }
拷贝初始化不仅在我们用=定义变量时会发生,在下列情况下也会发生
*将一个对象作为实参传递给一个非引用类型的形参
*从一个返回类型为非引用类型的函数返回一个对象
*用花括号列表初始化一个数组中的元素或一个聚合类中的成员
拷贝初始化的限制
/** 拷贝初始化的限制 */ void fun2() { vector<int> v1(10); //正确:直接初始化 // vector<int> v2=10; //错误:接受大小参数的构造函数式explicit的 void f(vector<int>); //f的参数进行拷贝初始化 // f(10); //错误:不能用一个explicit的构造函数拷贝一个实参 // f(vector<int>(10)); //正确:从一个int直接构造一个临时的vector }
13.1.2拷贝赋值运算符
/************************************** 13.1.2拷贝赋值运算符 **************************************/ void fun3() { Sales_data trans, accum; trans=accum; //使用Sales_data的拷贝赋值运算符 }
重载赋值运算符
/** 重载赋值运算符 */ class Foo2 { public: Foo2& operator=(const Foo2&); //赋值运算符 //... };
合成拷贝赋值运算符
/** 合成拷贝赋值运算符 */ Sales_data& Sales_data::operator=(const Sales_data &rhs) { bookNo=rhs.bookNo; //调用string::operator= units_sold=rhs.units_sold; //使用内置的int赋值 revenue=rhs.revenue; //使用内置的double赋值 return *this; //返回一个此对象的引用 }
13.1.3析构函数
/************************************** 13.1.3析构函数 **************************************/ class Foo3 { public: ~Foo3(); //析构函数 //... };
析构函数自动运行,我们的程序可以按需要分配资源,无需担心何时释放这些资源
void fun4() { //p和p2指向动态分配的对象 Sales_data *p=new Sales_data; //p是一个内置指针 auto p2=shared_ptr<Sales_data>(); //p2是一个shared_ptr Sales_data item(*p); //拷贝构造函数吧*p拷贝到item中 vector<Sales_data> vec; //局部对象 vec.push_back(*p2); //拷贝p2指向的对象 delete p; //对p指向的对象执行析构函数 } //退出局部作用域;对item,vec,p2调用析构函数 //销毁p2会递减其引用计数;如果引用计数变为0,对象被释放 //销毁vec会销毁它的元素
FOO类
//Foo类 class Foo4 { public: Foo4(){cout<<"想知道我为何这么屌?"<<endl;} //默认构造函数 Foo4(const Foo4&); //拷贝构造函数 Foo4& operator=(const Foo4&); //赋值运算符 ~Foo4(){cout<<"cutter_point:我就是这么屌!";} //析构函数 }; Foo4& Foo4::operator=(const Foo4 &f) { cout<<"你为何这么屌cutter_point?"; }
全代码!!!
/** * 功能:拷贝、赋值与销毁 * 时间:2014年7月11日09:39:06 * 作者:cutter_point */ #include<iostream> #include<string> #include<vector> #include<memory> using namespace std; /************************************** 13.1.1拷贝构造函数 **************************************/ class Foo1 { public: Foo1(); //默认构造函数 Foo1(const Foo1&); //拷贝构造函数 //... }; /* 拷贝构造函数的第一个参数必须是一个参数 */ /************************************** 合成拷贝构造函数 **************************************/ class Sales_data { friend Sales_data add(const Sales_data&, const Sales_data&); friend ostream &print(ostream&, const Sales_data&); friend istream &read(istream&, Sales_data&); public: // constructors Sales_data(): units_sold(0), revenue(0.0) { } Sales_data(const string &s): bookNo(s), units_sold(0), revenue(0.0) { } Sales_data(const string &s, unsigned n, double p): bookNo(s), units_sold(n), revenue(p*n) { } Sales_data(istream &); // operations on Sales_data objects string isbn() const { return bookNo; } Sales_data& combine(const Sales_data&); double avg_price() const; /* 与合成的拷贝构造函数等价的拷贝构造函数的声明 */ Sales_data(const Sales_data&); Sales_data& operator=(const Sales_data&); //赋值运算符 ~Sales_data(){} private: string bookNo; int units_sold=0; double revenue=0.0; }; //与Sales_data的合成的拷贝构造函数等价 Sales_data::Sales_data(const Sales_data &orig):bookNo(orig.bookNo), units_sold(orig.units_sold),revenue(orig.revenue){} // nonmember Sales_data interface functions Sales_data add(const Sales_data&, const Sales_data&); ostream &print(ostream&, const Sales_data&); istream &read(istream&, Sales_data&); // used in future chapters inline bool compareIsbn(const Sales_data &lhs, const Sales_data &rhs) { return lhs.isbn() < rhs.isbn(); } /************************************** 拷贝初始化 **************************************/ void fun1() { string dots(10, '.'); //直接初始化 string s(dots); //直接初始化 string s2=dots; //拷贝初始化 string null_book="9-999-99999-9"; //拷贝初始化 string nines=string(100, '9'); //拷贝初始化 } /* 拷贝初始化不仅在我们用=定义变量时会发生,在下列情况下也会发生 *将一个对象作为实参传递给一个非引用类型的形参 *从一个返回类型为非引用类型的函数返回一个对象 *用花括号列表初始化一个数组中的元素或一个聚合类中的成员 */ /** 拷贝初始化的限制 */ void fun2() { vector<int> v1(10); //正确:直接初始化 // vector<int> v2=10; //错误:接受大小参数的构造函数式explicit的 void f(vector<int>); //f的参数进行拷贝初始化 // f(10); //错误:不能用一个explicit的构造函数拷贝一个实参 // f(vector<int>(10)); //正确:从一个int直接构造一个临时的vector } /************************************** 13.1.2拷贝赋值运算符 **************************************/ void fun3() { Sales_data trans, accum; trans=accum; //使用Sales_data的拷贝赋值运算符 } /** 重载赋值运算符 */ class Foo2 { public: Foo2& operator=(const Foo2&); //赋值运算符 //... }; /** 合成拷贝赋值运算符 */ Sales_data& Sales_data::operator=(const Sales_data &rhs) { bookNo=rhs.bookNo; //调用string::operator= units_sold=rhs.units_sold; //使用内置的int赋值 revenue=rhs.revenue; //使用内置的double赋值 return *this; //返回一个此对象的引用 } /************************************** 13.1.3析构函数 **************************************/ class Foo3 { public: ~Foo3(); //析构函数 //... }; /* 析构函数自动运行,我们的程序可以按需要分配资源,无需担心何时释放这些资源 */ void fun4() { //p和p2指向动态分配的对象 Sales_data *p=new Sales_data; //p是一个内置指针 auto p2=shared_ptr<Sales_data>(); //p2是一个shared_ptr Sales_data item(*p); //拷贝构造函数吧*p拷贝到item中 vector<Sales_data> vec; //局部对象 vec.push_back(*p2); //拷贝p2指向的对象 delete p; //对p指向的对象执行析构函数 } //退出局部作用域;对item,vec,p2调用析构函数 //销毁p2会递减其引用计数;如果引用计数变为0,对象被释放 //销毁vec会销毁它的元素 //Foo类 class Foo4 { public: Foo4(){cout<<"想知道我为何这么屌?"<<endl;} //默认构造函数 Foo4(const Foo4&); //拷贝构造函数 Foo4& operator=(const Foo4&); //赋值运算符 ~Foo4(){cout<<"cutter_point:我就是这么屌!";} //析构函数 }; Foo4& Foo4::operator=(const Foo4 &f) { cout<<"你为何这么屌cutter_point?"; } int main() { Foo4 *f4=new Foo4(); delete f4; return 0; }
结果图!!(新产品)
PS:尼玛,完全没法淡定了,大热天的感冒,我的天,我受不了了。。。。。。。。。。。。