Từ 1 tới 7 trên tổng số 7 kết quả

Đề tài: Lớp chung

  1. #1
    Ngày gia nhập
    08 2008
    Bài viết
    48

    Mặc định Lớp chung

    Tớ mới học về lớp chung, thật sự còn mơ màng nên có bài tập như thế này mà không biết phải sửa như thế nào. Nội dung của nó là: Xây dựng lớp CStack chung(mẫu) mô tả ngăn xếp chung, sau đó xây dựng chương trình ứng dụng CStack mẫu cho kiểu dữ liệu là struct SV có các thuộc tính: họ tên, quê quán, năm sinh, điểm trung bình.
    C++ Code:
    1. #include<iostream>
    2. using namespace std;
    3. struct SinhVien{
    4.     char hoTen[25];
    5.     char queQuan[30];
    6.     int namSinh;
    7.     float diemTB;
    8. };
    9. SinhVien SV[100];//khai bao mot mang 100 phan tu co kieu struct la SinhVien
    10. template<class StackType>class CStack{
    11.     StackType ds[100];
    12.     int pos;
    13.     int size;
    14. public:
    15.     CStack(int n){size=n; pos=0;}
    16.     void Push(StackType);
    17.     StackType Pop();
    18.  
    19. };
    20. template<class StackType> void CStack<StackType>::Push(StackType ch)
    21. {
    22.     if (pos==size)
    23.     {
    24.         cout<<"\n Stack full";
    25.         return;
    26.     }
    27.     ds[pos]=ch;
    28.     pos++;
    29.  
    30. }
    31. template<class StackType> StackType CStack<StackType>::Pop()
    32. {
    33.     if (pos==0)
    34.     {
    35.         cout<<"\n Stack empty";
    36.         return 0;
    37.     }
    38.     pos--;
    39.     return ds[pos];
    40.  
    41. }
    42. void main()
    43. {
    44.     int n;
    45.     cout<<"Ban muon nhap bao nhieu Sinh Vien ha? ";
    46.     cin>>n;
    47.     cout<<"\nNhap noi dung cua cac SV";
    48.     for (int i=0; i<n; i++){
    49.         cout<<"\nSinh vien thu "<<i<<"\n";
    50.         cout<<"\nho ten";
    51.         cin.getline(SV[i].hoTen,25);
    52.         cout<<"\nque quan";
    53.         cin.getline(SV[i].queQuan,30);
    54.         cout<<"\nnam sinh";
    55.         cin>>SV[i].namSinh;
    56.         cout<<"\ndiem trung binh";
    57.         cin>>SV[i].diemTB;
    58.     }
    59.     CStack<SinhVien>SV[100];
    60.     for(int i = 0;i<n;i++)
    61.         SV[i].Push(i);
    62.     cout<<"\n Stack Int: ";
    63.     for(int i=0; i<n; i++)
    64.         cout<<SV[i].Pop();
    65.     cin.get();
    66. }
    Đã được chỉnh sửa lần cuối bởi hahonga3 : 30-11-2008 lúc 03:45 PM.
    Hạnh phúc luôn đợi ta mỉn cười lại với nó.(^,,^).

  2. #2
    Ngày gia nhập
    11 2008
    Nơi ở
    Neverland
    Bài viết
    48

    Mình chưa học về Template nhưng thấy bài của bạn sai vài chỗ rồi còn chỉnh sửa thế nào có lẽ phải nhờ anh R2 .
    C++ Code:
    1. CStack<SinhVien>SV[100];//Khai báo trùng tên với mảng SinhVien toàn cục với lại bạn tạo ra 100 đối tượng CStack làm gì chứ
    Chỗ này nữa :
    C++ Code:
    1.   for(int i = 0;i<n;i++)
    2.         SV[i].Push(i);
    3.     cout<<"\n Stack Int: ";
    4.     for(int i=0; i<n; i++)
    5.         cout<<SV[i].Pop();
    Bạn dùng Stack kiểu này tức là đẩy mỗi chỉ số Sinh Viên vào và mỗi Stack lưu chỉ số một sinh viên --> mất hết ý nghĩa của Stack xài kiểu này mình thấy dùng mảng còn hơn .
    C++ Code:
    1. StackType ds[100];//Bạn để ý chỗ này thực ra Stack là một Container và một đối tượng Stack đã có thể lưu một tập các đối tượng nào đó rồi thông qua các thao tác đẩy vào lấy ra .
    Khi đó hàm main dùng Stack chỉ cần :
    C++ Code:
    1. CStack<SinhVien*> svStack;
    2. for (int i=0;i<n;i++)
    3.     svStack.Push(&SV[i]);
    Mình nghĩ trước khi viết template hãy học cách dùng các STL sẵn có trước đã rồi mới có nền tảng để thiết kế template được ( như mình bây giờ học hành chậm chạp giờ mới biết xài mỗi thằng vector ) . Bài này với trình độ mình bây giờ chỉ biết dùng mỗi cách dùng void* cho Stack để đạt được cái "Stack có thể chứa bất cứ thứ gì" chứ còn dùng Template thì chịu . Hix bao giờ mới được như anh R2 .
    Đã được chỉnh sửa lần cuối bởi trung_dk070384 : 30-11-2008 lúc 07:11 PM.
    I'm superman

  3. #3
    Ngày gia nhập
    08 2008
    Bài viết
    48

    hi`.Tớ dùng template là vì bị "ép buộc". Sai chỗ nào tớ cũng biết nhưng sửa thế nào thì...!
    Hạnh phúc luôn đợi ta mỉn cười lại với nó.(^,,^).

  4. #4
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    C++ Code:
    1. CStack<SinhVien>SV[100];
    -> Chỗ này khởi tạo mãng mà không có default-constructor, Cái này có rất nhiều cách giải quyết, rảnh tui sẽ post hết cho cậu. Chỗ này tui dùng kĩ thuật partial specialization, dễ hiểu và code sáng sủa.
    C++ Code:
    1. cout<<SV[i].Pop();
    Pop() trả về dữ liệu kiểu StackType trong khi StackType không có overload operator << thì làm sao chạy được ?
    C++ Code:
    1. for(int i = 0;i<n;i++)
    2.         SV[i].Push(i);
    SV là kiểu SinhVien làm sao push( integer ) ?
    C++ Code:
    1. #include <iostream>
    2. #include <cstdlib>
    3.  
    4. using namespace std;
    5.  
    6. struct SinhVien
    7. {
    8.     char  hoTen[ 25 ];
    9.     char  queQuan[ 30 ];
    10.     int   namSinh;
    11.     float diemTB;
    12.  
    13. public :
    14.     friend
    15.     ostream& operator <<( ostream& o, const SinhVien& sv ) {
    16.         return o << sv.hoTen << "->" << sv.queQuan << "->" << sv.namSinh << "->" << sv.diemTB << endl;
    17.     }
    18.  
    19.     friend
    20.     istream& operator >>( istream& i, SinhVien& sv ) {
    21.         cout << "\nTen : ";
    22.         i.getline( sv.hoTen, 25 );
    23.         cout << "\nQue Quan : ";
    24.         i.getline( sv.queQuan, 30 );
    25.         cout << "\nNam Sinh : ";
    26.         i >> sv.namSinh;
    27.         cout << "\nDiem Trung Binh : ";
    28.         i >> sv.diemTB;
    29.         return i;
    30.     }
    31. };
    32.  
    33. template< class StackType, int SIZE >
    34. class CStack
    35. {
    36.     StackType ds[ SIZE ];
    37.     int pos;
    38. public:
    39.     CStack():pos( 0 ) {
    40.     }
    41.     void Push( const StackType& );
    42.     StackType Pop();
    43.  
    44. };
    45.  
    46. template< class StackType, int SIZE >
    47. void CStack< StackType, SIZE >::Push( const StackType& ch )
    48. {
    49.     if( pos == SIZE )
    50.     {
    51.         cout << "\n Stack full";
    52.         return;
    53.     }
    54.  
    55.     ds[ pos ] = ch;
    56.     pos++;
    57. }
    58.  
    59. template< class StackType, int SIZE >
    60. StackType CStack< StackType, SIZE >::Pop()
    61. {
    62.     if( pos == 0 ) {
    63.         cout << "\n Stack empty";
    64.         exit( 1 );
    65.     }
    66.     pos--;
    67.     return ds[ pos ];
    68.  
    69. }
    70.  
    71. int main()
    72. {
    73.     CStack< SinhVien, 100 > svStack;
    74.  
    75.     SinhVien sv;
    76.     cin >> sv;
    77.     svStack.Push( sv );
    78.     cout << svStack.Pop();
    79.     return 0;
    80. }

  5. #5
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    Cách này thì khỏi cần dùng default-constructor mà vẫn tạo được mãng của stack.
    C++ Code:
    1. #include <iostream>
    2. #include <cstdlib>
    3.  
    4. using namespace std;
    5.  
    6. struct SinhVien
    7. {
    8.     char  hoTen[ 25 ];
    9.     char  queQuan[ 30 ];
    10.     int   namSinh;
    11.     float diemTB;
    12.  
    13. public :
    14.     friend
    15.     ostream& operator <<( ostream& o, const SinhVien& sv ) {
    16.         return o << sv.hoTen << "->" << sv.queQuan << "->" << sv.namSinh << "->" << sv.diemTB << endl;
    17.     }
    18.  
    19.     friend
    20.     istream& operator >>( istream& i, SinhVien& sv ) {
    21.         cout << "\nTen : ";
    22.         i.getline( sv.hoTen, 25 );
    23.         cout << "\nQue Quan : ";
    24.         i.getline( sv.queQuan, 30 );
    25.         cout << "\nNam Sinh : ";
    26.         i >> sv.namSinh;
    27.         cout << "\nDiem Trung Binh : ";
    28.         i >> sv.diemTB;
    29.         return i;
    30.     }
    31. };
    32.  
    33. const int SIZE = 100;
    34. template< class StackType >
    35. class CStack
    36. {
    37.     StackType ds[ SIZE ];
    38.     int pos;
    39.     int size;
    40. public:
    41.     CStack( int size ):pos( 0 ), size( size ) {
    42.     }
    43.     void Push( const StackType& );
    44.     StackType Pop();
    45.  
    46. };
    47.  
    48. template< class StackType >
    49. void CStack< StackType >::Push( const StackType& ch )
    50. {
    51.     if( pos == SIZE )
    52.     {
    53.         cout << "\n Stack full";
    54.         return;
    55.     }
    56.  
    57.     ds[ pos ] = ch;
    58.     pos++;
    59. }
    60.  
    61. template< class StackType >
    62. StackType CStack< StackType >::Pop()
    63. {
    64.     if( pos == 0 ) {
    65.         cout << "\n Stack empty";
    66.         exit( 1 );
    67.     }
    68.     pos--;
    69.     return ds[ pos ];
    70.  
    71. }
    72.  
    73. int main()
    74. {
    75.     /* Tạo 1 mãng stack sinh viên */
    76.     CStack< SinhVien >** svStack = new CStack< SinhVien >*[ 10 ];
    77.  
    78.     for( int o = 0; o < 10; ++o ) {
    79.         svStack[ o ] = new CStack< SinhVien >( o + 1 );
    80.     }
    81.  
    82.     SinhVien sv;
    83.     cin >> sv;
    84.     ( svStack[ 0 ] )->Push( sv );
    85.     cout << svStack[ 0 ]->Pop();
    86.  
    87.     // Giải phóng resource
    88.     for( int o = 0; o < 10; ++o ) {
    89.         delete[] svStack[ o ];
    90.     }
    91.     delete[] svStack;
    92.  
    93.     return 0;
    94. }
    Một cách more-robust nhưng khó đọc hơn, placement-new và placement delete :
    C++ Code:
    1. int main()
    2. {
    3.     const int SIZE_OF_ARRAY_STACK = 10;
    4.     void* raw_memory = operator new[]( SIZE_OF_ARRAY_STACK * sizeof( CStack< SinhVien > ) );
    5.  
    6.     CStack< SinhVien >* ary_of_stack = static_cast< CStack< SinhVien >* >( raw_memory );
    7.     for( int o = 0; o < SIZE_OF_ARRAY_STACK; ++o ) {
    8.         new( &ary_of_stack[ o ] )CStack< SinhVien >( o + 1 );
    9.     }
    10.  
    11.  
    12.     SinhVien sv;
    13.     cin >> sv;
    14.     ary_of_stack[ 0 ].Push( sv );
    15.     cout << ary_of_stack[ 0 ].Pop();
    16.  
    17.     // Giải phóng ngược thứ tự khởi tạo *NOTE
    18.     for( int o = SIZE_OF_ARRAY_STACK - 1; o >= 0; --o ) {
    19.         ary_of_stack[ o ].~CStack();
    20.     }
    21.     operator delete[]( raw_memory );
    22.  
    23.     return 0;
    24. }

  6. #6
    Ngày gia nhập
    08 2008
    Bài viết
    48

    Mặc định Lớp chung

    Cho tớ hỏi 2 vấn đề về bài trả lời của bạn RR là:
    1. Tại sao nhất định phải có từ khóa "friend" trong 2 hàm:
    friend
    ostream& operator <<( ostream& o, const SinhVien& sv ) {

    và: friend
    istream& operator >>( istream& i, SinhVien& sv ) {

    2. Ở bài RR post lần đâu tiên biến int SIZE để làm gì? nó ở đây
    template< class StackType, int SIZE >
    class CStack
    {
    StackType ds[ SIZE ];
    int pos;
    public:
    CStack():pos( 0 ) {
    }
    void Push( const StackType& );
    StackType Pop();

    };
    Hạnh phúc luôn đợi ta mỉn cười lại với nó.(^,,^).

  7. #7
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    - Để friend hay không chỗ đó cũng work( vì đây không phải là class ), nhưng lý do tui để bên trong vì đơn giản mình muốn nó là inline. Nếu không dùng friend thì phải để ở ngoài như sau :
    C++ Code:
    1. inline ostream& operator <<( ostream& o, const SinhVien& sv ) {
    2.     return o << sv.hoTen << "->" << sv.queQuan << "->" << sv.namSinh << "->" << sv.diemTB << endl;
    3. }
    4.  
    5.  
    6. inline istream& operator >>( istream& i, SinhVien& sv ) {
    7.     cout << "\nTen : ";
    8.     i.getline( sv.hoTen, 25 );
    9.     cout << "\nQue Quan : ";
    10.     i.getline( sv.queQuan, 30 );
    11.     cout << "\nNam Sinh : ";
    12.     i >> sv.namSinh;
    13.     cout << "\nDiem Trung Binh : ";
    14.     i >> sv.diemTB;
    15.     return i;
    16. }
    - Còn việc biến dùng biến int SIZE vì code của cậu dùng mãng là internal structure và 2 thằng này thường là tightly-coupling. Viết kiểu đó code cậu sẽ flexible hơn vì cậu không phải hardcode, cậu thích dùng bao nhiêu at runtime thì cậu chỉ việc thêm 1 biến vào, đó là lợi thế của partial-specialization. Nhưng đó chỉ là 1 design giúp code trên tốt hơn 1 tí thôi, vì cái lỗi chính của cậu vẫn là cậu đã khởi tạo mãng stack mà không có default-constructor. Hai kĩ thuật cuối đều có thể dùng được, nhưng có lẽ hơi advance, cậu coi cho biết cũng được.
    - Tui thêm cho cậu 1 cách :
    C++ Code:
    1. #include <iostream>
    2. #include <cstdlib>
    3.  
    4. using namespace std;
    5.  
    6. struct SinhVien
    7. {
    8.     char  hoTen[ 25 ];
    9.     char  queQuan[ 30 ];
    10.     int   namSinh;
    11.     float diemTB;
    12.  
    13. };
    14.  
    15. inline ostream& operator <<( ostream& o, const SinhVien& sv ) {
    16.     return o << sv.hoTen << "->" << sv.queQuan << "->" << sv.namSinh << "->" << sv.diemTB << endl;
    17. }
    18.  
    19.  
    20. inline istream& operator >>( istream& i, SinhVien& sv ) {
    21.     cout << "\nTen : ";
    22.     i.getline( sv.hoTen, 25 );
    23.     cout << "\nQue Quan : ";
    24.     i.getline( sv.queQuan, 30 );
    25.     cout << "\nNam Sinh : ";
    26.     i >> sv.namSinh;
    27.     cout << "\nDiem Trung Binh : ";
    28.     i >> sv.diemTB;
    29.     return i;
    30. }
    31.  
    32. const int SIZE = 100;
    33.  
    34. template< class StackType >
    35. class CStack
    36. {
    37.     int  pos;
    38.     int  size;
    39.     int* ds;
    40. public:
    41.     CStack( int size = SIZE )
    42.         :pos( 0 ), size( size ), ds( new int[ size ] )  {
    43.     }
    44.     ~CStack() {
    45.         delete[] ds;
    46.     }
    47.  
    48.     void Push( const StackType& );
    49.     StackType Pop();
    50.  
    51. };
    52.  
    53. template< class StackType >
    54. void CStack< StackType >::Push( const StackType& ch )
    55. {
    56.     if( pos == SIZE )
    57.     {
    58.         cout << "\n Stack full";
    59.         return;
    60.     }
    61.  
    62.     ds[ pos ] = ch;
    63.     pos++;
    64. }
    65.  
    66. template< class StackType >
    67. StackType CStack< StackType >::Pop()
    68. {
    69.     if( pos == 0 ) {
    70.         cout << "\n Stack empty";
    71.         exit( 1 );
    72.     }
    73.     pos--;
    74.     return ds[ pos ];
    75.  
    76. }
    77.  
    78. int main()
    79. {
    80.     CStack< int > s;
    81.     s.Push( 1 );
    82.  
    83.     return 0;
    84. }
    Hoặc dùng vector<>, giải pháp tui cảm thấy tiện lợi nhất :
    C++ Code:
    1. #include <iostream>
    2. #include <cstdlib>
    3. #include <vector>
    4.  
    5. using namespace std;
    6.  
    7. struct SinhVien
    8. {
    9.     char  hoTen[ 25 ];
    10.     char  queQuan[ 30 ];
    11.     int   namSinh;
    12.     float diemTB;
    13.  
    14. };
    15.  
    16. inline ostream& operator <<( ostream& o, const SinhVien& sv ) {
    17.     return o << sv.hoTen << "->" << sv.queQuan << "->" << sv.namSinh << "->" << sv.diemTB << endl;
    18. }
    19.  
    20.  
    21. inline istream& operator >>( istream& i, SinhVien& sv ) {
    22.     cout << "\nTen : ";
    23.     i.getline( sv.hoTen, 25 );
    24.     cout << "\nQue Quan : ";
    25.     i.getline( sv.queQuan, 30 );
    26.     cout << "\nNam Sinh : ";
    27.     i >> sv.namSinh;
    28.     cout << "\nDiem Trung Binh : ";
    29.     i >> sv.diemTB;
    30.     return i;
    31. }
    32.  
    33. const int SIZE = 100;
    34.  
    35. template< class StackType >
    36. class CStack
    37. {
    38.     int                 size;
    39.     vector< StackType > internal_data;
    40. public:
    41.     CStack( int size = SIZE )
    42.         :size( size ), internal_data( size ) {
    43.     }
    44.  
    45.     void Push( const StackType& );
    46.     StackType Pop();
    47.  
    48. };
    49.  
    50. template< class StackType >
    51. void CStack< StackType >::Push( const StackType& ch )
    52. {
    53.     internal_data.push_back( ch );
    54.     size++;
    55. }
    56.  
    57. template< class StackType >
    58. StackType CStack< StackType >::Pop()
    59. {
    60.     StackType top_item = internal_data[ size - 1 ];
    61.     size--;
    62.     internal_data.pop_back();
    63.     return top_item;
    64. }
    65.  
    66. int main()
    67. {
    68.     CStack< int > s;
    69.     s.Push( 1 );
    70.     s.Push( 2 );
    71.  
    72.     int x = s.Pop();
    73.     cout << x << endl;
    74.  
    75.     return 0;
    76. }

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

  1. @Chung cư mini mỹ đình ,chung cư làng bún phú đô, Chung cư diện tích nhỏ
    Gửi bởi ephat_tt86 trong diễn đàn Giới thiệu website, sản phẩm của bạn
    Trả lời: 0
    Bài viết cuối: 18-11-2011, 10:29 AM

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