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ố 11 kết quả

Đề tài: [ Solved ]Thắc mắc friend functions

  1. #1
    No Avatar
    dauchuot Khách

    Mặc định [ Solved ]Thắc mắc friend functions

    'dauchuot' co' header file, khai báo lớp Time có 2 private variables giờ, phút và các public function: constructor, cộng thêm phút vào, cộng thêm giờ vào, các operator dể có thể thực hiện +, -, * với 2 objects

    Code:
    #include <iostream>
    using namespace std;
    
    class Time
    {
    private:
    	int hours;
    	int minutes;
    public:
    	Time();
    	Time(int h, int m = 0);
    	void AddMin(int m);
    	void AddHr(int h);
    	void Reset(int h = 0, int m = 0);
    	Time operator+(const Time & t) const;
    	Time operator-(const Time & t) const;
    	Time operator*(double mult) const;
    	friend Time operator*(double m, const Time & t)
    		{ return t * m;}
    	friend ostream & operator<<(ostream & os, const Time & t);
    };
    Hàm operator* 'dauchuot' dùng để tăng thời gian lên mult lần
    Code:
    Time Time::operator*(double mult) const
    {
    	Time result;
    	long totalmin = (hours * 60 + minutes) * mult;
    	result.hours = totalmin / 60;
    	result.minutes = totalmin % 60;
    	return result;
    }
    Khi đó ta có thể thực hiện: B * 2.75 (với B được khai báo là object kiểu Time)
    và 'dauchuot' muốn phép toan 2.75 * B cũng thực hiện được nên viết thêm
    friend Time operator*(double m, const Time & t)
    { return t * m;}
    'dauchuot' thắc mắc tại sao phải có friend mới chạy được? 'dauchuot' dâu có đụng gì tới private variables đâu !

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

    pó tay, code chuối quá
    Thực ra vấn đề của bạn mình chưa hiêu lắm, không chạy tức là compile bị lỗi hay run kết quả sai. giả sử bỏ đi friend thì bạn bỏ chữ friend hay xóa khai hàm như thế nào. Hỏi thì phải rõ ràng chứ, còn nhìn vào trên thì tui chưa thấy lỗi đâu cả, đúng là không đụng tới private thì không cần friend cũng được

    Còn chuối ở chỗ nào:
    - ta nên cho 2 thằng operator đó friend luôn, chứ ai lại 1 thằng là member, 1 đứa là friend
    - kết quả của 2*B =? hay là không có kiểu nhân này (chú ý 2 là integer)

  3. #3
    No Avatar
    dauchuot Khách

    Mặc định kg ro ràng

    Xin lỗi, bây giờ đọc lại thấy mình diễn đạt tViet tệ qua'! (dúng là dầu chuột). 'Dauchuot' đưa code chạy được ra nè:
    ===============================
    (mytime3.h)
    Code:
    #ifndef MYTIME3_H_
    #define MYTIME3_H_
    #include <iostream>
    using namespace std;
    
    class Time
    {
    private:
    	int hours;
    	int minutes;
    public:
    	Time();
    	Time(int h, int m = 0);
    	void AddMin(int m);
    	void AddHr(int h);
    	void Reset(int h = 0, int m = 0);
    	Time operator+(const Time & t) const;
    	Time operator-(const Time & t) const;
    	Time operator*(double mult) const;
    	friend Time operator*(double m, const Time & t)
    		{ return t * m;}
    	friend ostream & operator<<(ostream & os, const Time & t);
    };
    #endif
    ==================================
    (mytime3.cpp)
    Code:
    #include "mytime3.h"
    
    Time::Time()
    {
    	hours = minutes = 0;
    }
    
    Time::Time(int h, int m)
    {
    	hours = h;
    	minutes = m;
    }
    
    void Time::AddHr(int h)
    {
    	hours += h;
    }
    
    void Time::AddMin(int m)
    {
    	minutes += m;
    	hours += minutes / 60;
    	minutes %= 60;
    }
    
    void Time::Reset(int h, int m)
    {
    	hours = h;
    	minutes = m;
    }
    
    Time Time::operator +(const Time & t) const
    {
    	Time sum;
    	sum.minutes = minutes + t.minutes;
    	sum.hours = hours + t.hours + sum.minutes / 60;
    	sum.minutes %= 60;
    	return sum;
    }
    
    Time Time::operator -(const Time & t) const
    {
    	Time diff;
    	int mot1, mot2;
    	mot1 = t.minutes + t.hours * 60;
    	mot2 = minutes + hours * 60;
    	diff.minutes = (mot1 - mot2) / 60;
    	diff.hours = (mot1 - mot2) % 60;
    	return diff;
    }
    
    Time Time::operator*(double mult) const
    {
    	Time result;
    	long totalmin = (hours * 60 + minutes) * mult;
    	result.hours = totalmin / 60;
    	result.minutes = totalmin % 60;
    	return result;
    }
    
    ostream & operator<<(ostream & os, const Time & t) 
    {
    	os << t.hours << " hours, " << t.minutes << " minutes";
    	return os;
    }
    =======================
    (usemytime3.ccp)
    Code:
    #include <iostream>
    using namespace std;
    #include "mytime3.h"
    
    int main()
    {
    	Time A;
    	Time B(5, 40);
    	Time C(2, 55);
    	cout << "A, B, C:\n";
    	cout << A << "; " << B << "; " << C << endl;
    	A = B + C;
    	cout << "B + C: " << A << endl;
    	A = B * 2;
    	cout << "B * 2: " << A << endl;
    	cout << "10 * B: " << 10 * B << endl;
    	return 0;
    }
    =================================
    (B * 2.75 chạy được tất nhiên B * 2 phải chạy chứ, copy code kiểm tra lại thử cho trường hợp 2.75 và 2 thử xem)
    Câu hỏi: ở header file có khai báo
    friend Time operator*(double m, const Time & t)
    { return t * m;}
    chường trình Build Solution( nhấn F7) được. Nếu bỏ đi từ khóa friend tức là chỉ khai báo trong mytime3.h như sau:
    Time operator*(double m, const Time & t)
    { return t * m;}
    ---> Không Build được. 'Dauchuot' kg hiểu tại sao bỏ friend đi thì không build được, thây có dính dang gì tới t.minutes, t.hours đâu.
    Đã được chỉnh sửa lần cuối bởi dauchuot : 06-09-2006 lúc 07:51 PM.

  4. #4
    No Avatar
    noname.cpp Khách

    Bởi vì * là toán tử 2 ngôi, khi chồng toán tử nhân bằng hàm thành phần của lớp thì đối tượng hiện tại ngầm định là một toán hạng vì vậy chỉ được phép khai báo một tham số là toán hạng thứ 2.
    Đó là hàm thứ nhất bủa bạn :
    Time operator*(double mult) const;

    Còn nếu muốn chồng toán tử 2 ngôi bằng hàm có 2 tham số là 2 toán hạng thì hàm này không thể là hàm thành phần của lớp vì vậy bắt buộc nó phải làm hàm bạn.
    friend Time operator*(double m, const Time & t)

  5. #5
    No Avatar
    dauchuot Khách

    Cám ơn 'noname.cpp' nhiều !

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

    Mặc định [ Solved ]Thắc mắc friend functions

    noname.cpp nói chính xác đấy
    tui hỏi bạn là nếu không dùng friend thì bạn xóa đi cả khai báo hàm trong lớp hay là chỉ xóa đi "friend" thôi chính là vì như vậy
    nếu bạn xóa đi "friend" thôi thì đương nhiên là lỗi compile
    nếu bạn xóa đi "friend" và chuyển hàm ra ngoài lớp thì lại không có vấn đề gì hết (vì hàm của bạn không truy xuất đến thành phần private)
    Đã được chỉnh sửa lần cuối bởi nguyentuan2 : 07-09-2006 lúc 10:55 AM.

  7. #7
    No Avatar
    dauchuot Khách

    'nguyentuan2' có thể hướng dẫn rõ hơn phương án chuyển hàm "friend" ra khỏi class được kg ?
    'dauchuot' hiểu như thế này:
    Code:
    #ifndef MYTIME3_H_
    #define MYTIME3_H_
    #include <iostream>
    using namespace std;
    
    class Time
    {
    private:
    	int hours;
    	int minutes;
    public:
    	Time();
    	Time(int h, int m = 0);
    	void AddMin(int m);
    	void AddHr(int h);
    	void Reset(int h = 0, int m = 0);
    	Time operator+(const Time & t) const;
    	Time operator-(const Time & t) const;
    	Time operator*(double mult) const;
        friend ostream & operator<<(ostream & os, const Time & t);
    	
    };
    Time operator*(double m, const Time & t)
    	{ return t.operator*(m);}
    #endif
    'dauchuot' chuyển như thế thì kg build được.

  8. #8
    No Avatar
    dauchuot Khách

    'dauchuot' thử không dùng "friend" va` khai ba'o hàm ở trêm hàm main() (bên trong usemytime3.cpp, thì build được. Ai đó giải thích cho 'dauchuot' tình huống này kg ?

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

    'dauchuot' chuyển như thế thì kg build được.
    bạn vừa làm 1 việc là hiện thực hàm trong file .h (đặt cả thân hàm trong file mytime3.h)

    file mytime3.cpp và usemytime3.ccp đều include file mytime3.h
    tức là mytime3.obj và usemytime3.obj đều có thân của hàm đó, cho nên trình dịch không thể link được (biết link vào operator * trong mytime3.obj hay usemytime3.obj). Lý giải tương tự thì sẽ dễ hiểu nếu bạn chuyển có sang usemytime3.ccp thì build được

    Đây là điều lỗi thường gặp (thấy vậy đó)

    Cách giải quyết rất đơn giản, cũng tức là làm đúng chuẩn của lập trình C++, là đặt phần khai báo trong file .h, hiện thực trong file .cpp
    như thế này
    //mytime3.h
    Time operator*(double m, const Time & t); //không hiện thực , ghi chú là nếu muốn sử dụng friend thì bạn thêm friend ở đầu hàng rồi chuyển vào trong khai báo lớp, nếu không thì bỏ friend và đặt ở ngoài phần khai báo lớp

    //mytime3.cpp
    Time operator*(double m, const Time & t)
    { return t.operator*(m);}

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

    bạn đã gặp lỗi external resove, hay can not resolve, đoại loại như vậy, đúng không nhỉ

    bạn đặt code của operator * trước hàm main thì hết lỗi là do phần hiện thực đã được chuyển vào file .cpp

    nếu muốn đặt phần hiện thực trong file .h thì có 1 cách là dùng inline, như thế này
    //mytime3.h
    inline Time operator*(double m, const Time & t)
    { return t.operator*(m);}

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

  1. Bài tập C++ thắc mắc về hàm friend trong C++
    Gửi bởi nntrungduy trong diễn đàn Nhập môn lập trình C/C++
    Trả lời: 15
    Bài viết cuối: 16-04-2012, 08:25 AM
  2. Thắc mắc về Generic functions
    Gửi bởi cakiem.b10 trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 2
    Bài viết cuối: 08-03-2010, 10:27 AM
  3. Làm sao thay thế friend ?
    Gửi bởi iamme22021990 trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 2
    Bài viết cuối: 09-02-2010, 11:13 AM
  4. [ Solved ]Thừa kế đối với friend function
    Gửi bởi thavali trong diễn đàn Nhập môn lập trình C/C++
    Trả lời: 9
    Bài viết cuối: 22-11-2008, 09:50 AM
  5. [ Solved ]Lỗi khi sử dụng friend
    Gửi bởi bvKim trong diễn đàn Nhập môn lập trình C/C++
    Trả lời: 8
    Bài viết cuối: 19-11-2008, 12:41 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