require.h ? Where's it ??
one of my favorite book : thinking in C++!
Post code lại hoàn chỉnh coi cậu, cậu copy và paste cũng không nên thân nữa à ?
các bác giúp em hiểu mấy bài code này với ,thầy em bảo dịch từ bản tiếng anh xong rùi làm thuyết trình hic hic ,mấy cái này dịch đã khổ rùi ,nhìn còn lạ hơắc ,bác nào hảo tâm giúp em cái.em xin cảm ơn và hậu tạ (hic tuần tới em pải nộp bài rùi)
Định nghĩa thành viên của hàm được thay đổi là initialize() và cleanup(), chúng được thay thế bởi hàm tạo và hàm hủy.C++ Code:
Stash with constructors and destructors //: C06:Stash2.h // With constructors & destructors #ifndef STASH2_H #define STASH2_H class Stash { int size; // Size of each space int quantity; // Number of storage spaces int next; // Next empty space // Dynamically allocated array of bytes: unsigned char* storage; void inflate(int increase); public: Stash(int size); ~Stash(); int add(void* element); void* fetch(int index); int count(); }; #endif // STASH2_H ///:~
C++ Code:
//: C06:Stash2.cpp {O} // Constructors & destructors #include "Stash2.h" #include <iostream> #include <cassert> using namespace std; const int increment = 100; Stash::Stash(int sz) { size = sz; quantity = 0; storage = 0; next = 0; } int Stash::add(void* element) { if(next >= quantity) // Enough space left? inflate(increment); // Copy element into storage, // starting at next empty space: int startBytes = next * size; unsigned char* e = (unsigned char*)element; for(int i = 0; i < size; i++)//: C06:Stash2.h // With constructors & destructors #ifndef STASH2_H #define STASH2_HĐịnh nghĩa thành viên của hàm được thay đổi là initialize() và cleanup(), chúng được thay thế bởi hàm tạo và hàm hủy.C++ Code:
class Stash { int size; // Size of each space int quantity; // Number of storage spaces int next; // Next empty space // Dynamically allocated array of bytes: unsigned char* storage; void inflate(int increase); public: Stash(int size); ~Stash(); int add(void* element); void* fetch(int index); int count(); }; #endif // STASH2_H ///:~
Hãy xem inflate(), có lẽ bạn hỏi tại sao assert() vẫn được sử dụng sau hàm required.h (đã được giới thiệu). Sự khác biệt quan trọng: trong quyển sách này assert() sẽ được sử dụng để theo dõi lỗi chương trình. Trong khi require.h là một hàm được thiết kế đặc biệt để sử dụng hợp lý cho người dùng.C++ Code:
//: C06:Stash2.cpp {O} // Constructors & destructors #include "Stash2.h" #include <iostream> #include <cassert> using namespace std; const int increment = 100; Stash::Stash(int sz) { size = sz; quantity = 0; storage = 0; next = 0; } int Stash::add(void* element) { if(next >= quantity) // Enough space left? inflate(increment); // Copy element into storage, // starting at next empty space: int startBytes = next * size; unsigned char* e = storage[startBytes + i] = e[i]; next++; return(next - 1); // Index number } void* Stash::fetch(int index) { assert(0 <= index && index < next); // Produce pointer to desired element: return &(storage[index * size]); } int Stash::count() { return next; // Number of elements in CStash } void Stash::inflate(int increase) { assert(increase > 0); int newQuantity = quantity + increase; int newBytes = newQuantity * size; int oldBytes = quantity * size; unsigned char* b = new unsigned char[newBytes]; for(int i = 0; i < oldBytes; i++) b[i] = storage[i]; // Copy old to new delete [](storage); // Old storage storage = b; // Point to new memory quantity = newQuantity; } Stash::~Stash() { if(storage != 0) { delete []storage; } } ///:~ .fetch(" << k << ") = " << cp << endl; } ///:~
Bởi vì inflate() là phần riêng, chỉ assert() có thể xuất hiện…
Chú ý: Theo chương trình kiểm tra, định nghĩa thế nào cho đối tượng Stash xuất hiện trước khi chúng được cần đến, khởi tạo như một phần của việc định nghĩa. Trong cấu trúc hàm tạo:
C++ Code:
//: C06:Stash2Test.cpp //{L} Stash2 // Constructors & destructors #include "Stash2.h" #include "../require.h" #include <fstream> #include <iostream> #include <string> using namespace std; int main() { Stash intStash(sizeof(int)); for(int i = 0; i < 100; i++) intStash.add(&i); for(int j = 0; j < intStash.count(); j++) << *(int*)intStash.fetch(j) << endl; const int bufsize = 80; Stash stringStash(sizeof(char) * bufsize); ifstream in("Stash2Test.cpp"); assure(in, " Stash2Test.cpp"); string line; while(getline(in, line)) stringStash.add((char*)line.c_str()); int k = 0; char* cp; while((cp = (char*)stringStash.fetch(k++))!=0)
Lứu ý bỏ code vào thẻ code !
Đã được chỉnh sửa lần cuối bởi rox_rook : 06-04-2008 lúc 04:46 PM.
require.h ? Where's it ??
one of my favorite book : thinking in C++!
Post code lại hoàn chỉnh coi cậu, cậu copy và paste cũng không nên thân nữa à ?
hic ,bác thông cảm cho em vì vùi đầu vào cái đống ấy mà em hơi bị ngộ .mà cái require.h em cũng chẳng hiểu ji_lạ hoắc đấy đúng là ở quyển thinking in c++.bác có thể nói rõ cho em mỗi dòng lệnh nói ji dc ko ạ.em học bên kinh tế nên .......hic ko hiêu rõ cho lắm.Mong bác phúc đáp cho em sớm
haha cậu học kinh tế mà ông nào đưa cậu cái đống bùi bui kia thế ? Cái này dùng style C mixed C++, void* pointer là very poor style. Dùng generic template code sẽ sáng hơn rất nhiều.
- Sách đó tui đọc cũng lâu rùi, cậu thắc mắc dòng nào thì tui sẽ giải thích. Còn nếu mỗi dòng lệnh từ A->Z thì tui nghĩ cậu cũng biết đùa
Guaranteed cleanup with the destructor
C++ Code:
//: C06:Constructor1.cpp // Constructors & destructors #include <iostream> using namespace std; class Tree { int height; public: Tree(int initialHeight); // Constructor ~Tree(); // Destructor void grow(int years); void printsize(); }; Tree::Tree(int initialHeight) { height = initialHeight; } Tree::~Tree() { printsize(); } void Tree::grow(int years) { height += years; } void Tree::printsize() { } int main() { { Tree t(12); t.printsize(); t.grow(4); } } ///:~
C++ Code:
Elimination of the definition block //: C06:DefineInitialize.cpp // Defining variables anywhere #include "../require.h" #include <iostream> #include <string> using namespace std; class G { int i; public: G(int ii); }; G::G(int ii) { i = ii; } int main() { int retval = 0; require(retval != 0); int y = retval + 3; G g(y); } ///:~
C++ Code:
Storage Allocation(Kho lưu trữ) //: C06:Nojump.cpp // Can't jump past constructors class X { public: X(); }; X::X() {} void f(int i) { if(i < 10) { //! goto jump1; // Error: goto bypasses init } X x1; // Constructor called here jump1: switch(i) { case 1 : X x2; // Constructor called here break; //! case 2 : // Error: case bypasses init X x3; // Constructor called here break; } } int main() { f(9); f(11); }///:~
Định nghĩa thành viên của hàm được thay đổi là initialize() và cleanup(), chúng được thay thế bởi hàm tạo và hàm hủy.C++ Code:
Stash with constructors and destructors //: C06:Stash2.h // With constructors & destructors #ifndef STASH2_H #define STASH2_H class Stash { int size; // Size of each space int quantity; // Number of storage spaces int next; // Next empty space // Dynamically allocated array of bytes: unsigned char* storage; void inflate(int increase); public: Stash(int size); ~Stash(); int add(void* element); void* fetch(int index); int count(); }; #endif // STASH2_H ///:~
C++ Code:
//: C06:Stash2.cpp {O} // Constructors & destructors #include "Stash2.h" #include <iostream> #include <cassert> using namespace std; const int increment = 100; Stash::Stash(int sz) { size = sz; quantity = 0; storage = 0; next = 0; } int Stash::add(void* element) { if(next >= quantity) // Enough space left? inflate(increment); // Copy element into storage, // starting at next empty space: int startBytes = next * size; unsigned char* e = (unsigned char*)element; for(int i = 0; i < size; i++) storage[startBytes + i] = e[i]; next++; return(next - 1); // Index number } void* Stash::fetch(int index) { assert(0 <= index && index < next); // Produce pointer to desired element: return &(storage[index * size]); } int Stash::count() { return next; // Number of elements in CStash } void Stash::inflate(int increase) { assert(increase > 0); int newQuantity = quantity + increase; int newBytes = newQuantity * size; int oldBytes = quantity * size; unsigned char* b = new unsigned char[newBytes]; for(int i = 0; i < oldBytes; i++) b[i] = storage[i]; // Copy old to new delete [](storage); // Old storage storage = b; // Point to new memory quantity = newQuantity; } Stash::~Stash() { if(storage != 0) { delete []storage; } } ///:~
C++ Code:
//: C06:Stash2Test.cpp //{L} Stash2 // Constructors & destructors #include "Stash2.h" #include "../require.h" #include <fstream> #include <iostream> #include <string> using namespace std; int main() { Stash intStash(sizeof(int)); for(int i = 0; i < 100; i++) intStash.add(&i); for(int j = 0; j < intStash.count(); j++) << *(int*)intStash.fetch(j) << endl; const int bufsize = 80; Stash stringStash(sizeof(char) * bufsize); ifstream in("Stash2Test.cpp"); assure(in, " Stash2Test.cpp"); string line; while(getline(in, line)) stringStash.add((char*)line.c_str()); int k = 0; char* cp; while((cp = (char*)stringStash.fetch(k++))!=0) << cp << endl; } ///:~ Stack with constructors & destructors //: C06:Stack3.h // With constructors/destructors #ifndef STACK3_H #define STACK3_H class Stack { struct Link { void* data; Link* next; Link(void* dat, Link* nxt); ~Link(); }* head; public: Stack(); ~Stack(); void push(void* dat); void* peek(); void* pop(); }; #endif // STACK3_H ///:~
C++ Code:
Stack không chỉ có một hàm tạo và hàm hủy mà còn có thể chồng các lớp vào nhau //: C06:Stack3.cpp {O} // Constructors/destructors #include "Stack3.h" #include "../require.h" using namespace std; Stack::Link::Link(void* dat, Link* nxt) { data = dat; next = nxt; } Stack::Link::~Link() { delete data; } Stack::Stack() { head = 0; } void Stack::push(void* dat) { head = new Link(dat,head); } void* Stack::peek() { return head->data; } void* Stack::pop() { if(head == 0) return 0; void* result = head->data; Link* oldHead = head; head = head->next; delete oldHead; return result; } Stack::~Stack() { Link* cursor = head; while(head) { cursor = cursor->next; delete head; head = cursor; } head = 0; // Officially empty } ///:~Hàm tạo và hàm hủy được tự động gọi đến, cho nên người sử dụng lớp có thể tập trung thao tác với đối tượng mà không lo lắng về việc nó đã được khởi tạo và hủy như thế nào.C++ Code:
//: C06:Stack3Test.cpp //{L} Stack3 // Constructors/destructors #include "Stack3.h" #include "../require.h" #include <fstream> #include <iostream> #include <string> using namespace std; int main(int argc, char* argv[]) { requireArgs(argc, 1); // File name is argument ifstream in(argv[1]); assure(in, argv[1]); Stack textlines; string line; // Read file and store lines in the stack: while(getline(in, line)) textlines.push(new string(line)); // Pop the lines from the stack and print them: string* s; while((s = (string*)textlines.pop()) != 0) { delete s; } } ///:~
Đã được chỉnh sửa lần cuối bởi rox_rook : 06-04-2008 lúc 07:36 PM.
Tui cảnh cáo cậu lần chót, đọc nội qui bỏ code vào thẻ. Vì đây là sách mà tui rất thích nên tui không nỡ xóa hết code của cậu. Còn 1 lần nữa là tui del topic luôn nghe cậu !
- Cậu học C++ được bao lâu rồi, nếu dưới 3 tháng thì tui nghĩ cậu quên việc hiểu hết trong 1 ngày đi. Vì tui có giải thích cậu cũng không thể hiểu hết 1 lần được. Post những đoạn nhỏ nêu ra những cái cậu đã học và không hiểu tui sẽ giải thích, còn nếu post 1 đống như thế 1 lần nữa tui sẽ cho bài cậu vào thùng rác ngay !
HIC BÁC NGUÔI NÀO !!!DOẠN NÀY NÓI VỀ Storage Allocation BÁC CÓ THỂ GIẢI THÍCH Í CỦA NÓ VÀ DOAN CODE CUA NO LA GI KO A.EM LA THANH VIEN MOI NEN HOI GA MONG BAC THONG CAM
Code://: C06:Nojump.cpp//C06 LA??? // Can't jump past constructors class X { public: X(); }; X::X() {} void f(int i) { if(i < 10) { //! goto jump1; // Error: goto bypasses init//SAO CHO NAY LAI SAI HA BAC??? } X x1; // Constructor called here jump1: switch(i) { case 1 : X x2; // Constructor called here break; //! case 2 : // Error: case bypasses init//???LẠI SAI X x3; // Constructor called here break; } } int main() { f(9); f(11); }///:~
Đó là lỗi nhảy qua những điểm liên tục trong chuơng trình và đoạn đó dùng để nêu ra sự nghèo nàn trong việc dùng goto và switch, vì khi đối tượng được tạo ra. Giả sử nếu if điều kiện thỏa và điều kiện của switch thỏa, compiler nó vẫn kiểm tra xem có đối tượng nào đã đang được khởi tạo hay chưa. Và dù nó không thỏa điều kiện thì constructor cho đối tượng x2 vẫn được gọi, cũng như x1.
Đã được chỉnh sửa lần cuối bởi rox_rook : 06-04-2008 lúc 08:09 PM.
THANK BÁC NHIỀU VẬY XIN BÁC CHO EM BIT STASH O DAY DC SU DUNG LA TEN HAM HAY LA GÌ AH.VA Stash2.cpp VA Stash2.h KHÁC NHAU O CHO NAO AH
Nếu cậu không phân biêt được cả file .h và cpp thì tui thành thật khuyên cậu khỏi đọc nữa cho khổ. Đây là sách không phải cho beginner, cái này là intermediate. Trường nào mà dạy quái lạ thế này, bắt 1 thằng học ktế mà đi đọc code này thì tui cũng thua...
Stash2.cpp là tách ra để dễ quản lý : bao gồm các hàm thành viên.
Stash2.h : dữ liệu, prototype của các hàm thành viên.
Nói thật tui thực sự thấy tui quá rảnh khi ngồi giải thích với 1 người hoàn toàn mù về lập trình như cậu, có lẽ vì đây là cuốn sách có nhiều kỉ niệm với tôi nên tôi thực sự không nở nhìn nó mà làm ngơ, nhưng thôi cậu ráng mà tìm cách khác, vì 1 lần nữa tui phải nhắc lại : cậu không thể hiểu được những đoạn code trên nếu cậu chưa thực sự học qua C++.