Trang 1 trên tổng số 2 12 Cuối cùngCuối cùng
Từ 1 tới 10 trên tổng số 20 kết quả

Đề tài: [VC] Save an object 2 FILE

  1. #1
    Ngày gia nhập
    07 2006
    Bài viết
    166

    Mặc định [VC] Save an object 2 FILE

    Chào mọi người, mình hiện có một thắc mắc về vấn đề lưu một đối tượng vào một biến kiểu FILE. Giả sử lớp này được thiết như sau:
    Code:
    class MyClasss
    {
         int m_iSomething;// not important
    
         std::list<int> *m_mylist;
    
         MyClass* m_pNeighbors;
    };
    Bây giờ giả sử mình khai báo một đối tượng của lớp này:
    Code:
    MyClass myObject;
    Tiếp theo ví nhiều lí do nào đó mà ta phải lưu đối tượng myObject này vào một biến kiểu FILE* myFile (dùng kiểu biến này là bởi vì có nhiều tác dụng khác).
    (dùng fwrite(....)
    Vấn đề đặt ra ở đây là ta cần phải lưu các biến m_Mylist và m_pNeighbors riêng chứ không thể chỉ đơn thuần dùng hàm fwrite(&myObject, 1, 1, myFile);

    Ngoài ra vì phải lưu thêm biến con trỏ m_pNeighbors cũng là một biến kiểu MyClass nên dẫn đến việc phải lưu cả biến m_pNeighbors của thành phần này, cứ như vậy...

    Mình post vấn đề này của mình lên mong mong các bạn trao đổi và giúp đỡ


    Thanks a lot!
    Đã được chỉnh sửa lần cuối bởi vinhie47 : 13-09-2006 lúc 04:16 PM.

  2. #2
    Ngày gia nhập
    08 2006
    Bài viết
    18

    Vừa load được bộ Turbo C++. Mạn phép bác vinhie47, tui xin trả lời bằng đoạn code viết trong TurboC++.
    Phiên bản code này chưa đầy đủ (chưa load được đối tượng con neibor). Trong phiên bản tới chúng ta tiếp tục giải quyết vấn đề này. (nếu các bác test trong bộ compile khác thì copy từ chỗ //--- std lib đến cuối)

    Code:
    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    
    //--- std lib
    #include <list>
    #include <iostream>
    #include <fstream>
    
    //---------------------------------------------------------------------------
    
    #pragma argsused
    
    using namespace std;
    class MyClass
    {
    public:
    	int id;			  // object id
    
    public:	
    	list<int> m_mylist;
    	MyClass* m_pNeighbors;
    
    	MyClass& save(ostream& out) 
    	{
    		// save object-id
    		out << this->id << endl;
    
    		// save list data
    		out << m_mylist.size() << endl;
    		for (list<int>::iterator it = m_mylist.begin();
    					it != m_mylist.end(); it++)
    		{
    			out << *it << endl;
    		}
    
    		// save pointer
    		if (m_pNeighbors)
    		{
    			out << m_pNeighbors->id  << endl;
    		}
    		else
    		{
            	out << (int) 0  << endl;
    		}
    
    
    		return *this;
    	};
    
    	MyClass& load(istream& in)
    	{
    		// first load id
    		in >> this->id;
    
    		// load list data
    		int count;
    		in >> count;
    
    		for (int i = 0; i < count; i++)
    		{
    		   int val;
    		   in >> val;
    		   this->m_mylist.push_back(val);
    		}
    
    		// pass m_pNeighbors
    		int idNeighbors;
    		in >> idNeighbors;
    
    		if (!idNeighbors)
    		{
    			this->m_pNeighbors = NULL;
    		}
    		
         	return *this;
    	}
    
    	MyClass& dump(ostream& out) 
    	{
    		// dump object-id
    		out << "id: " << this->id << endl;
    
    		// dump list data
    
    		out << "list size: " << m_mylist.size() << endl;
    		out << "list data: ";
    		for (list<int>::iterator it = m_mylist.begin();
    					it != m_mylist.end(); it++)
    		{
    			out << *it << ", ";
    		}
    
    		out << endl;
    
    		// dump pointer
    		if (m_pNeighbors)
    		{
    			out << "NeighborsId: " << m_pNeighbors->id << endl;
    		}
    		else
    		{
            	out << "NeighborsId: " << (int) 0 << endl;
    		}
    
    
    		return *this;
    	};
    };
    
    int main(int argc, char* argv[])
    {
    	//--- save object
    	MyClass testOrgClass;
    	testOrgClass.id = 1;
    	testOrgClass.m_pNeighbors = NULL;
    
    	for (int i = 0; i <= 10; i++)
    	{
    		testOrgClass.m_mylist.push_back(i);		
    	}
    	ofstream outdata ("data.txt");
    	testOrgClass.save(outdata);
    	outdata.close();
    
    	// load object
    	ifstream indata ("data.txt");
    	MyClass testNewClass;
    	testNewClass.load(indata);
    	testNewClass.dump(cout);
    
    
    	return 0;
    }
    //---------------------------------------------------------------------------

  3. #3
    Ngày gia nhập
    07 2006
    Bài viết
    166

    Bác longdh chu đáo quá, reply luôn bằng code! (nhưng TC++3.0 thì làm sao mà chạy được cái code đó nhỉ )
    Vấn đề lưu biến m_mylist như trên chắc là ổn rồi, ý tưởng quan trọng ở đây đấy là cần phải ghi riêng biệt những thành phần được cấp phát động.

    Còn về vấn đề biến m_pNeighbors thì vẫn phức tạp, mình nghĩ là để làm được điều này thì mỗi biến kiểu MyClass sẽ được gán một Id (hình như bác longdh cũng có ý tưởng đấy thì phải), khi đó mỗi khi lưu một biến kiểu MyClass thì ta sẽ không lưu biến thành viên m_pNeighbors mà sẽ lưu lại cái Id của nó. Như vậy lúc nào đọc ra từ FILE sẽ dựa vào Id này mà trỏ nó đến.

    Mong các bạn cho ý kiến

    P/S: code hoàn chỉnh chưa có, mới chỉ nêu lên ý tưởng xem có hợp lý không thôi

  4. #4
    Ngày gia nhập
    08 2006
    Bài viết
    18

    Tranh thủ quảng cáo cho borland phát!
    Không phải Turbo C++ 3 đâu (cái này chạy trên DOS), Borland mới phát hành 1 bộ công cụ "turbo" mới: Turbo Delphi (+.NET), Turbo C++, Turbo C#
    (http://www.turboexplorer.com)
    Về vấn đề cấp phát động biến Neiborh thì đúng như vinhie47 nói, mình phải căn cứ vào id của object rồi nạp lên.
    Mình thấy có cái này rất hay cho các lập trình viên C khi muốn lưu trữ Object: (Lưu xuống file hoặc cơ sở dữ liệu quan hệ)
    C++ Object-Relational Persistence Framework (http://litesql.sourceforge.net/)

  5. #5
    Ngày gia nhập
    08 2006
    Nơi ở
    TpHCM
    Bài viết
    202

    theo tui nghĩ
    nếu vấn đề là ở chỗ *m_pNeighbors đã được giải phóng hay chưa
    nếu giải phóng rồi thì lưu id cũng vô ích, ngoại trừ khi từ id ta có thể gọi constructor để tạo được đối tượng cho *m_pNeighbors giống như cũ (khi đó phải xây dựng map từ id tới dữ liệu)

    còn nếu *m_pNeighbors chưa được giải phóng thì lưu luônn m_pNeighbors dưới dạng là một ssoos kieu long

  6. #6
    Ngày gia nhập
    07 2006
    Bài viết
    166

    Mặc định [VC] Save an object 2 FILE

    Trích dẫn Nguyên bản được gửi bởi nguyentuan2
    còn nếu *m_pNeighbors chưa được giải phóng thì lưu luônn m_pNeighbors dưới dạng là một ssoos kieu long
    Không rõ ý của bạn lắm nhưng với những biến con trỏ thì ta không thể lưu cùng với đối tượng chứa nó được, ví dụ với lớp sau:
    Code:
    class AnothorClass
    {
       char something;
       int *value;
    };
    sau đó ta khai báo một đối tượng của lớp này:
    Code:
    AnotherClass AnotherObject;
    sau một loạt các thao tác, ta muốn lưu đối tượng này lại, khi đó ta không thể lưu vào file như sau:
    Code:
    fwrite(&AnotherObject, sizeof(AnotherClass), 1, file);// wrong way
    mà phải làm như sau:
    Code:
    fwrite(&AnotherObject, sizeof(AnotherClass), 1, file);
    fwrite(AnotherObject->value, sizeof(int), 1, file);
    khi nào cần đọc ra thì làm như sau:
    Code:
    Object = new AnotherClass();
    fread(Object, sizeof(AnotherClass), 1, file);
    Object->value = new int;
    fread(Object->value, sizeof(int), 1, file);
    Không biết hình hiểu có đúng ý bạn không?

    Best regards!
    Đã được chỉnh sửa lần cuối bởi vinhie47 : 12-09-2006 lúc 11:44 PM.

  7. #7
    Ngày gia nhập
    08 2006
    Nơi ở
    Hải Phòng
    Bài viết
    218

    Em đồng tình với ý kiến của NguyenTuan2, nếu đối tượng vãn còn tồn tại trong bộ nhớ nghĩa là địa chỉ cấp phát cho nó vẫn tồn tại thì ta chỉ cần lưu lại địa chỉ đó, nói cách khác lưu lại giá trị của con trỏ trỏ tới đối tượng như cách anh vinhie47 làm ở trên.
    Còn khi đối tượng không còn tồn tại nữa ta sẽ phải lưu vào file mỗi đối tượng sẽ được gán cho một số Id và một con trỏ trỏ tới đối tượng đó sẽ được gán giá trị là ID đó. Và khi sử dụng ta sé phải thực hiện một bước map từ Id đên dữ liệu như anh NguyenTuan2 nói. Nhưng em vẫn chưa hiểu được bằng cách nào đưa được đối tượng trở lai bộ nhớ, em chỉ quen làm với Pascal và Pascal không trực tiếp hỗ trợ điều này vì đối tượng không chỉ đơn thuần là dữ liệu mà nó còn có những mối liên kết riêng với hệ thống để thực hiện được các phương thức. Không biết theo cách làm của 2 anh thì có lưu trữ và sử dụng được cả các phương thức của đối tượng hay không

  8. #8
    Ngày gia nhập
    07 2006
    Bài viết
    166

    Trích dẫn Nguyên bản được gửi bởi hailoc12
    Không biết theo cách làm của 2 anh thì có lưu trữ và sử dụng được cả các phương thức của đối tượng hay không
    Khi lưu đối tượng ta chỉ cần quan tâm phần dữ liệu của nó, còn nếu đúng là đối tượng của lớp nào thì dĩ nhiên nó phải có đầy đủ các phương thức của lớp đó rồi.

    Tóm lại vấn đề mà mình nêu ra ở đây chỉ là lưu một đối tượng của một lớp A vào bộ nhớ (có thể là buffer, trên disk,....) trong đó lớp A này chứa nhiều thành phần dữ liệu được cấp phát động và kiểu dữ liệu phức tạp (có thể một biến thành viên là một đối tượng lớp B trong khi lớp B lại chứa biến thành viên có kiểu dữ liệu là lớp A,....).

  9. #9
    Ngày gia nhập
    08 2006
    Bài viết
    18

    Đúng như vinhie47 nói, khi lưu đối tượng ta chỉ cần lưu thông tin về dữ liệu của lớp. Theo như yêu cầu ban đầu của bạn í, việc lưu đối tượng xuống file (đối tượng lưu trữ bền vững) là giúp quá trình phục hồi lại các đối tượng sau này (ví dụ chạy lại phiên làm việc cũ của chương trình, replication các distrbuted objects,...). Nếu theo như bạn NguyenTuan2 nói, ta chỉ cần lưu trữ con trỏ tới đối tượng con thì sẽ rất nguy hiểm trong quán trình phục hồi đối tượng.
    Đã được chỉnh sửa lần cuối bởi longdh : 13-09-2006 lúc 02:14 AM.

  10. #10
    Ngày gia nhập
    07 2006
    Bài viết
    166

    Chán thật thấy vấn đề mà mình gặp phải cũng thấy hay hay post lên tí cho vui mà ít người tham gia quá. Mà việc lưu trữ lại trạng thái của một chương trình thì lại gặp rất nhiều trong khi lập trình.

    Các bác rảnh rỗi thì ghé thăm http://www.parashift.com/c++-faq-lit...alization.html tí chơi, riêng về cái vấn đề này mà nó chia ra làm đến chục trường hợp chứ chẳng vừa

Các đề tài tương tự

  1. Error:Object reference not set to an instance of an object.Không khởi chạy được file Global.asax
    Gửi bởi nightelf trong diễn đàn Thắc mắc lập trình C#
    Trả lời: 0
    Bài viết cuối: 16-04-2013, 12:10 PM
  2. Lổi Session Object reference not set to an instance of an object file Hendler.ashx
    Gửi bởi vuanphuong trong diễn đàn Thắc mắc lập trình ASP.NET
    Trả lời: 2
    Bài viết cuối: 22-04-2012, 10:22 PM
  3. Trả lời: 8
    Bài viết cuối: 15-08-2011, 12:42 PM
  4. tạo store procedures trong SQL lúc save sao không hiển thị trong object explorer
    Gửi bởi lapmaihokdc trong diễn đàn Thắc mắc lập trình ASP.NET
    Trả lời: 6
    Bài viết cuối: 30-05-2011, 10:08 AM
  5. [Solved]Save một file vào db
    Gửi bởi nthung trong diễn đàn Thắc mắc đại cương Database & Reporting
    Trả lời: 1
    Bài viết cuối: 13-04-2008, 06:24 PM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn