全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1888
推到 Plurk!
推到 Facebook!

TStringList s1[100] 在run時為何會出現錯誤呢?

答題得分者是:axsoft
tommylee926
一般會員


發表:24
回覆:25
積分:9
註冊:2003-08-17

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-08-26 17:20:15 IP:211.75.xxx.xxx 未訂閱
TStringList s1[100]; 或TStringList *s1 = new TStringList[100]; 都會出現 access violation呢? 要怎麼解決呢?
RaynorPao
版主


發表:139
回覆:3622
積分:7025
註冊:2002-08-12

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-08-26 17:35:36 IP:203.73.xxx.xxx 未訂閱
引言: TStringList s1[100]; 或TStringList *s1 = new TStringList[100]; 都會出現 access violation呢? 要怎麼解決呢?
tommylee926 你好:
(1)請問?? 你的目的是什麼呢?? 也許你的目的跟表示方法差很多喔
( >
   >    -- 
        
------
-- 若您已經得到滿意的答覆,請適時結案!! --
-- 欲知前世因,今生受者是;欲知來世果,今生做者是 --
-- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 --
axsoft
版主


發表:681
回覆:1056
積分:969
註冊:2002-03-13

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-08-26 17:44:23 IP:61.218.xxx.xxx 未訂閱
引言: TStringList s1[100]; 或TStringList *s1 = new TStringList[100]; 都會出現 access violation呢? 要怎麼解決呢?
tommylee926 您好: 參閱community.borland.com How do I create an array of TStringList? http://www.rxlib.ru/faqs/faqc_en/10538.html
/*開心的事情別隱藏在心裡,分享給別人知道會更快樂的*/
/*得到新知識別隱藏在心裡,分享給別人了解會更清楚的*/
axsoft
版主


發表:681
回覆:1056
積分:969
註冊:2002-03-13

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-08-26 18:02:10 IP:61.218.xxx.xxx 未訂閱

TStringList as a template array class

By David Bridges 資料來源: http://www.bridgespublishing.com/articles/issues/0101/TStringList_as_a_template_array_class.htm There are many container and array classes available for use with C Builder, such as the ones in the Standard Template Library (STL) that ships with all versions. Often, however, I like a “quick and easy” alternative to using these classes, which frequently have a high overhead of coding, and impose requirements on the type of objects that you put into an array. C Builder’s Visual Component Library contains a few types of simple array classes, and among them is TStringList. TStringList is ideal for storing an array of strings. It has built-in methods for adding, deleting, sorting, finding, etc. One important feature that it also has is the ability to store an additional user-defined value along with each string. This value is accessed via the Objects property, which works just like the Strings property except that it returns objects of type TObject*. The Objects property greatly extends the capabilities of TStringList. Because you can store pointers to any type of object, TStringList can be used as a container class for any type of object you can think of. However, there are a few drawbacks to using TStringList this way. First, in order to store and then retrieve your object pointers using the Objects property, you must always cast the pointers back and forth from between your type and TObject*. Second, there is no ownership defined for the objects in a TStringList. This means that when the TStringList object is deleted, any associated pointers contained in Objects are not deleted. You must manually delete all objects yourself in order to avoid a memory leak. For example:
class MyClass
{
  public:
  AnsiString sValue;
  MyClass(AnsiString sInValue) { sValue = sInValue; }
};    // Create the list
TStringList* mylist = new TStringList();    // Add objects to the list
mylist->AddObject("1", (TObject*) new MyClass("First"));
mylist->AddObject("2", (TObject*) new MyClass("Second"));    // Read objects from the list
for (int i=0;i< mylist->Count;i  ) {
  MyClass* nextobj = (MyClass*)(mylist->Objects[i]);
  MessageBox(NULL, nextobj->sValue.c_str(), "Next Object:", MB_OK);
}    // Delete the objects
for (int i=0;i< mylist->Count;i  ) {
  MyClass* nextobj = (MyClass*)(mylist->Objects[i]);
  delete nextobj;
}    // Free the list
delete mylist;
As you can see, the code isn’t very pretty. We continually have to cast back and forth between TObject and the actual class we’re using for the objects. Also, we must manually delete all of the objects when we’re done with them. But we do get some good benefits from using the TStringList class: we can sort the list based on the string values (“1” and “2”, in this case), we can iterate through the list, and use all of the other methods and properties of TStringList. The ObjectList class The ObjectList class solves the casting problem and the deleting problem. One of my requirements in designing this class is that it imposes no restrictions upon the class of objects that it holds. The class doesn’t have to be derived from TObject, doesn’t have to have any operators defined, etc. In fact, it can be absolutely any type you want. Also, it should have a simple way to handle ownership of its objects. The listing for this class is shown in Listing A. Before explaining any further, let’s revisit the first example, but using the ObjectList class instead:
    typedef ObjectList MyObjectList;    MyObjectList* myobjects = new MyObjectList(true);    // Add objects to the list
myobjects->AddItem("1", new MyClass("First"));
myobjects->AddItem("2", new MyClass("Second"));    // Read objects from the list
for (int i=0;iCount;i  ) {
  MyClass* nextobj = myobjects->Items[i];
  MessageBox(NULL, nextobj->sValue.c_str(), "Next Object:", MB_OK);
  }    // Free the list, which will delete all objects.
delete myobjects;
The AddItem() method replaces the AddObject() method of TStringList. It takes a string and a pointer to an object of the class used in the template definition (in this case, MyClass). There is also a method called AddNewItem(). This works exactly the same as AddItem(), but it adds a new copy of the original object to the list, instead of the object itself. This sometimes saves writing code to allocate a new object each time. The only restriction is that the object should have a copy constructor. The Items property replaces the Objects property of TStringList. It returns an object of the desired class, instead of a TObject pointer. As you can see from the class constructor, the default behavior of the class is to sort the list and accept duplicates. It will sort based on whatever you have supplied as the string parameter in the AddItem() method. This gives a lot of flexibility since you can generate any kind of sort key you want for an object (or have the object create its own). The ObjectList class has the ability to take ownership if the objects it contains. The class constructor takes one parameter, which is a flag indicating whether the list owns its objects. If it owns the objects, they will be automatically deleted when the list is deleted. If not, then you are responsible for deleting them. You can always override this ownership flag however, by using the ClearItems() method. If you pass true to ClearItems(), the list will be emptied and each of it’s objects will be deleted. Passing false to ClearItems() will empty the list without deleting the objects. One final thing to mention is that this provides a good example of creating properties in a class—in this case, the Items property. This is a very typical example of a read/write property and its associated read and write methods. This happens to be an indexed property so the read method looks like this:
    T* GetItem(int index)         The write method is declared like this:         void SetItem(int index, T* ptr)     
If it were not an indexed property, the read and write methods would be identical but lacking the index parameters. The __property keyword ties these together and specifies that these functions actually get called when you read or write the Items property. Conclusion By using the built-in power of the TStringList class and extending it by creating a template class that can handle any data type, we have created a very capable array class that can take advantage of all of the common array functions.
template  class ObjectList : 
  public TStringList
{
  public:      // Set OwnsObjects to true if the objects should automatically be 
  // deleted when the list is destroyed.
  bool OwnsObjects;      __fastcall ObjectList(bool bOwnsObjects = false) : TStringList()
  {
    Duplicates = dupAccept;
    Sorted = true;
    OwnsObjects = bOwnsObjects;
  }      __fastcall ~ObjectList()
  {
    ClearItems(OwnsObjects);
  }      int AddItem(AnsiString sValue, T* ptr)
  {
    int index = Add(sValue);
    Objects[index] = (TObject*)ptr;
    return index;
  }      int AddNewItem(AnsiString sValue, T* ptr)
  {
    T* newptr = new T;
    *newptr = *ptr;
    return AddItem(sValue, newptr);
  }      T* GetItem(int index)
  {
    return (T*)Objects[index];
  }      void SetItem(int index, T* ptr)
  {
    Objects[index] = (TObject*)ptr;
  }      void ClearItems(bool Delete)
  {
    if (Delete) {
      for (int i=0;i
Copyright © 2003, Bridges Publishing. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of Bridges Publishing is prohibited. All other product names and logos are trademarks or registered trademarks of their respective owners.    
/*開心的事情別隱藏在心裡,分享給別人知道會更快樂的*/
/*得到新知識別隱藏在心裡,分享給別人了解會更清楚的*/
tommylee926
一般會員


發表:24
回覆:25
積分:9
註冊:2003-08-17

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-08-26 18:20:49 IP:163.22.xxx.xxx 未訂閱
那為何 TStringList *s1 = new TStringList[100]; 不行呢?????
axsoft
版主


發表:681
回覆:1056
積分:969
註冊:2002-03-13

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-08-27 11:43:42 IP:61.218.xxx.xxx 未訂閱
引言: 那為何 TStringList *s1 = new TStringList[100]; 不行呢?????
The reason you are getting th AV(Access violation) is VCL objects must be created on the heap.
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
    const int HowMany = 4;
    TStringList *Spring[HowMany];        for(int i = 0; i < HowMany; i++)
        Spring[i] = new TStringList;        Spring[0]->Add("Joseph");
    Spring[0]->Add("Michael");
    Spring[0]->Add("Caroline");
    Spring[0]->Add("Helene");
    Spring[0]->Add("Adam");        Spring[1]->Add("Mauricette");
    Spring[1]->Add("Mark");
    Spring[1]->Add("Gertrude");        Spring[2]->Add("Lydia");
    Spring[2]->Add("Annette");
    Spring[2]->Add("Pauline");
    Spring[2]->Add("Esther");        Spring[3]->Add("Said");
    Spring[3]->Add("Amidou");
}
//---------------------------------------------------------------------------
/*開心的事情別隱藏在心裡,分享給別人知道會更快樂的*/
/*得到新知識別隱藏在心裡,分享給別人了解會更清楚的*/
發表人 - axsoft 於 2003/08/27 11:55:28
tommylee926
一般會員


發表:24
回覆:25
積分:9
註冊:2003-08-17

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-08-29 15:27:54 IP:211.75.xxx.xxx 未訂閱
The reason you are getting th AV(Access violation) is VCL objects must be created on the heap. ==================================================================== 這句話是不是說所有的vcl object要new的話,一定都要像tstringlist一樣的方法嗎? 對了,大大我有一句話不懂就是 "VCL objects must be created on the heap." 中的heap是指啥呢? 所有的vcl object 都要在序列上被creat <======怪怪地 ????
系統時間:2024-05-14 20:33:29
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!