30/09/2018, 16:21

Có nên dùng con trỏ this?

e viết thư viện như sau?
có cần thiết dùng con trỏ this ạ?

#include <iomanip>
#include <complex>
#include <iostream>
using namespace std;

#define MAX 10

class MaTran
{
	public:
		MaTran(int m, int n);
		~MaTran();
		void inMaTran();
		void nhapMaTran();
		void chuyenVi();
		int dinhThuc(int p=0);
		float phuHop(int hangXoa, int cotXoa);
		void nghichDao();
		int hang();
		void xoaHang();
		void xoaCot();
		void congMaTran();
		void truMaTran();
		void nhanMT_So();
		void nhanMT_MT();
	private:
		int soHang=MAX,soCot=MAX;
		float det=0;
		float **mt=new float*[soHang];
};

MaTran::MaTran(int m, int n){
	this->soHang=m;
	this->soCot=n;
	for(int i=0;i<this->soHang;i++)
		this->mt[i]=new float[this->soCot];
}

MaTran::~MaTran(){
	for(int i=0;i<this->soHang;i++) delete[] this->mt[i];
	delete[] this->mt;
	this->soHang=0; this->soCot=0;
	this->det=0;
}

void MaTran::inMaTran(){
	cout<<fixed<<setprecision(2);
	for(int i=0;i<this->soHang;i++){
		cout<<"
	";
		for(int j=0;j<this->soCot;j++) cout<<setw(4)<<this->mt[i][j]<<" ";
	}
	cout<<endl;
}

void MaTran::nhapMaTran(){
	for(int i=0;i<this->soHang;i++)
		for(int j=0;j<this->soCot;j++){
			cout<<"	Phan tu ["<<i+1<<","<<j+1<<"] = ";
			cin>>this->mt[i][j];
		}
	cout<<"Ma tran ban vua nhap la:";
	this->inMaTran();
}

void MaTran::chuyenVi(){
	MaTran cv(this->soCot,this->soHang);
	for(int i=0;i<cv.soHang;i++)
		for(int j=0;j<cv.soCot;j++)
			cv.mt[i][j]=this->mt[j][i];
	cout<<"Ma tran chuyen vi cua ma tran A la:";
	cv.inMaTran();
}

int MaTran::dinhThuc(int p){
	if(this->soHang==this->soCot){
		int i=0,d=0;
		float dt=1.0;
		//Tao ma tran B lay gia tri cua ma tran A
		MaTran b(this->soHang,this->soCot);
		for(int i=0;i<b.soHang;i++)
			for(int j=0;j<b.soCot;j++)
				b.mt[i][j]=this->mt[j][i];
		//Dua ma tran ve ma tran tam giac tren
		for(i=0;i<b.soHang-1;i++){
			if(b.mt[i][i]==0)
				for(int k=i+1;k<b.soHang;k++){
					bool c=0;
					if(b.mt[k][i]!=0){
						for(int j=0;j<b.soCot;j++){
							float t=b.mt[i][j];
							b.mt[i][j]=b.mt[k][j];
							b.mt[k][j]=t;
						}
						d++;
						c=1;
						break;
					}
					if(c) break;
				}
			for(int k=i+1;k<b.soHang;k++){
				double tl=b.mt[k][i]/b.mt[i][i];
				for(int j=0;j<soCot;j++)
					b.mt[k][j]-=b.mt[i][j]*tl;
			}
		}
		//Tinh dinh thuc bang tich cac phan tu tren duong cheo chinh
		for(i=0;i<b.soCot;i++) dt*=b.mt[i][i];
		if(dt!=0) dt*=pow(-1,d);
		this->det=dt;
		if(p) cout<<"	Dinh thuc cua ma tran A la: det(A) = "<<this->det<<endl;
		return 0;
	} else{
		return 1;
	}
}

