Mẫu C++

Trong bài viết này, bạn sẽ tìm hiểu về các mẫu trong C ++. Bạn sẽ học cách sử dụng sức mạnh của các mẫu để lập trình chung.

Mẫu là các tính năng mạnh mẽ của C ++ cho phép bạn viết các chương trình chung chung. Nói một cách dễ hiểu, bạn có thể tạo một hàm hoặc một lớp để làm việc với các kiểu dữ liệu khác nhau bằng cách sử dụng các mẫu.

Các mẫu thường được sử dụng trong cơ sở mã lớn hơn với mục đích tái sử dụng mã và tính linh hoạt của chương trình.

Khái niệm về khuôn mẫu có thể được sử dụng theo hai cách khác nhau:

  • Function Templates
  • Class Templates

Mẫu chức năng

Một mẫu hàm hoạt động tương tự như một hàm bình thường , với một điểm khác biệt chính.

Một mẫu hàm duy nhất có thể hoạt động với các kiểu dữ liệu khác nhau cùng một lúc nhưng một hàm bình thường chỉ có thể hoạt động với một nhóm kiểu dữ liệu.

Thông thường, nếu bạn cần thực hiện các thao tác giống hệt nhau trên hai hoặc nhiều loại dữ liệu, bạn sử dụng tính năng nạp chồng hàm để tạo hai hàm với khai báo hàm được yêu cầu.

Tuy nhiên, một cách tiếp cận tốt hơn sẽ là sử dụng các mẫu hàm vì bạn có thể thực hiện cùng một tác vụ viết mã ít hơn và có thể bảo trì được.

Làm thế nào để khai báo một mẫu hàm?

Mẫu hàm bắt đầu với mẫu từ khóa, theo sau là / các tham số mẫu bên trong   < >, sau đó là khai báo hàm.

template <class T>
T someFunction(T arg)
{
   ... .. ...
}

Trong đoạn mã trên, T là một đối số mẫu chấp nhận các kiểu dữ liệu khác nhau (int, float) và lớp là một từ khóa.

Bạn cũng có thể sử dụng từ khóa typenamethay vì lớp trong ví dụ trên.

Khi, một đối số của một kiểu dữ liệu được chuyển đến someFunction( ), trình biên dịch sẽ tạo ra một phiên bản mới của someFunction() kiểu dữ liệu đã cho.

Ví dụ 1: Mẫu hàm để tìm số lớn nhất

Chương trình hiển thị lớn nhất trong số hai số bằng cách sử dụng các mẫu hàm.

// If two characters are passed to function template, character with larger ASCII value is displayed.

#include <iostream>
using namespace std;

// template function
template <class T>
T Large(T n1, T n2)
{
	return (n1 > n2) ? n1 : n2;
}

int main()
{
	int i1, i2;
	float f1, f2;
	char c1, c2;

	cout << "Enter two integers:\n";
	cin >> i1 >> i2;
	cout << Large(i1, i2) <<" is larger." << endl;

	cout << "\nEnter two floating-point numbers:\n";
	cin >> f1 >> f2;
	cout << Large(f1, f2) <<" is larger." << endl;

	cout << "\nEnter two characters:\n";
	cin >> c1 >> c2;
	cout << Large(c1, c2) << " has larger ASCII value.";

	return 0;
}

Đầu ra

Enter two integers:
5
10
10 is larger.

Enter two floating-point numbers:
12.4
10.2
12.4 is larger.

Enter two characters:
z
Z
z has larger ASCII value.

Trong chương trình trên, một mẫu hàm Large()được định nghĩa chấp nhận hai đối số n1 và n2 của kiểu dữ liệu TTbiểu thị rằng đối số có thể thuộc bất kỳ kiểu dữ liệu nào.

Large()hàm trả về giá trị lớn nhất trong số hai đối số bằng cách sử dụng một phép toán có điều kiện đơn giản .

Bên trong main()chức năng, các biến của ba loại dữ liệu khác nhau: intfloatvà charđược khai báo. Các biến sau đó được chuyển đến Large()mẫu hàm như các hàm bình thường.

Trong thời gian chạy, khi một số nguyên được chuyển đến hàm mẫu, trình biên dịch biết nó phải tạo ra một Large()hàm để chấp nhận các đối số int và làm như vậy.

Tương tự, khi dữ liệu dấu chấm động và dữ liệu ký tự được truyền, nó sẽ biết các kiểu dữ liệu đối số và tạo ra Large()hàm tương ứng.

Bằng cách này, chỉ sử dụng một mẫu hàm duy nhất đã thay thế ba hàm bình thường giống hệt nhau và làm cho mã của bạn có thể bảo trì được.

Ví dụ 2: Hoán đổi dữ liệu bằng các mẫu hàm

Chương trình hoán đổi dữ liệu bằng cách sử dụng các mẫu hàm.

#include <iostream>
using namespace std;

template <typename T>
void Swap(T &n1, T &n2)
{
	T temp;
	temp = n1;
	n1 = n2;
	n2 = temp;
}

int main()
{
	int i1 = 1, i2 = 2;
	float f1 = 1.1, f2 = 2.2;
	char c1 = 'a', c2 = 'b';

	cout << "Before passing data to function template.\n";
	cout << "i1 = " << i1 << "\ni2 = " << i2;
	cout << "\nf1 = " << f1 << "\nf2 = " << f2;
	cout << "\nc1 = " << c1 << "\nc2 = " << c2;

	Swap(i1, i2);
	Swap(f1, f2);
	Swap(c1, c2);

        cout << "\n\nAfter passing data to function template.\n";
	cout << "i1 = " << i1 << "\ni2 = " << i2;
	cout << "\nf1 = " << f1 << "\nf2 = " << f2;
	cout << "\nc1 = " << c1 << "\nc2 = " << c2;

	return 0;
}

Đầu ra

Before passing data to function template.
i1 = 1
i2 = 2
f1 = 1.1
f2 = 2.2
c1 = a
c2 = b

After passing data to function template.
i1 = 2
i2 = 1
f1 = 2.2
f2 = 1.1
c1 = b
c2 = a

Trong chương trình này, thay vì gọi một hàm bằng cách truyền một giá trị, một lệnh gọi bằng tham chiếu được thực hiện.

Mẫu Swap()hàm nhận hai đối số và hoán đổi chúng bằng cách tham chiếu.

Mẫu lớp học

Giống như các mẫu hàm, bạn cũng có thể tạo các mẫu lớp cho các hoạt động chung của lớp.

Đôi khi, bạn cần triển khai lớp giống nhau cho tất cả các lớp, chỉ có kiểu dữ liệu được sử dụng là khác nhau.

Thông thường, bạn sẽ cần tạo một lớp khác nhau cho mỗi kiểu dữ liệu HOẶC tạo các biến và hàm thành viên khác nhau trong một lớp duy nhất.

Điều này sẽ làm cồng kềnh cơ sở mã của bạn một cách không cần thiết và sẽ khó duy trì, vì một thay đổi là một lớp / hàm nên được thực hiện trên tất cả các lớp / hàm.

Tuy nhiên, các mẫu lớp giúp bạn dễ dàng sử dụng lại cùng một mã cho tất cả các kiểu dữ liệu.

Làm thế nào để khai báo một mẫu lớp?

template <class T>
class className
{
   ... .. ...
public:
   T var;
   T someOperation(T arg);
   ... .. ...
};

Trong khai báo trên, Tlà đối số mẫu, là một trình giữ chỗ cho kiểu dữ liệu được sử dụng.

Bên trong phần thân của lớp, một biến thành viên var và một hàm thành viên someOperation()đều thuộc kiểu T.

Làm thế nào để tạo một đối tượng mẫu lớp?

Để tạo một đối tượng mẫu lớp, bạn cần xác định kiểu dữ liệu bên trong < >khi tạo.

className<dataType> classObject;

Ví dụ:

className<int> classObject;
className<float> classObject;
className<string> classObject;

Ví dụ 3: Máy tính đơn giản sử dụng Mẫu lớp

Chương trình cộng, trừ, nhân và chia hai số bằng mẫu lớp

#include <iostream>
using namespace std;

template <class T>
class Calculator
{
private:
	T num1, num2;
	
public:
	Calculator(T n1, T n2)
	{
		num1 = n1;
		num2 = n2;
	}
	
	void displayResult()
	{
		cout << "Numbers are: " << num1 << " and " << num2 << "." << endl;
		cout << "Addition is: " << add() << endl;
		cout << "Subtraction is: " << subtract() << endl;
		cout << "Product is: " << multiply() << endl;
		cout << "Division is: " << divide() << endl;
	}
	
	T add() { return num1 + num2; }
	
	T subtract() { return num1 - num2; }
	
	T multiply() { return num1 * num2; }
	
	T divide() { return num1 / num2; }
};

int main()
{
	Calculator<int> intCalc(2, 1);
	Calculator<float> floatCalc(2.4, 1.2);
	
	cout << "Int results:" << endl;
	intCalc.displayResult();
	
	cout << endl << "Float results:" << endl;
	floatCalc.displayResult();
	
	return 0;
}

Đầu ra

Int results:
Numbers are: 2 and 1.
Addition is: 3
Subtraction is: 1
Product is: 2
Division is: 2

Float results:
Numbers are: 2.4 and 1.2.
Addition is: 3.6
Subtraction is: 1.2
Product is: 2.88
Division is: 2

Trong chương trình trên, một mẫu lớp Calculatorđược khai báo.

Lớp này chứa hai thành viên private kiểu T: num1 & num2 và một hàm tạo để tạo ra các thành viên.

Nó cũng chứa các hàm thành viên công cộng để tính toán cộng, trừ, nhân và chia các số trả về giá trị của kiểu dữ liệu do người dùng xác định. Tương tự, một chức năng displayResult()để hiển thị kết quả cuối cùng ra màn hình.

Trong main()hàm, hai Calculatorđối tượng khác nhau intCalcvà floatCalcđược tạo cho các kiểu dữ liệu: intvà floattương ứng. Các giá trị được khởi tạo bằng cách sử dụng hàm tạo.

Lưu ý rằng chúng tôi sử dụng <int>và <float>trong khi tạo các đối tượng. Chúng cho trình biên dịch biết kiểu dữ liệu được sử dụng để tạo lớp.

Điều này tạo ra một định nghĩa lớp cho mỗi intvà float, sau đó được sử dụng cho phù hợp.

Sau đó, displayResult()cả hai đối tượng được gọi là đối tượng thực hiện các hoạt động Máy tính và hiển thị kết quả đầu ra.









Gõ tìm kiếm nhanh...