C++primer 13.6.1节练习

练习13.45

右值引用:使用&&,他是必须绑定到右值的引用,右值短暂,要么是字面常量,要么是表达式求职过程中的创建的临时对象;不能将一个右值引用绑定到一个右值引用类型的变量上;

练习13.46

 1 #include <iostream>
 2 #include <string>
 3 #include <utility>
 4 #include <memory>
 5 #include <algorithm>
 6 #include <vector>
 7
 8 using namespace std;
 9
10 int f() {
11     return 3;
12 }
13
14 int main()
15 {
16     vector<int> vi(100);
17     int&& r1 = f();
18     int& r2 = vi[0];
19     int& r3 = r1;
20     int&& r4 = vi[0] * f();
21     system("pause");
22     return 0;
23 }

练习13.47

  1 #include <iostream>
  2 #include <string>
  3 #include <utility>
  4 #include <memory>
  5 #include <algorithm>
  6
  7 using namespace std;
  8
  9 class String {
 10     friend ostream &print(ostream &os, String &s);
 11 public:
 12     String(): element(nullptr), first_free(nullptr) {}
 13     String(char *);
 14     size_t size() const{ return first_free - element; }
 15     String(const String&);
 16     String& operator=(const String&);
 17     ~String() { free(); }
 18 private:
 19     static allocator<char> alloc;
 20     pair<char *, char *> alloc_n_copy(const char*, const char *);
 21     void free();
 22     char *element;
 23     char *first_free;
 24 };
 25 allocator<char> String::alloc;
 26 ostream &print(ostream &os, String &s);
 27
 28 int main()
 29 {
 30     String s1;
 31     String s2("hello");
 32     String s3("hello world");
 33     String s4(s2);
 34     s1 = s3;
 35     print(cout, s1);
 36     print(cout, s2);
 37     print(cout, s3);
 38     system("pause");
 39     return 0;
 40 }
 41
 42 String::String(char *s)
 43 {
 44     int i = 0;
 45     while (s[i] != ‘\0‘)
 46         i = i + 1;
 47     auto newloc = alloc.allocate(i);
 48     auto dest = newloc;
 49     for (auto count = 0; count != i;++count)
 50         alloc.construct(dest++, s[count]);
 51     element = newloc;
 52     first_free = dest;
 53 }
 54
 55 String::String(const String &s)
 56 {
 57     auto newdata = alloc_n_copy(s.element, s.first_free);
 58     element = newdata.first;
 59     first_free = newdata.second;
 60     cout << "拷贝构造函数" << endl;
 61 }
 62
 63 String & String::operator=(const String &rhs)
 64 {
 65     auto newdata = alloc_n_copy(rhs.element, rhs.first_free);
 66     free();
 67     element = newdata.first;
 68     first_free = newdata.second;
 69     cout << "拷贝赋值运算符" << endl;
 70     return *this;
 71     // TODO: 在此处插入 return 语句
 72 }
 73
 74 pair<char*, char*> String::alloc_n_copy(const char *b, const char *e)
 75 {
 76     auto data = alloc.allocate(e - b);
 77     return{ data,uninitialized_copy(b,e,data) };
 78 }
 79
 80 void String::free()
 81 {
 82     if (element)
 83     {
 84         for (auto p = first_free; p != element;)
 85             alloc.destroy(--p);
 86         alloc.deallocate(element,first_free - element);
 87     }
 88 }
 89
 90 ostream & print(ostream &os,String &s)
 91 {
 92     while (s.element != s.first_free)
 93     {
 94         os << *(s.element);
 95         s.element++;
 96     }
 97     cout << endl;
 98     return os;
 99     // TODO: 在此处插入 return 语句
100 }

该题的代码存在内存释放的问题,请大家指正

练习13.48

  1 #include <iostream>
  2 #include <string>
  3 #include <utility>
  4 #include <memory>
  5 #include <algorithm>
  6 #include <vector>
  7
  8 using namespace std;
  9
 10 class String {
 11     friend ostream &print(ostream &os, String &s);
 12 public:
 13     String(): element(nullptr), first_free(nullptr) {}
 14     String(char *);
 15     size_t size() const{ return first_free - element; }
 16     String(const String&);
 17     String& operator=(const String&);
 18     ~String() { free(); }
 19 private:
 20     static allocator<char> alloc;
 21     pair<char *, char *> alloc_n_copy(const char*, const char *);
 22     void free();
 23     char *element;
 24     char *first_free;
 25 };
 26 allocator<char> String::alloc;
 27 ostream &print(ostream &os, String &s);
 28
 29 int main()
 30 {
 31     vector<String> vec;
 32     String s1("hello");
 33     String s2("world");
 34     String s3(s1);
 35     String s4 = s2;
 36     s3 = s1;
 37     vec.push_back(s1);
 38     vec.push_back(s2);
 39     vec.push_back(s3);
 40     vec.push_back(s4);
 41      system("pause");
 42     return 0;
 43 }
 44
 45 String::String(char *s)
 46 {
 47     int i = 0;
 48     while (s[i] != ‘\0‘)
 49         i = i + 1;
 50     auto newloc = alloc.allocate(i);
 51     auto dest = newloc;
 52     for (auto count = 0; count != i;++count)
 53         alloc.construct(dest++, s[count]);
 54     element = newloc;
 55     first_free = dest;
 56 }
 57
 58 String::String(const String &s)
 59 {
 60     auto newdata = alloc_n_copy(s.element, s.first_free);
 61     element = newdata.first;
 62     first_free = newdata.second;
 63     cout << "拷贝构造函数" << endl;
 64 }
 65
 66 String & String::operator=(const String &rhs)
 67 {
 68     auto newdata = alloc_n_copy(rhs.element, rhs.first_free);
 69     free();
 70     element = newdata.first;
 71     first_free = newdata.second;
 72     cout << "拷贝赋值运算符" << endl;
 73     return *this;
 74     // TODO: 在此处插入 return 语句
 75 }
 76
 77 pair<char*, char*> String::alloc_n_copy(const char *b, const char *e)
 78 {
 79     auto data = alloc.allocate(e - b);
 80     return{ data,uninitialized_copy(b,e,data) };
 81 }
 82
 83 void String::free()
 84 {
 85     if (element)
 86     {
 87         for (auto p = first_free; p != element;)
 88             alloc.destroy(--p);
 89         alloc.deallocate(element,first_free - element);
 90     }
 91 }
 92
 93 ostream & print(ostream &os,String &s)
 94 {
 95     while (s.element != s.first_free)
 96     {
 97         os << *(s.element);
 98         s.element++;
 99     }
100     cout << endl;
101     return os;
102     // TODO: 在此处插入 return 语句
103 }

