30/09/2018, 23:28

Friend { something } trong C++

mình có 1 vấn đề nhỏ
hàm bạn = friend function
lớp bạn = friend class

theo mình biết
khi dùng c++ để oop
hàm là chương trình con không nằm trong class nào cả
phương thức là chương trình con nằm trong 1 class nào đó
chúng ta có các khái niệm hàm bạn, lớp bạn
nhưng mình mới xem 1 tài liệu
thì biết thêm là có phương thức bạn = friend method (k biết gọi có đúng không)
như hình

nhưng mình đã thử, thì thấy hình như không có ý nghĩa gì với kiểu phương thức bạn như trong hình
hàm bạn thì phải truyền vào obj, như trong hình, nếu ở class Y, truyền vào obj kiểu Y, thì vô lý, nếu truyền vào obj A thì lại thừa thãi, truyền vào obj của 1 class khác thì nó lại trở về là hàm bạn, và tại sao lại mang nó vào class Y khi mà không có sự liên quan, hoặc có nhưng k cần

abcxyz viết 01:42 ngày 01/10/2018

mình có thử friend method như sau, nhưng lỗi :3

#include <iostream>
using namespace std;

class sothuc;

class songuyen{
private:
	int sn;
public:
	songuyen(int sn = 0){
		this->sn = sn;
	}
	void xuat(sothuc b){
		cout << sn << endl;
		cout << b.st << endl;   // Error
	}
};

class sothuc{
private:
	float st;
public:
	sothuc(float st = 1.1){
		this->st = st;
	}
	friend void songuyen::xuat(sothuc);
};

int main(){
	songuyen a;
	sothuc b;
	a.xuat(b);
	system("pause");
	return 0;
}
abcxyz viết 01:43 ngày 01/10/2018

thì thấy nó biến tướng quá

viết 01:38 ngày 01/10/2018

lỗi là tại bạn gọi b.st trước khi mà chưa biết sothuc có gì ở trỏng…

để phần định nghĩa của hàm songuyen::xuat về sau cùng thì ko bị lỗi (khi đã biết class sothuc có biến gì rồi)

#include <iostream>
using namespace std;

class sothuc;

class songuyen
{
public:
    songuyen(int sn = 0) : sn(sn) {}
    void xuat(sothuc b); //chỉ khai báo hàm
private:
    int sn;
};

class sothuc
{
public:
    sothuc(float st = 1.1) : st(st) {}
    friend void songuyen::xuat(sothuc);
private:
    float st;
};

int main()
{
    songuyen a;
    sothuc b;
    a.xuat(b);
}

void songuyen::xuat(sothuc b) //xuống dưới này thì đã có định nghĩa đầy đủ cho class sothuc
{
    cout << sn << endl;
    cout << b.st << endl;
}

friend vậy hại não quá

Thành Lê viết 01:37 ngày 01/10/2018

bạn ơi mình mới học C , tại s trong C++ phải sử dụng using namespace std vậy ? trong C mình ko thấy câu đó

viết 01:35 ngày 01/10/2018

namespace giống như thêm họ vô cho tên biến vậy đó. cin là biến thuộc họ std, cout cũng là biến thuộc họ là std, v.v… Khi xài cin/cout thì phải gọi đầy đủ cả tên lẫn họ: std::cin, std::cout.

using namespace std; là để chỉ cần gọi tên khỏi cần gọi họ.

đương nhiên là làm vậy thì có thể bị trùng tên: vd trong lớp có 2 bạn tên Nam, 1 bạn là Nguyễn::Nam, 1 bạn Trần::Nam thì nếu bạn using namespace Nguyễnusing namespace Trần thì khi bạn gọi Nam thì ko rõ là đang gọi bạn nào.

namespace nguyen { int nam; }
namespace tran { int nam; }

using namespace nguyen;
using namespace tran;

int main()
{
    nam = 0; //error: reference to ‘nam’ is ambiguous ("ambiguous" nghĩa là ko rõ ràng)
    nguyen::nam = 0; //ok
    tran::nam = 0; //ok
}

std là họ “chuẩn” (standard) của C++. Thư viện chuẩn của C++ thì nhiều vô kể, bỏ cái họ này đi thì 1 nùi tên riêng bị mất họ, khiến bạn đặt tên biến dễ bị trùng hơn, nên hạn chế using namespace. Cứ gọi cả tên lẫn họ cho quen.

abcxyz viết 01:29 ngày 01/10/2018

mục đích dùng namespace là để quản lý class tốt hơn

ví dụ như
trong 1 phường A (class) có số nhà 21b (method)
phường B (class) cũng có 1 số nhà 21 (method)
nhưng khi gọi 1 trong 2 nhà số 21 này sẽ k bị lỗi,
vì A a;
a.21();
khác với
B b;
b.21();

21 có cùng tên nhưng lại ở class khác nhau

tương tự cấp cao hơn 1 chút

trong 1 huyện A (namespace ) có phường C , có số nhà 21 (method)
trong 1 huyện B (namespace ) có phường C , có số nhà 21 (method)

trùng tên số nhà , trùng tên class, nhưng khi gọi 1 trong 2 số nhà 21 trên thì cũng k bị lỗi

A.C.21();
khác với
B.C.21();
phương thức 21 và lớp c trung tên nhau nhưng lại ở namespace khác nhau

đó là ý nghĩa của namespace
từ đây người ra tạo ra namespace
và đặc biệt là namepsace không bị dưới hạn về cấp
bạn có thể tạo ra namespace để quản lý namespacce

namespace.namspace.namspace.class.method

còn cách dùng và cách tạo thì như bạn ở dưới nói

abcxyz viết 01:40 ngày 01/10/2018

thế là mình nghĩ cái này là phương thức bạn chứ không phải hàm bạn
tks bạn

abcxyz viết 01:40 ngày 01/10/2018

nếu làm như thế này, chương trình k lỗi, chạy được, nhưng lại có 1 lỗi cảnh báo, khi build k hiển thị

#include <iostream>
using namespace std;

class sothuc;

class songuyen{
private:
	int sn;
public:
	songuyen(int sn = 0){
		this->sn = sn;
	}
	void xuat(sothuc);
};

class sothuc{
private:
	float st;
public:
	sothuc(float st = 1.1){
		this->st = st;
	}
	friend void songuyen::xuat(sothuc);
};

void songuyen::xuat(sothuc b){
	cout << sn << endl;
	cout << b.st << endl;
}

int main(){
	songuyen a;
	sothuc b;
	a.xuat(b);
	system("pause");
	return 0;
}

Bài liên quan
0