Related code:
1.
#include <stdio.h>class tree{int height;public:tree (int initialheight); ~tree (); void grow (int years); void PrintSize ();}; Tree::tree (int initialheight) {height = initialheight;} Tree::~tree () {puts ("inside Tree destructor");p rintsize ();} void Tree::grow (int years) {height + = years;} void Tree::p rintsize () {printf ("Tree height is%d\n", height);} int main () {puts ("before opening brace"); { Tree T;p UTS ("After tree Creation"); T.printsize (); T.grow (4);p UTS ("Brfore closing brace");} Puts ("After closing brace"); return 0;}
2.
#include <stdio.h> #include <assert.h> #include <stdlib.h>class g{int i;public:g (int i); void Show ();}; g::g (int i) {i = i;} /*void g::show () {printf ("%d\n", I);} */int Main () {#define SZ 100char buf[sz];//We can see that BUF is defined first, then some statements. Then x is defined and used by a function call to start //Initialize it. Then Y and g are defined by printf ("initialization value?").int retval = (int) gets (BUF); assert (retval); int x = Atoi (buf); int y = x+3; g g (Y);//g.show (); return 0;}
3.
#include <iostream>using namespace Std;class x{public:x () {}};void f (int i) {if (I <) {//!goto Jump1;//error: Goto bypasses Init}x X1;jump1:switch (i) {case 1:x x2;break;//!case 2://error:case bypasses Initx X3;//Constructor called H Erebreak;}} /* In the preceding code, both Goto and switch may skip the call point of the constructor. However, this object will function in a later block, so the constructor is not called, so the compiler gives an error message. This ensures that the object is initialized at the same time that it was created. */int Main () {return 0;}
4.
/* constructor with multiple parameters */#include <iostream>using namespace Std;class x{int i,j;public:x (int i, int j) {i = I;j = j;}}; int main () {x xx[] = {x (n), X (3,4), X (5,6), X (7,8)};/* Note that it looks like every object in the array is called once for a constructor that is not named */return 0;}
5.
#ifndef nested_h_#define nested_h_class stack//This nested struct is called link. It contains a pointer to the next link in the table and a pointer to the data stored in the link, assuming that the next pointer is zero, which means the footer. {struct link/* note that although the stack has constructors and destructors, the nested class link does not, which is not to say that it does not need to be.When it is used. The problem is: */{void* data;link* next;void Initialize (void* data, link* next);} *head;stack (); ~stack (); void push (void* Data); void* peek (); void* pop ();}; #endif
#include "nested.h" #include <stdlib.h> #include <assert.h>void stack::link::initialize (void* Data, link* Next)//simply use the range decomposition operator two times to indicate the name of the nested struct. The Stack::link::initialize () function takes the number of parameters and assigns the parameters to its members {data = Data;next = Next;} Stack::stack () {head = 0;} void stack::p ush (void* data)//stack::p Ush () takes a pointer to a piece of data that you want to save with this stack. and put//this pointer on the top of the stack {link* NewLink = (link*) malloc (sizeof); assert (NewLink); Newlink->initialize (Data, head); head = NewLink;} void* stack::p eek ()//Return the value of head {return head->data;} void* stack::p op ()//stack::p op () takes out the data pointer that is currently at the top of the stack, and then moves the head pointer down. Delete the stack's old stack top element {if (head = = 0) {return 0;} void* result = head->data;link* Oldhead = Head;head = Head->next;free (oldhead); return result;} Stack::~stack () {link* cursor = Head;while (head) {cursor = Cursor->next;free (head->data); free (head); head = cursor ;}}
#include "nested.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h >int Main (int argc, char** argv) {assert (argc = = 2); file* file = fopen (Argv[1], "R"), assert (file), #define BUFSIZE 100char buf[bufsize];stack textlines;while (fgets (BUF, BUFSIZE, file) {char* string = (char*) malloc (strlen (BUF) +1); assert (string); strcpy (string, buf); Textlines.push ( string);} Char* S;while ((s = (char*) textlines.pop ())! = 0) {printf ("%s", s); free (s);} The constructors and destructors of/*textlines are called on their own initiative, so users of the class simply focus on how to use the objects. Instead of worrying about whether they have been properly initialized and cleared */return 0;}
6.
#include <assert.h> #include <stdlib.h> #include <string.h> #include <stdio.h>//c++class stash {int size; Size of each spaceint quantity; Number of storage spacesint next; Next empty spaceunsigned char* storage; The storage pointer is a unsigned char*. This is the smallest memory slice supported by the C compiler. Although on some machines//it may be as large as the largest, this depends on the detailed implementation. The memory that storage points to allocates void inflate (int increase) from the heap, and the/*inflate () function uses realloc () to get a larger block of space for stash.ReAlloc () takes the stored-order head address that has been allocated and wants to be redistributed as its first parameter (assuming that the number is zero. For example, when initialize () has just been called, realloc () allocates a new block).
The second parameter is the new length of the block, assuming the length is smaller than the original, the block will not need to be copied. Simply tell the heap manager that the rest of the space is spare. Assuming the length is larger than the original, there is not enough space in the heap. So you want to allocate new blocks and copy the memory. ASSERT () Check to make sure that the operation was successful.
(Assuming that the heap is exhausted, malloc (), Calloc (), and realloc () all return zeros. ) */public:stash (int Size); Constructor ~stash (); destructor int Add (void* element); The Add () function inserts an element on the next available seat in the stash.
First of all. It checks if there is free space, such as//fruit not. It expands the storage space with the inflate () function described later. void* Fetch (int index); Fetch () first looks at whether the index is out of bounds, assuming no bounds, and returns the desired variable address. The calculation of the address is taken with the same method as in//add () int count (); Returns the size of the stored space};
/*test.cpp*//* If there is a programming tool, it behaves like an array when it is created, but its length can be established at execution time. I call it stash*/#include "test.h" stash::stash (int size) {size = size; quantity = 0;storage = 0; next = 0; }stash::~stash () {if (storage) {puts ("freeing storage"); free (storage);}} int Stash::add (void* element) {if (next >= quantity) {inflate (100);} memcpy (& (Storage[next * size]), element,size);/* We have to copy this variable one byte at a byte using the standard C library function memcpy (). The first parameter is the destination address of the memcpy () starting copy byte, which is generated by the following expression: & (S->storage[s->next * s->size]) it indicates the end of the next available unit starting from the storage block.This number is actually the count of the unit number plus one that has been used, and it must multiply the number of bytes owned by each cell to produce an offset in bytes.
This does not produce an address, but rather produces a byte at this address, in order to generate the address, must use the address operator &. The second and third parameters of memcpy () are the start address of the copied variable and the number of bytes to be copied.
The n e x T counter adds one and returns the index of the stored value.
Such The program ape can use it to get this element when it calls fetch () later. */next ++;return (next-1);} void* stash::fetch (int index) {if (index >= Next | | Index < 0) {return 0;} Return & (Storage[index * size]);} int Stash::count () {return next;} void stash::inflate (int increase) {void* v = realloc (storage, (quantity + increase) *size); assert (v); storage = (unsigned ch ar*) v;quantity + = increase;}
#include "test.h" #define BUFSIZE 80int Main () {Stash intstash (sizeof (int)), for (int i = 0;i < 100;++i) {Intstash.add (& Amp;i);} file* file = fopen ("Main.cpp", "R"), assert (file), Stash Stringstash (sizeof (char) *bufsize), Char buf[bufsize];while ( Fgets (buf, BUFSIZE, file)) {Stringstash.add (BUF);} fclose (file); for (i = 0;i < Intstash.count (); ++i) {printf ("intstash.fetch (%d) =%d\n", i,* (int*) Intstash.fetch (i));} for (i = 0;i < Stringstash.count (); ++i) {printf ("stringstash.fetch (%d) =%s", I, (char*) Stringstash.fetch (i++));} Putchar (' \ n ');/* Then see if the cleanup () call has been canceled, but when Intstash and Stringstash are out of the scope of the program block. The destructor was called by itself to */return 0;}
Exercises + answers
1) Change the handle.h,handle at the end of chapter 3rd with the constructor and destructor. CPP and USEHANDL.CPP files.
#ifndef handle_h_#define Handle_h_class handle{struct cheshire;//struct Cheshire; is a type description or class declaration that is not fully specified (the definition of a class includes the body of the Class) cheshire* smile;public:handle (); ~handle (); int read (); void change (int);}; #endif
#include "handle.h" #include <stdlib.h> #include <assert.h>struct handle::cheshire//cheshire is a nested structure, Therefore, it must define the struct Handle::cheshire { //in handle (), allocate storage space for the Cheshire struct in the Handle::cleanup (), and the space is freed {int i;} with the range decomposition character; Handle::handle () {smile = (cheshire*) malloc (sizeof (Cheshire)); assert (smile); smile->i = 1;} Handle::~handle () {free (smile);} int Handle::read () {return smile->i;} void Handle::change (int x) {smile->i = x;}
#include "handle.h"/* client program The only thing that the ape can access is the public interface part, so that only the parts of the implementation are changed, and the files do not have to be compiled again */int main () {handle u;u.read (); U.change (1) ; return 0;}
2) Create a class with non-default constructors and destructors that display some information to indicate their existence.
Write a code that explains when the constructor and destructor are called.
#include <iostream>using namespace Std;class a{int i;double d;public:a (int i, double d); ~a ();}; a::a (int i, double D) {i = I;d = d;cout<< "create! "<<i<<" "<<D<<ENDL; A::~a () {cout<< "delete! "<<i<<" "<<D<<ENDL; int main () {a A (1,2.0); A b (3,4.0); A c (5,6.0); return 0;}
3) Create an array of the classes in the previous question to demonstrate that you are actively counting and initializing the collection.
In this class, add a member function that displays information.
Calculate the size of the array and visit them individually. Call the new member function.
#include <iostream>using namespace Std;class a{int i;double d;public:a (); A (int I, double D); ~a (); void Show ();}; A::a () {i = 1;d = 1.0;} a::a (int i, double D) {i = I;d = d;cout<< "create! "<<i<<" "<<D<<ENDL; A::~a () {cout<< "delete! "<<i<<" "<<D<<ENDL; void A::show () {cout<<i<< "" <<d<<endl;} int main () {a aa[] = {A (a), a (3,4), A (5,6)};cout<< "sizeof (AA) =" <<sizeof (aa) <<endl;for (int i = 0;i < sizeof (AA)/sizeof (aa[0]); ++i) {aa[i].show ();} return 0;}
4) Create a class that does not have any constructors whatsoever. Shows that we can create an object with the default constructor. Now create a non-default constructor (with one parameter) for this class. Try compiling one more time.
Explain the phenomenon that occurs.
<span style= "FONT-SIZE:18PX;" > #include <iostream>using namespace Std;class b{int i;}; int main () {B B;return 0;} </span>
<span style= "FONT-SIZE:18PX;" > #include <iostream>using namespace std;class b{int i;public:b (int i);}; b::b (int i) {i = i;} int main () {b b (1);//b b; definition will error. Only the defined constructors are called at this time. The default constructor is not called return 0;} </span>
The above code is for reference only. If there's a problem, I want you to say thank you
"C + + Programming thought" fourth chapter initialization and elimination (original code + exercise + solution)