上一题的问题已解决,可能是编译器抽风。。。。

时间: 2024-10-05 03:35:00

C++primer 13.6.1节练习的相关文章

C++primer 13.1.3节练习

练习13.9 析构函数执行与构造函数相反的操作,构造函数初始化对象的非static数据成员,析构函数释放对象使用的资源,并销毁对象的非static数据成员.当一个类没有定义自己的析构函数的时候,编译器会为它定义一个合成析构函数. 练习13.10 在一个构造函数中,成员的初始化是在函数体执行之前完成的,且按照他们再类中出现的顺序进行初始化.再一个析构函数中,首先执行函数体,然后销毁成员.成员按照初始化顺序的逆序销毁. 练习13.11 1 #include <iostream> 2 #includ

C++primer 13.1.2节练习

练习13.6 其实就是"="运算,也就是赋值运算.右侧运算对象作为显示参数向左侧传递时时候.合成拷贝赋值运算符来禁止该类型对象的赋值.当一个类没有定义自己的拷贝赋值运算符的时候,编译器会为它自动生成一个合成拷贝赋值运算符. 练习13.7 将一个StrBlob赋值给另一个StrBlob这个操作是完全没有问题的. 当赋值StrBlobPtr的时候就会出错,在编译的时候就会报错,左右值的类型不一样(也不是继承关系),无法完成赋值. 练习13.8 1 #include <iostream

C++primer 13.6.2节练习

练习13.49 13.50 1 #include <iostream> 2 #include <string> 3 #include <utility> 4 #include <memory> 5 #include <algorithm> 6 #include <vector> 7 8 using namespace std; 9 10 class String { 11 friend ostream &print(ostre

C++primer 13.2.1节练习

练习13.23 1 #include <iostream> 2 #include <string> 3 #include <memory> 4 5 using namespace std; 6 7 8 class HasPtr { 9 friend ostream &print(ostream &os, HasPtr &h); 10 public: 11 HasPtr(const string &s = string()) : ps(ne

C++primer 13.6.3节练习

练习13.55 1 void push_back(const string& s) &&; 练习13.56 此时拷贝一个副本,但是问题来了,ret是一个左值,返回他的sorted函数,会不停的进行递归自己,而该函数并没有一个终止条件,所以最后堆栈会溢出,导致程序异常终止: 练习13.57 此时函数返回的是一个临时对象的sorted函数,而临时对象是一个右值,这时会调用右值的sorted重载函数,程序正常运行,但是原对象依然没有排序,因为他是一个const或者是一个左值,改变的只是临

C++primer 13.1.1节练习

练习13.1 如果一个构造函数的第一个参数是自身类类型的引用,且任何额外参数都有默认值,则此构造函数是拷贝构造函数:拷贝初始化通常使用拷贝构造函数来完成.拷贝构造函数被用来初始化非引用类类型参数: 练习13.2 拷贝构造函数自己的参数必须是引用类型.如果其参数不是引用类型,则调用永远也不会成功-为了调用拷贝构造函数,我们必须拷贝他的实参,但为了拷贝实参,我们又需要调用拷贝构造函数,如此无限循环: 练习13.3 如果我们没有定义自己的拷贝构造函数,则会调用编译器为我们合成的拷贝构造函数 练习13.

C++primer 13.1.6节练习

练习13.18 1 #include <iostream> 2 #include <string> 3 #include <memory> 4 5 using namespace std; 6 7 static int i = 0; 8 9 class Employee { 10 friend ostream& print(ostream& os, const Employee& emp); 11 public: 12 Employee() :

C++primer 13.2节练习

练习13.22 1 #include <iostream> 2 #include <string> 3 #include <memory> 4 5 using namespace std; 6 7 8 class HasPtr { 9 friend ostream &print(ostream &os, HasPtr &h); 10 public: 11 HasPtr(const string &s = string()) : ps(s)

C++primer 13.3节练习

练习13.29 不会,因为该类中的数据成员都是内置类型的,而内置类型是没有特定版本的swap的,所以对swap的调用会调用标准库的std::swap: 练习13.30 1 #include <iostream> 2 #include <string> 3 #include <memory> 4 5 using namespace std; 6 7 8 class HasPtr { 9 friend ostream &print(ostream &os,