operator

Ngoài việc sử dụng các hàm chồng toán tử (operator) để thực hiện 4 phép toán +,-,*,/ còn có định nghĩa chồng các phép toán << và >>để xuất, nhập các đối tượng của một lớp bất kỳ do người dùng định nghĩa. Có thể xây dựng các toán tử để thực hiện các phép đọc nghi theo kiểu văn bản cũng như nhị phân. Cú pháp xuất như sau:

ostream& operator<<(ostream& tên_đối_số,const tên_lớp tên_đối_tượng) {

tên_đối_số<<…<<…//tuỳ cách sử dụng

}

Cú pháp xuất:

istream& operator>>(istream&  tên_đối_số,const  tên_lớp  tên_đối_tượng) {

tên_đối_tượng>>…>>…

}

ở last post chúng ta đã thấy việc sử dụng lớp stack để đưa vào và đẩy ra các kí tự rồi cả số, vậy nếu muốn thao tác với một cấu trúc khác như struc thì sao. Lúc này chúng ta phải sử dụng đến lý thuyết vừa được đề cập ở trên! Trong ví dụsau chúng ta sẽ thử đưa một đối tượng sinh viên gồm các thuộc tính như họ tên, quê quán, điểm trung bình, .. vào trong stack, sau đó lại lấy nó ra. Chúng ta làm như sau:#include <iostream>
#include <cstdlib>
using namespace std;
struct SinhVien{
—-char  hoTen[ 25 ];
—-char  queQuan[ 30 ];
—-int   namSinh;
—-float diemTB;
public :
—-friend
—-ostream& operator <<( ostream& o, const SinhVien& sv ) {
—-—-return o << sv.hoTen << “->” << sv.queQuan << “->” << sv.namSinh << “->” << sv.diemTB << endl;
—-}
—-friend
—-istream& operator >>( istream& i, SinhVien& sv ) {
—-—-cout << “\nTen : “;
—-i.ignore();
—-—-i.getline( sv.hoTen, 25 );
—-—-cout << “\nQue Quan : “;
—-—-i.getline( sv.queQuan, 30 );
—-—-cout << “\nNam Sinh : “;
—-—-i >> sv.namSinh;
—-—-cout << “\nDiem Trung Binh : “;
—-—-i >> sv.diemTB;
—-—-return i;
—-}
};

template< class StackType, int SIZE >
class CStack

{

—-StackType ds[ SIZE ];
—-int pos;
public:
—-CStack():pos( 0 ) {}
—-void Push( const StackType& );
—-StackType Pop();
};
template< class StackType, int SIZE >
void CStack< StackType, SIZE >::Push( const StackType& ch )
{
—- if( pos == SIZE ){
—-—-cout << “\n Stack full”;
—-—-return;
—-}
—-ds[ pos ] = ch;
—-pos++;
}
template< class StackType, int SIZE >
StackType CStack< StackType, SIZE >::Pop()
{
—-if( pos == 0 ) {
—-—-exit( 1 );
—-}
—-pos–;
—-return ds[ pos ];
}
int main(){
—-CStack< SinhVien, 100 > svStack;
—-int n;
—-SinhVien sv;
—-cout<<“\n n = ?    n = “; cin>>n;
—-for(int i = 0;i<n;i++){
—-—-cin >> sv;
—-—-svStack.Push( sv );
—-}
—-for(int i = 0;i<n;i++){
—-—-cout << svStack.Pop();
—-}
—-return 0;
}

