本 Wiki 开启了 HTTPS。但由于同 IP 的 Blog 也开启了 HTTPS,因此本站必须要支持 SNI 的浏览器才能浏览。为了兼容一部分浏览器,本站保留了 HTTP 作为兼容。如果您的浏览器支持 SNI,请尽量通过 HTTPS 访问本站,谢谢!
这里会显示出您选择的修订版和当前版本之间的差别。
两侧同时换到之前的修订记录前一修订版 | |||
cs:programming:cpp:cpp_primer:answers:chpt_12 [2024/01/14 13:46] – 移除 - 外部编辑 (未知日期) 127.0.0.1 | cs:programming:cpp:cpp_primer:answers:chpt_12 [2024/01/14 13:46] (当前版本) – ↷ 页面programming:cpp:cpp_primer:answers:chpt_12被移动至cs:programming:cpp:cpp_primer:answers:chpt_12 codinghare | ||
---|---|---|---|
行 1: | 行 1: | ||
+ | ======Chapter.12====== | ||
+ | Answers for chapter 12 | ||
+ | ---- | ||
+ | ====Ex.12.1-12.10==== | ||
+ | ==ex.12.1== | ||
+ | > | ||
+ | <code cpp> | ||
+ | StrBlob b1; | ||
+ | { | ||
+ | StrBlob b2 = {" | ||
+ | b1 = b2; | ||
+ | b2.push_back(" | ||
+ | } | ||
+ | </ | ||
+ | There are 4 elements do '' | ||
+ | ==ex.12.2== | ||
+ | >Write your own version of the StrBlob class including the const versions of front and back. | ||
+ | CODE: [[https:// | ||
+ | ==ex.12.3== | ||
+ | > | ||
+ | No. A const function implies we cannot modify anything through it, whereas push_back & pop_back will modify the container' | ||
+ | <code cpp> | ||
+ | inline void | ||
+ | strBlob:: | ||
+ | { | ||
+ | check(0, " | ||
+ | data-> | ||
+ | } | ||
+ | </ | ||
+ | If we call the // | ||
+ | This issue raises another question: what kind of member function should be declared as a const member function? | ||
+ | \\ \\ | ||
+ | The answer is: a member function that inspects (rather than mutates) its object, since we never change the object through it. An object mutating function, such as pop_back() / push_back(), | ||
+ | \\ \\ | ||
+ | **Refs**: | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | ==ex.12.4== | ||
+ | > | ||
+ | '' | ||
+ | ==ex.12.5== | ||
+ | > | ||
+ | Pros: | ||
+ | * '' | ||
+ | Cons: | ||
+ | * '' | ||
+ | * '' | ||
+ | In general, there is no standard stating whether we should use explicit for initializer_list. However, if you follow the Google Guide, then this behavior is prohibited: | ||
+ | >// | ||
+ | **Refs:** | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | ==ex.12.6== | ||
+ | > | ||
+ | CODE: [[https:// | ||
+ | ==ex.12.7== | ||
+ | > | ||
+ | CODE: [[https:// | ||
+ | ==ex.12.8== | ||
+ | <code cpp> | ||
+ | bool b() { | ||
+ | int* p = new int; | ||
+ | // ... | ||
+ | return p; | ||
+ | } | ||
+ | </ | ||
+ | '' | ||
+ | In addition, we should initialize the object to which '' | ||
+ | ==ex.12.9== | ||
+ | > | ||
+ | <code cpp> | ||
+ | //The memory to which r points before will never be freed when q is assigned to r. | ||
+ | //Thus we have memory leak here. | ||
+ | int *q = new int(42), *r = new int(100); | ||
+ | r = q; | ||
+ | //When q2 is assigned to r2, the object to which r2 points is freed. | ||
+ | //The counter associated with int 42 increases by 1. | ||
+ | auto q2 = make_shared< | ||
+ | r2 = q2; | ||
+ | </ | ||
+ | ==ex.12.10== | ||
+ | > | ||
+ | <code cpp> | ||
+ | shared_ptr< | ||
+ | process(shared_ptr< | ||
+ | </ | ||
+ | The code is correct, because of two reasons: | ||
+ | * the shared_ptr '' | ||
+ | * the argument of process function is an copy of the shared_ptr '' | ||
+ | Due to the first reason, '' | ||
+ | ====Ex.12.11-12.20==== | ||
+ | ==ex.12.11== | ||
+ | > | ||
+ | <code cpp> | ||
+ | process(shared_ptr< | ||
+ | </ | ||
+ | It is incorrect. '' | ||
+ | > | ||
+ | <code cpp> | ||
+ | auto p = new int(); | ||
+ | auto sp = make_shared< | ||
+ | //ok, sp is passed as an copy to the process. | ||
+ | (a) process(sp); | ||
+ | |||
+ | //error, The process function requires a shared_ptr< | ||
+ | (b) process(new int()); | ||
+ | |||
+ | //error, The process function requires a shared_ptr< | ||
+ | (c) process(p); | ||
+ | |||
+ | //Ok. However, such a usage should be avoided. As p is a plain pointer, assigning it to a shared_ptr implies that the shared_ptr will take over the management of the object that p points to. Afterwards, it is the user's responsibility to ensure that the object is available. Any behavior that might cause shared_ptr to free the object would result in p a dangling pointer. | ||
+ | (d) process(shared_ptr< | ||
+ | </ | ||
+ | ==ex.12.13== | ||
+ | > | ||
+ | <code cpp> | ||
+ | auto sp = make_shared< | ||
+ | auto p = sp.get(); | ||
+ | delete p; | ||
+ | </ | ||
+ | Deleteing '' | ||
+ | ==ex.12.14== | ||
+ | > | ||
+ | CODE: [[https:// | ||
+ | ==ex.12.15== | ||
+ | > | ||
+ | CODE: [[https:// | ||
+ | ==ex.12.16== | ||
+ | > | ||
+ | |||
+ | <code bash> | ||
+ | ##assign | ||
+ | #g++ | ||
+ | ex_12_16.cc: | ||
+ | p2 = p1; | ||
+ | #clang++ | ||
+ | ex_12_16.cc: | ||
+ | p2 = p1; | ||
+ | ##copy | ||
+ | #g++ | ||
+ | ex_12_16.cc: | ||
+ | std:: | ||
+ | |||
+ | #clang++ | ||
+ | ex_12_16.cc: | ||
+ | std:: | ||
+ | </ | ||
+ | CODE: [[https:// | ||
+ | ==ex.12.17== | ||
+ | > | ||
+ | <code cpp> | ||
+ | int ix = 1024, *pi = &ix, *pi2 = new int(2048); | ||
+ | typedef unique_ptr< | ||
+ | |||
+ | //illegal, ix is not a pointer. | ||
+ | (a) IntP p0(ix); | ||
+ | |||
+ | //illegal, unique_ptr is designed for managing dynamic memory, however, pi is managed by the compiler since it resides in stack memory. | ||
+ | (b) IntP p1(pi); | ||
+ | |||
+ | //legal, however, mixing smart pointers and plain pointers is considered bad practice. When p2 is destoried, pi2 might become a dangling pointer. | ||
+ | (c) IntP p2(pi2); | ||
+ | |||
+ | //illegal, this is equivalent to b. | ||
+ | (d) IntP p3(& | ||
+ | |||
+ | //legal | ||
+ | (e) IntP p4(new int(2048)); | ||
+ | |||
+ | //legal, but bad practice. The result of the //get()// function should never be used to initialize smart pointers. The operation will result in two independent smart pointers pointing to the same dynamic object, which is undefined behavior. Furthermore, | ||
+ | (f) IntP p5(p2.get()); | ||
+ | </ | ||
+ | ==ex.12.18== | ||
+ | > | ||
+ | The // | ||
+ | If you want to perform some similar operations to // | ||
+ | ==ex.12.19== | ||
+ | > | ||
+ | CODE: [[https:// | ||
+ | ==ex.12.20== | ||
+ | > | ||
+ | CODE: [[https:// | ||
+ | ==ex.12.21== | ||
+ | > | ||
+ | <code cpp> | ||
+ | std:: | ||
+ | { | ||
+ | return (*check(curr, | ||
+ | } | ||
+ | </ | ||
+ | Both versions work fine. I prefer the version in a book because it is more readable. | ||
+ | ==ex.12.22== | ||
+ | > | ||
+ | CODE: [[https:// | ||
+ | Notice: A member called '' | ||
+ | ==ex.12.23== | ||
+ | > | ||
+ | CODE: [[https:// | ||
+ | ==ex.12.24== | ||
+ | > | ||
+ | To handle varying input sizes, we can either use the size information from inputs to allocate memory, or we can specify the maximum size that the memory can hold.\\ \\ | ||
+ | The first method requires a temporary storage space for the input. It can either be an '' | ||
+ | In the second method, the dynamic memory is given a fixed size. The size may be specified by the user. To transfer input to a dynamic array, we can either use the '' | ||
+ | Addtionally, | ||
+ | CODE: [[https:// | ||
+ | ==ex.12.25== | ||
+ | > | ||
+ | <code cpp> | ||
+ | int *pa = new int[10]; | ||
+ | </ | ||
+ | In the code, a dynamic array is allocated with space for '' | ||
+ | <code cpp> | ||
+ | delete [] pa; | ||
+ | </ | ||
+ | ==ex.12.26== | ||
+ | > | ||
+ | CODE: [[https:// | ||
+ | ==ex.12.27== | ||
+ | > | ||
+ | CODE: [[https:// | ||
+ | ==ex.12.28== | ||
+ | > | ||
+ | [[https:// | ||
+ | ==ex.12.29== | ||
+ | > | ||
+ | The do-while statement is my preferred method. It goes through our logic, which is inputing before condition checking is performed. | ||
+ | ==ex.12.30== | ||
+ | > | ||
+ | CODE: [[https:// | ||
+ | ====Ex.12.31-12.33==== | ||
+ | ==ex.12.31== | ||
+ | > | ||
+ | It is preferable to use the //set// approach since the //vector// method does not order the line numbers or eliminate duplicates. | ||
+ | ==ex.12.32== | ||
+ | > | ||
+ | CODE: [[https:// | ||
+ | ==ex.12.33== | ||
+ | > | ||
+ | CODE: [[https:// |