float MaTran::phuHop(int hangXoa, int cotXoa){
	MaTran ph(this->soHang-1,this->soCot-1);
	for(int i=0;i<hangXoa;i++){
		for(int j=0;j<cotXoa;j++)
			ph.mt[i][j]=this->mt[i][j];
		for(int j=cotXoa;j<ph.soCot;j++)
			ph.mt[i][j]=this->mt[i][j+1];
	}
	for(int i=hangXoa;i<ph.soHang;i++){
		for(int j=0;j<cotXoa;j++)
			ph.mt[i][j]=this->mt[i+1][j];
		for(int j=cotXoa;j<ph.soCot;j++)
			ph.mt[i][j]=this->mt[i+1][j+1];
	}
	ph.dinhThuc(0);
	float pTu=(float) ph.det/this->det;
	if(pTu!=0)
		pTu*=pow(-1,hangXoa+cotXoa);
	return pTu;
}

void MaTran::nghichDao(){
	if(this->dinhThuc(0)==1 || this->det==0) cout<<"	Ma Tran A khong kha nghich
";
	else{
		//Tao ma tran chuyen vi cua ma tran A
		MaTran cv(this->soCot,this->soHang);
		for(int i=0;i<cv.soHang;i++)
			for(int j=0;j<cv.soCot;j++)
				cv.mt[i][j]=this->mt[j][i];
		//Tao ma tran B co cac phan tu la ma tran phu hop cua ma tran chuyen vi
		MaTran b(this->soHang,this->soCot);
		cv.det=this->det;
		for(int i=0;i<b.soHang;i++)
			for(int j=0;j<b.soCot;j++)
				b.mt[i][j]=cv.phuHop(i,j);
		cout<<"Ma tran nghich dao cua ma tran A la:";
		b.inMaTran();
	}
}

int MaTran::hang(){
	//Tao ma tran B lay gia tri cua ma tran A
	MaTran b(this->soHang,this->soCot);
	for(int i=0;i<b.soHang;i++)
		for(int j=0;j<b.soCot;j++)
			b.mt[i][j]=this->mt[i][j];
	//Dua ma tran ve ma tran tam giac tren
	for(int i=0;i<b.soHang-1;i++){
		for(int j=i;j<b.soCot;j++){
			if(b.mt[i][j]==0)
				for(int k=i+1;k<b.soHang;k++)
					if(b.mt[k][j]!=0){
						for(int u=0;u<b.soCot;u++){
							float t=b.mt[i][u];
							b.mt[i][u]=b.mt[k][u];
							b.mt[k][u]=t;
						}
						break;
					}
			if(b.mt[i][j]!=0){
				for(int k=i+1;k<b.soHang;k++){
					double tl=(double) b.mt[k][j]/b.mt[i][j];
					for(int u=0;u<b.soCot;u++){
						b.mt[k][u]-=b.mt[i][u]*tl;
					}
				}
				break;
			}
		}
	}
	//Tim hang
	int r=0;
	for(int i=b.soHang-1;i>=0;i--){
		for(int j=0;j<b.soCot;j++)
			if(abs(b.mt[i][j])!=0){
				r=i+1;
				break;
			}
		if(r>0) break;
	}
	return r;
}

void MaTran::xoaHang(){
	int x=0;
	do{
		cout<<"Nhap vao hang thu x (0<x<"<<this->soHang+1<<") ban muon xoa: ";
		cin>>x;
	} while(x<1 || x>this->soHang);
	MaTran b(this->soHang-1,this->soCot);
	x--;
	for(int j=0;j<b.soCot;j++){
		for(int i=0;i<x;i++)
			b.mt[i][j]=this->mt[i][j];
		for(int i=x;i<b.soHang;i++)
			b.mt[i][j]=this->mt[i+1][j];
	}
	cout<<"Ma tran A sau khi xoa hang thu "<<x+1<<" la:";
	b.inMaTran();
}

void MaTran::xoaCot(){
	int x=0;
	do{
		cout<<"Nhap vao cot thu x (0<x<"<<this->soCot+1<<") ban muon xoa: ";
		cin>>x;
	} while(x<1 || x>this->soCot);
	MaTran b(this->soHang,this->soCot-1);
	x--;
	for(int i=0;i<b.soHang;i++){
		for(int j=0;j<x;j++)
			b.mt[i][j]=this->mt[i][j];
		for(int j=x;j<b.soCot;j++)
			b.mt[i][j]=this->mt[i][j+1];
	}
	cout<<"Ma tran A sau khi xoa cot thu "<<x+1<<" la:";
	b.inMaTran();
}