10 thoughts on “operator

  1. Dùng từ khoá “friend” như trong ví dụ trên là để làm gì? Tại sao nếu không có từ khoá này tại chỗ đó thì không ổn? Thực ra theo như RR nói, không có từ khoá thì vẫn làm việc chỉ cần đưa nó ra ngoài struct la ok. Nhưng thực ra muốn dùng inline nó cớ. Vậy một điều thắc mắc đó là inline là gì? Từ khoá này nhằm biến một hàm thành hàm trực tuyến. Hàm trực tuyến sẽ làm chương trình có cấu trúc rõ ràng hơn việc dùng “macro”, nó cũng làm chương trình chạy nhanh hơn nhưng đồng thời cũng làm tốn kém bộ nhớ hơn. Khi gọi hàm inline thì cũng cần có từ khoá này trước lời gọi hàm thì trình biên dịch mới sử lý theo kiểu inline(nội tuyến) được.Chú ý rằng, các hàm chứa biến “static, hàm chứa lệnh chu trình, lệnh goto, switch, hoặc hàm đệ quy” thì trình biên dịch hiển nhiên bỏ qua từ khó inline này. Nếu chương trình sử dụng nhiều inlile quá thì trình biên dịch cũng làm lơ luôn! Chương trình do RR viết trên diễn đàn C Việt như sau:
    #include
    #include

    using namespace std;

    struct SinhVien
    {
    char hoTen[ 25 ];
    char queQuan[ 30 ];
    int namSinh;
    float diemTB;

    };

    inline ostream& operator <<( ostream& o, const SinhVien& sv ) {
    return o << sv.hoTen <” << sv.queQuan <” << sv.namSinh <” << sv.diemTB <>( istream& i, SinhVien& sv ) {
    cout << “\nTen : “;
    i.getline( sv.hoTen, 25 );
    cout << “\nQue Quan : “;
    i.getline( sv.queQuan, 30 );
    cout <> sv.namSinh;
    cout <> sv.diemTB;
    return i;
    }

    const int SIZE = 100;

    template
    class CStack
    {
    int pos;
    int size;
    int* ds;
    public:
    CStack( int size = SIZE )
    :pos( 0 ), size( size ), ds( new int[ size ] ) {
    }
    ~CStack() {
    delete[] ds;
    }

    void Push( const StackType& );
    StackType Pop();

    };

    template
    void CStack::Push( const StackType& ch )
    {
    if( pos == SIZE )
    {
    cout << “\n Stack full”;
    return;
    }

    ds[ pos ] = ch;
    pos++;
    }

    template
    StackType CStack::Pop()
    {
    if( pos == 0 ) {
    cout << “\n Stack empty”;
    exit( 1 );
    }
    pos–;
    return ds[ pos ];

    }

    int main()
    {
    CStack s;
    s.Push( 1 );

    return 0;
    }

  2. #include
    #include
    #include
    #include
    #include
    struct sinhvien
    {
    char hoten[50];
    char quequan[50];
    int namsinh;
    float dtb;
    };

    class Cstack
    {
    public:
    Cstack();
    sinhvien data[100];
    int sizemax;
    int size;
    void Nhap(sinhvien sv);
    void Xoa();
    void Luu();
    } ;
    Cstack danhsach;
    void Cstack::Cstack()
    {
    size=0;
    }
    void Cstack::Nhap(sinhvien sv)
    {
    size+=1;
    int i;

    for (i=size;i>1;i–)
    {
    data[i]=data[i-1];
    }
    data[1]=sv;
    }
    void Cstack::Xoa()
    {
    int i;
    if (size==0) cout<<“\nDanh sach rong”;
    else
    {
    for (i=1;i<size;i++)
    data[i]=data[i+1];
    size-=1;
    }
    }
    void Cstack::Luu()
    {
    ofstream f(“stack.txt”);
    int i;
    for (i=1;i<=size;i++)
    {
    f<<“\nSINH VIEN THU “<<i<<” :”;
    f<<“\nHo va ten : “<<data[i].hoten;
    f<<“\nQue quan : “<<data[i].quequan;
    f<<“\nNam sinh : “<<data[i].namsinh;
    f<<“\nDiem trung binh : “<<setprecision(2)<<data[i].dtb;
    f<<“\n”;

    }
    f.close();
    }
    void Nhapdanhsach()
    {
    sinhvien sv;
    danhsach.size=0;
    cout<>danhsach.sizemax;
    cin.ignore();
    int kt=1;
    char ch;
    while (kt==1)
    {
    if (danhsach.size==danhsach.sizemax)
    {
    cout<<“Full stack!!!”;
    kt=0;
    }
    else
    {
    cout<<“Ho ten : “; cin.getline(sv.hoten,50);
    cout<<“Que quan : “; cin.getline(sv.quequan,50);
    cout<>sv.namsinh;
    cout<>sv.dtb;
    danhsach.Nhap(sv);
    cout<<“Ban muon nhap tiep khong (y\\n): “;
    cin.ignore();
    cin.get(ch);
    cin.ignore();
    if ((ch==’y’)||(ch==’Y’)) kt=1;
    else kt=0;
    }
    }
    }
    void Add()
    {
    sinhvien sv;
    int kt=1;
    char ch;
    while (kt==1)
    {
    if (danhsach.size==danhsach.sizemax)
    {
    cout<<“Full stack!!!”;
    kt=0;
    }
    else
    {
    cout<<“Ho ten : “; cin.getline(sv.hoten,50);
    cout<<“Que quan : “; cin.getline(sv.quequan,50);
    cout<>sv.namsinh;
    cout<>sv.dtb;
    danhsach.Nhap(sv);
    cout<<“Ban muon nhap tiep khong (y\\n): “;
    cin.ignore();
    cin.get(ch);
    cin.ignore();
    if ((ch==’y’)||(ch==’Y’)) kt=1;
    else kt=0;
    }
    }
    }

    void Luu()
    {
    cout<<“Danh sach sinh vien da duoc luu trong file STACK.TXT”;
    cout<<“\n”;
    danhsach.Luu();
    }
    void main()
    {
    int ch;
    while (1)
    {
    cout<<“Bai 7 – Struct Sinh vien”;
    cout<<“\n1. Nhap danh sach sinh vien”;
    cout<<“\n2. Them vao Stack”;
    cout<<“\n3. Xoa”;
    cout<<“\n4. Luu vao file”;
    cout<<“\n5. Thoat!!!\n”;
    cout<>ch; cin.ignore();
    if (ch==1) Nhapdanhsach();
    else if (ch==2) Add();
    else if (ch==3) danhsach.Xoa();
    else if (ch==4) Luu();
    else break;
    cin.get();
    }
    }

  3. Đây là bài tập 7 trong đề bài tập lớn của thầy. Cần sử dụng hàm chung và lớp chung, bài của bạn không hề sử dụng lý thuyết hàm chung và lớp chung, về cơ bản thầy sẽ không chấp nhận! Bạn có thể xem topic ” Hàm chung và lớp chung” để biết cách giải quyết vấn đề không khó lắm này. Có một số lỗi của bạn ở đây trình dịch không chấp nhận đâu. Ví dụ:
    coutdanhsach.sizemax;//rat nhieu loi kieu nay.
    các khai báo đối tượng cũng không được hợp lý. nó đây: else if (ch==3) danhsach.Xoa();//danh sach dâu đã được khai báo trong hàm main()…và nhiều nữa. Nhưng cho dù có triệt hết những lỗi này thì vẫn không ăn thua gì. bởi vì lỗi bản chất ở đây là bạn không thể xuất ra dữ liệu như thế này, dữ liệu lúc này có kiểu struct không phải dữ liệu là các kiểu đơn thuần như int, float, double…, cho nên phải dùng hàm chồng toán tử”operator” để xuất ra dữ liệu. Cái này đọc ở topic” operator” bạn sẽ thấy cách giải quyết. Lưu ý là thao tác với file bạn cần có thư viện “fstream.h”, dùng hàm setprecision() bạn cần khai báo thư viện “iomanip.h”, dùng hàm getline() thì cần dùng thư viện “string.h”. Thế thôi. Viết lại toàn bộ chương trình và không được sử dụng các hàm “Nhapdulieu, Add. Luu” một cách vô tổ chức như thế nhé.
    Sửa hết lỗi cú pháp của bạn thì Gió đã làm nhưng không post lên đây bới vì cách lập trình đó không giải quyết vấn đề được đặt ra của thầy. Xem sách và đọc một vài tại liệu mà có nói về lớp chung này, hàm chồng toán tử này. Có vấn đề gì nữa không nhỉ? Cứ nói nhé!

  4. Một điều đáng gét là trên trang này không có hỗ trợ code nên thật khó mà trình bày hết ý. Một số lưu ý là khi coppy bài trên này về chúng ta cần sửa lại các dấu nháy kép, các thu viện cũng cần lưu ý nha, rồi một số trình dịch cũng cần biết sử dụng các thư viện cho hợp lý.

  5. Bài kia về nó báo lỗi ở vòng lặp for cuối cùng H ơi, nó báo không trả về được giá trị i, không tìm thấy i luôn nữa cơ,😦. lên coi lại xem nào đi H

  6. có trả về giá trị i nào đâu? teturn 0; đấy chứ.
    for(int i = 0;i<n;i++){
    cout << svStack.Pop();
    } làm sao mà sai được. Xem lại đi, nếu không được mai đi thi mang lên lớp tui xem cho nha. Bài này chạy vèo vèo rồi mà.

  7. Hôm nay học phương pháp dịch, thầy giáo có giải thích là tại sao lại dùng hàm bạn khi ta dùng hàm chồng toán tử. Thầy có nói, bởi vì khi ta để hàm này như một thành viên của lớp, nó sẽ trả lại một giá trị, có kiểu dữ liệu cơ bản hoặc void, chính vì vậy cần để hàm này bên ngoài hoặc dùng nó như một hàm bạn để nó có thể trả về một đối tượng!

Gửi phản hồi

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Log Out / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Log Out / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Log Out / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Log Out / Thay đổi )

Connecting to %s