13.1 Copy, Assign, and Destroy

来源:互联网 发布:支配集网络matlab算法 编辑:程序博客网 时间:2024/05/20 23:03
/*class Sales_data {public:Sales_data(const Sales_data&);private:string bookNo;int units_sold = 0;double revenue = 0.0;};Sales_data::Sales_data(const Sales_data&orig):bookNo(orig.bookNo), units_sold(orig.units_sold), revenue(orig.revenue) { }int main() {return 0;}*//*int main() {string dots(10, '.');string s(dots);string s2 = dots;string null_book = "9-999-99999-9";string nines = string(100, '9');return 0;}*/// the vecotr uses a explicit constructor/*int main() {vector<int> v1(10);//vecotr<int> v2 = 10;void f(vector<int>);//f(10);f(vector<int>(10));return 0;}*///Exercises Section 13.1.1//Exercise 13.1: What is a copy constructor ? When is it used ?//A constructor is the copy constructor if its first parameter is//a reference to the class type and any additional parameters have//default values//when copy initialization happens and that copy initialization re//quires either copy constructor or move constructor//Define variables using an '=', pass an object as an argument to a//parameter of nonreference type, return an object from a function//that has a nonreference return type, Brace initilaize the elements//in an array or the members of an aggregate class, some class types//also use copy initialzation for the objects they allocate//Exercise 13.2: Explain why the following declaration is illegal ://Sales_data::Sales_data(Sales_data rhs);//the call would never succeed to call the copy ocnstructor, it's on indefinitely//Exercise 13.4: Assuming Point is a class type with a public copy//constructor, identify each use of the copy constructor in this program//fragment :/*Point global;Point foo_bar(Point arg)//this{Point local = arg, *heap = new Point(global);//these two*heap = local;Point pa[4] = { local, *heap };//these tworeturn *heap;//this}*///Exercise 13.5: Given the following sketch of a class, write a copy//constructor that copies all the members.Your constructor should dynamically//allocate a new string(§ 12.1.2, p. 458) and copy the object to which ps//points, rather than copying ps itself.class HasPtr {public:HasPtr(const std::string &s = std::string()) :ps(new std::string(s)), i(0) { }HasPtr(const HasPtr &hp) : ps(new std::string(*hp.ps), i(hp.i)) { }private:std::string *ps;int i;};/*HasPtr::HasPtr(const HasPtr &c) {string s = *c.ps;ps = &s;i = c.i}*/

13.2. Copy Control and Resource ManagementExercises Section 13.1.2Exercise 13.6: What is a copy-assignment operator? When is this operatorused? What does the synthesized copy-assignment operator do? When is itsynthesized?The copy-assignment operator is function named operator= and takes an argument of the same class.It is used when assignment occurred.The synthesized copy-assignment operator assigns each nonstatic memberof the right-hand object to corresponding member of the left-hand objectusing the copy-assignment operator for the type of that member.When the class does not define its own.Exercise 13.8: Write the assignment operator for the HasPtr class fromexercise 13.5 in § 13.1.1 (p. 499). As with the copy constructor, yourassignment operator should copy the object to which ps points.class HasPtr {public:HasPtr(const std::string &s = std::string()) :ps(new std::string(s)), i(0) { }HasPtr(const HasPtr &hp) : ps(new std::string(*hp.ps)), i(hp.i) { }HasPtr &operator=(const HasPtr &hp) {if (this != &hp) {string *tps = new string(*hp.ps);delete ps;ps = tps;i = hp.i;}}private:std::string *ps;int i;};Exercises Section 13.1.3Exercise 13.9: What is a destructor? What does the synthesized destructordo? When is a destructor synthesized?The destructor operates inversely to the constructors: Constructor initialize the nonstatic data members and may do other work, destructors dowhatever work is needed to free the resources used by an object and destory the nonstatic data members of the object.when class does not define its own destructor.Exercise 13.11: Add a destructor to your HasPtr class from the previousexercises.class HasPtr {public:HasPtr(const std::string &s = std::string()) :ps(new std::string(s)), i(0) { }HasPtr(const HasPtr &hp) : ps(new std::string(*hp.ps)), i(hp.i) { }HasPtr &operator=(const HasPtr &hp) {if (this != &hp) {string *tps = new string(*hp.ps);delete ps;ps = tps;i = hp.i;}}~HasPtr() { delete ps; }private:std::string *ps;int i;};Exercise 13.12: How many destructor calls occur in the following codefragment?bool fcn(const Sales_data *trans, Sales_data accum){Sales_data item1(*trans), item2(accum);return item1.isbn() != item2.isbn();} threeExercise 13.13: A good way to understand copy-control members andconstructors is to define a simple class with these members in which eachmember prints its name:struct X {X() {std::cout << "X()" << std::endl;}X(const X&) {std::cout << "X(const X&)" <<std::endl;}};Add the copy-assignment operator and destructor to X and write a program usingX objects in various ways: Pass them as nonreference and reference parameters;dynamically allocate them; put them in containers; and so forth. Study the outputuntil you are certain you understand when and why each copy-control member isused. As you read the output, remember that the compiler can omit calls to thecopy constructor.struct X {X() { std::cout << "X()" << std::endl; }X(const X&) {std::cout << "X(const X&)" << std::endl;}X &operator=(const X &rhs) {cout << "X &operator=(const X&)" << endl;return *this;}~X() { cout << "~X()" << endl; }};void f(const X &rx, X x) {//1cout << 1 << endl;vector<X> vec;vec.reserve(2);vec.push_back(rx);cout << 2 << endl;vec.push_back(x);cout << 3 << endl;}//out of the range the three are destructedint main() {X *px = new X;f(*px, *px);delete px;//the x are destructedreturn 0;}

//Exercises Section 13.1.4//Exercise 13.14: Assume that numbered is a class with a default constructor//that generates a unique serial number for each object, which is stored in a//data member named mysn.Assuming numbered uses the synthesized copycontrol//members and given the following function ://Three identical numberclass numbered {public:numbered() {mysn = unique++;}int mysn;static int unique;};int numbered::unique = 10;void f(numbered s) {cout << s.mysn << endl;}int main() {numbered a, b = a, c = b;f(a);f(b);f(c);return 0;}//Exercise 13.15: Assume numbered has a copy constructor that generates a//new serial number.Does that change the output of the calls in the previous//exercise ? If so, why ? What output gets generated ?class numbered {public:numbered() {mysn = unique++;}numbered(numbered &n) {mysn = unique++;}int mysn;static int unique;};int numbered::unique = 10;void f(numbered s) {cout << s.mysn << endl;}int main() {numbered a, b = a, c = b;cout << a.mysn << endl;cout << b.mysn << endl;cout << c.mysn << endl;f(a);f(b);f(c);return 0;}//Exercise 13.16: What if the parameter in f were const numbered& ?//Does that change the output ? If so, why ? What output gets generated ?class numbered {public:numbered() {mysn = unique++;}numbered(numbered &n) {mysn = unique++;}int mysn;static int unique;};int numbered::unique = 10;void f(numbered &s) {cout << s.mysn << endl;}int main() {numbered a, b = a, c = b;cout << a.mysn << endl;cout << b.mysn << endl;cout << c.mysn << endl;f(a);f(b);f(c);return 0;}

//exercises Section 13.1.6//Exercise 13.18: Define an Employee class that contains an employee name//and a unique employee identifier.Give the class a default constructor and a//constructor that takes a string representing the employee’s name.Each//constructor should generate a unique ID by incrementing a static data//member.//Exercise 13.19: Does your Employee class need to define its own versions//of the copy - control members ? If so, why ? If not, why not? Implement//whatever copy - control members you think Employee needs.//No, for the employe copy has no sensible meaning.class Employee {public:Employee();Employee(const string &);Employee(const Employee &) = delete;Employee &operator=(const Employee&) = delete;const int Id() const { return id; }private:static int unique;string name;int id;};int Employee::unique = 0;Employee::Employee() {id = unique++;}Employee::Employee(const string &s) {id = unique++;name = s;}int main() {return 0;}