void MaTran::congMaTran(){
	MaTran b(this->soHang,this->soCot);
	cout<<"Nhap ma tran B:
";
	b.nhapMaTran();
	for(int i=0;i<b.soHang;i++)
		for(int j=0;j<b.soCot;j++){
			b.mt[i][j]+=this->mt[i][j];
		}
	cout<<"Tong cua 2 ma tran A va B la:";
	b.inMaTran();
}

void MaTran::truMaTran(){
	MaTran b(this->soHang,this->soCot);
	cout<<"Nhap ma tran B:
";
	b.nhapMaTran();
	for(int i=0;i<b.soHang;i++)
		for(int j=0;j<b.soCot;j++){
			b.mt[i][j]=this->mt[i][j]-b.mt[i][j];
		}
	cout<<"Hieu cua 2 ma tran A va B la:";
	b.inMaTran();
}

void MaTran::nhanMT_So(){
	float x=1;
	MaTran b(this->soHang,this->soCot);
	cout<<"Nhap vao so x: ";
	cin>>x;
	for(int i=0;i<b.soHang;i++)
		for(int j=0;j<b.soCot;j++)
			b.mt[i][j]=x*this->mt[i][j];
	cout<<"Tich cua "<<x<<" voi ma tran A la:";
	b.inMaTran();
}

void MaTran::nhanMT_MT(){
	int cotB=10;
	cout<<"Nhap so cot cua ma tran B: ";
	cin>>cotB;
	MaTran b(this->soCot,cotB);
	cout<<"
Nhap ma tran B:
";
	b.nhapMaTran();
	MaTran c(this->soHang,b.soCot);
	for(int i=0;i<c.soHang;i++)
		for(int j=0;j<c.soCot;j++){
			c.mt[i][j]=0;
			for(int k=0;k<this->soCot;k++)
				c.mt[i][j]+=this->mt[i][k]*b.mt[k][j];
		}
	cout<<"Tich cua ma tran A va ma tran B la:";
	c.inMaTran();
}
Nguyễn Minh Dũng viết 18:24 ngày 30/09/2018

có cần thiết dùng con trỏ this ạ?

Viết thì cũng tốt, không viết cũng không sao. Bởi vì khi chương trình của em được compile thì compiler sẽ tự động gắn con trỏ this vào các biến member của class.

1.Trường nào hợp nào bắt buộc phải dùng con trỏ this?

Khi có sự trùng lặp tên biến, giữa biến bên ngoài và biến member. Ví dụ như sau:

MaTran::MaTran(int soHang, int soCot){
	this->soHang=soHang;
	this->soCot=soCot;
	for(int i=0;i<this->soHang;i++)
		this->mt[i]=new float[this->soCot];
}

2.Trường hợp nào không bắt buộc phải dùng con trỏ this?

Khi không có sự trùng lặp tên biến

MaTran::MaTran(int m, int n){
	this->soHang=m;
	this->soCot=n;
	for(int i=0;i<this->soHang;i++)
		this->mt[i]=new float[this->soCot];
}

3.Sử dụng con trỏ this để trả về chính thực thể của class đó
Như trong ví dụ này, và ví dụ này ta return về con trỏ this để thực hiện phép tính + liên tiếp.

template <class T>
Number<T>& Number<T>::operator+=(const Number<T>& value)
{
    m_data = m_data + value.m_data;
    return *this;
}

4.Videos về con trỏ this

Đăng ký khóa học C++ cơ bản 2016 ( NEW ) tại đây : Thông tin về khóa học xem tại đây : -Sự khác biệt giữa 2 khóa học cũ và mới : +Khóa học C++ cơ bản 2016 là khóa học mới, được đầu tư nhiều hơn từ nội dung, phương pháp học, cách học hiệu quả. +Trong khóa học còn có nhiều kiến thức mới như thực hành trên HackerRank, thực hành trên Codefights và Đạt nghĩ mọi người nên học khóa học mới, bởi vì đây là kiến thức mới, phù hợp với hiện tại..... Mặt khác âm thanh cũng tốt hơn nhiều so với khóa học …

Sáng Béo viết 18:24 ngày 30/09/2018

3.Sử dụng con trỏ this để trả về chính thực thể của class đóNhư trong ví dụ này, và ví dụ này ta return về con trỏ this để thực hiện phép tính + liên tiếp.

cái mục 3 này đau đầu quá a ơi. T.T

Nguyễn Minh Dũng viết 18:37 ngày 30/09/2018

Bỏ mục 3 đi, về sau sẽ cần, chứ bây giờ thì chưa cần

P/S: Đã sửa

Sáng Béo viết 18:37 ngày 30/09/2018

Bỏ mục 3 đi, về sau sẽ cần, chú bây giờ thì chưa cần

vâng thưa cháu.

viết 18:29 ngày 30/09/2018

Đối với bản thân thì mình thường dùng this để phân biệt biến bên trong phương thức và biến của class.
Bạn có thể sử dụng style của google http://google-styleguide.googlecode.com/svn/trunk/cppguide.html
Theo mình biết thì ở Facebook, người code sẽ review code chéo cho nhau, và code phải đúng theo một style chung, vừa kiểm tra giúp nhau, vừa học hỏi kỹ thuật lẫn nhau. Đó là cách làm hay và mỗi người nên tự áp dụng cho mình để trình bày khoa học.

Sáng Béo viết 18:21 ngày 30/09/2018

e nghĩ là cứ để this như thế cho rõ ràng cũng đc a nhỉ

Sáng Béo viết 18:35 ngày 30/09/2018

P/S: Đã sửa


dính trong quote rồi a ơi.

Nguyễn Minh Dũng viết 18:35 ngày 30/09/2018

Style của Google cũng không dùng this, theo như link của google thì mình không thấy thế.

http://google-styleguide.googlecode.com/svn/trunk/cppguide.html#Classes

Style của mình là khi nào conflict tên biến mới dùng, vì nó khá là phiên phức khi cứ phải ghi this->

Sáng Béo viết 18:37 ngày 30/09/2018

e tạo 1 obj mới trong function để lấy giá trị của obj đang làm việc và làm việc với obj thay thế đó. tránh thay đổi giá trị của obj gốc.
thế dùng this có đc khuyến khích ko a?

viết 18:23 ngày 30/09/2018

ý mình là có thể chọn lựa 1 style nào đó chứ không viết bừa bãi, chứ có this hay ko là tùy mỗi người, tùy nơi người đó làm việc. Lúc mình làm thì chỗ nào this được thì để this, có một số qui tắc thì áp dụng theo google style :D. @ltd

Nguyễn Minh Dũng viết 18:24 ngày 30/09/2018

e tạo 1 obj mới trong function để lấy giá trị của obj đang làm việc và làm việc với obj thay thế đó.

Em cho anh xem code mẫu được không? Giải thích của em chưa rõ lắm.

ý mình là có thể chọn lựa 1 style nào đó chứ không viết bừa bãi, chứ có this hay ko là tùy mỗi người, tùy nơi người đó làm việc. Lúc mình làm thì chỗ nào this được thì để this, có một số qui tắc thì áp dụng theo google style :D. @ltd

Ừ, mình cũng hay xem Google Style, mà có điều không hợp với mình lắm. Mình code C nhiêu hơn C++ nên bị nhiễm một ít C vào rồi. Với cả mình hay xem trên Code Complete nữa, đó cũng là một nguồn tốt. để xây dựng style coding cho mình.

Sáng Béo viết 18:22 ngày 30/09/2018

code e post ở đầu bài đó a.
đề thì là tạo thư viện làm việc với ma trận.
tên các function ở code nói hết các việc cần làm rồi a.

Nguyễn Minh Dũng viết 18:34 ngày 30/09/2018

code e post ở đầu bài đó a.

Cụ thể là đoạn nào? Code em dài thế mà không nói rõ anh lười xem lắm.

Sáng Béo viết 18:34 ngày 30/09/2018

ví dụ:

float MaTran::phuHop(int hangXoa, int cotXoa){
	MaTran ph(this->soHang-1,this->soCot-1);
	for(int i=0;i<hangXoa;i++){
		for(int j=0;j<cotXoa;j++)
			ph.mt[i][j]=this->mt[i][j];
		for(int j=cotXoa;j<ph.soCot;j++)
			ph.mt[i][j]=this->mt[i][j+1];
	}
	for(int i=hangXoa;i<ph.soHang;i++){
		for(int j=0;j<cotXoa;j++)
			ph.mt[i][j]=this->mt[i+1][j];
		for(int j=cotXoa;j<ph.soCot;j++)
			ph.mt[i][j]=this->mt[i+1][j+1];
	}
	ph.dinhThuc(0);
	float pTu=(float) ph.det/this->det;
	if(pTu!=0)
		pTu*=pow(-1,hangXoa+cotXoa);
	return pTu;
}
Sáng Béo viết 18:33 ngày 30/09/2018

Cụ thể là đoạn nào? Code em dài thế mà không nói rõ anh lười xem lắm.

mấy hàm e đều tạo obj mới để thao tác thay vì thao tác trên obj gốc mà a.
obj gốc có thể còn để thực hiện thao tác khác nữa nên không thể thay đổi đc.

Nguyễn Minh Dũng viết 18:36 ngày 30/09/2018

Quả thực là anh không thấy em tạo object mới ở đâu cả. Em có thể giải thích cụ thể hơn không?

float MaTran::phuHop(int hangXoa, int cotXoa){
	MaTran ph(this->soHang-1,this->soCot-1);
	for(int i=0;i<hangXoa;i++){
		for(int j=0;j<cotXoa;j++)
			ph.mt[i][j]=this->mt[i][j];
		for(int j=cotXoa;j<ph.soCot;j++)
			ph.mt[i][j]=this->mt[i][j+1];
	}
	for(int i=hangXoa;i<ph.soHang;i++){
		for(int j=0;j<cotXoa;j++)
			ph.mt[i][j]=this->mt[i+1][j];
		for(int j=cotXoa;j<ph.soCot;j++)
			ph.mt[i][j]=this->mt[i+1][j+1];
	}
	ph.dinhThuc(0);
	float pTu=(float) ph.det/this->det;
	if(pTu!=0)
		pTu*=pow(-1,hangXoa+cotXoa);
	return pTu;
}
Sáng Béo viết 18:32 ngày 30/09/2018

cái

MaTran ph(this->soHang-1,this->soCot-1);

đó a.
e tạo 1 ma trận mới với số hàng và số cột giảm đi 1 đơn vị lưu ma trận gốc đã xóa 1 hàng và 1 cột đc truyền ở tham số.
chứ e ko xóa ở ma trận gốc.

Sáng Béo viết 18:23 ngày 30/09/2018

à, a Đạt thêm cái nút Markdown vào thanh công cụ ở trên khung nhập text này đi. mỗi lần post code lại phải google markdown rồi copy paste vào. T.T

Nguyễn Minh Dũng viết 18:37 ngày 30/09/2018

Cách em làm không đúng hướng đối tượng. Không liên quan đến con trỏ this ở đây.

Đây không phải là cách hay để giải quyết vấn đề.

Bên trong một đối tượng để tạo một đối tượng khác là copy của đối tượng hiện tại.

Nếu em cần tái sử dụng object gốc như em nói

obj gốc có thể còn để thực hiện thao tác khác nữa nên không thể thay đổi đc.

Thì em làm cái việc tạo object mới ở hàm main, hay bất cứ hàm nào sử dụng object của em. Đừng copy trong nội bộ class như thế.

Class chỉ làm một việc là thực thi tính năng X, tính năng Y. Không nên bao gồm cả việc “backup” dữ liệu như thế.

à, a Đạt thêm cái nút Markdown vào thanh công cụ ở trên khung nhập text này đi. mỗi lần post code lại phải google markdown rồi copy paste vào. T.T

Markdown có gì phức tạp đâu mà phải google?

Sáng Béo viết 18:36 ngày 30/09/2018

Markdown có gì phức tạp đâu mà phải google?

à, a nói e mới để ý trên bàn phím có phím này `

Bài liên quan
0