Giới thiệu về nạp chồng toán tử
Thuộc phần Lập trình hướng đối tượng trong hành trình C++ của Coddy. Bài học 40 trên 104.
Quá tải toán tử cho phép bạn định nghĩa cách các toán tử như +, - hoặc == hoạt động khi dùng với các lớp tùy chỉnh. Thay vì gọi các phương thức như a.add(b), bạn có thể viết a + b trực quan hơn.
Trong C++, toán tử về cơ bản là các hàm có tên đặc biệt. Để nạp chồng toán tử, bạn định nghĩa một hàm bằng từ khóa operator, theo sau là ký hiệu:
class Vector2D {
double x, y;
public:
Vector2D(double x, double y) : x(x), y(y) {}
// Nạp chồng toán tử +
Vector2D operator+(const Vector2D& other) const {
return Vector2D(x + other.x, y + other.y);
}
};Giờ bạn có thể cộng hai vectơ một cách tự nhiên:
Vector2D v1(1.0, 2.0);
Vector2D v2(3.0, 4.0);
Vector2D v3 = v1 + v2; // Gọi v1.operator+(v2)Không phải toán tử nào cũng có thể được nạp chồng. Toán tử phân giải phạm vi ::, truy cập thành viên ., toán tử ba ngôi ?: và sizeof không thể được nạp chồng. Ngoài ra, bạn không thể tạo toán tử mới hoặc thay đổi độ ưu tiên của toán tử, * luôn được tính trước +.
Bạn có thể triển khai toán tử (operator) dưới dạng hàm thành viên (member function) như ở trên hoặc hàm không phải thành viên (non-member function). Trong các bài học tiếp theo, bạn sẽ tìm hiểu khi nào nên dùng từng cách và cách nạp chồng các nhóm toán tử cụ thể.
Thử thách
DễHãy tạo một lớp Point đại diện cho tọa độ 2D và hỗ trợ cộng hai điểm với nhau bằng toán tử +. Đây là bước đầu tiên để bạn tìm hiểu về nạp chồng toán tử, giúp các lớp tùy chỉnh hoạt động với những toán tử quen thuộc.
Bạn sẽ tạo hai tệp để sắp xếp code:
Point.h: Định nghĩa lớpPointlưu tọa độ x và y (cả hai đều có kiểuint). Lớp của bạn cần có:- Các thành viên private lưu tọa độ x và y
- Một hàm khởi tạo nhận giá trị x và y
- Các hàm getter
getX()vàgetY()(cả hai đều là const) - Một toán tử
+được nạp chồng để cộng hai điểm với nhau và trả về mộtPointmới có tọa độ là tổng của hai điểm
Hãy triển khai toán tử
+dưới dạng hàm thành viên, nhận mộtPointkhác qua tham chiếu const và trả về mộtPointmới. Đánh dấu hàm làconstvì hàm không sửa đổi toán hạng nào.main.cpp: Đọc bốn số nguyên từ đầu vào (x1, y1, x2, y2 trên các dòng riêng biệt), biểu diễn hai điểm. Tạo hai đối tượngPoint, cộng chúng bằng toán tử+rồi hiển thị kết quả.Định dạng đầu ra:
Point 1: (<x1>, <y1>) Point 2: (<x2>, <y2>) Sum: (<sum_x>, <sum_y>)
Điểm mấu chốt ở đây là p1 + p2 thực chất gọi p1.operator+(p2) ở phía sau. Toán tử được nạp chồng cho phép bạn viết code trực quan như Point p3 = p1 + p2; thay vì viết như Point p3 = p1.add(p2);.
Chuyển các chuỗi đầu vào thành số nguyên bằng std::stoi(). Đừng quên các header guard trong tệp header.
Tự làm thử
#include <iostream>
#include <string>
#include "Point.h"
using namespace std;
int main() {
// Đọc đầu vào
string line1, line2, line3, line4;
getline(cin, line1);
getline(cin, line2);
getline(cin, line3);
getline(cin, line4);
int x1 = stoi(line1);
int y1 = stoi(line2);
int x2 = stoi(line3);
int y2 = stoi(line4);
// TODO: Tạo hai đối tượng Point từ các giá trị đầu vào
// TODO: Cộng hai điểm bằng toán tử +
// TODO: In kết quả theo đúng định dạng yêu cầu:
// Point 1: (<x1>, <y1>)
// Point 2: (<x2>, <y2>)
// Sum: (<sum_x>, <sum_y>)
return 0;
}
Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Lập trình hướng đối tượng
1Nền tảng về OOP
Tệp bên ngoàiBiên dịch và tạo bản dựng C++Tệp header và tệp nguồnNamespace và phạm viGiới thiệu về OOP trong C++Lớp và đối tượngCon trỏ thisPhương thức (hàm thành viên)Thuộc tính (dữ liệu thành viên)Cơ bản về hàm khởi tạo và hàm hủyÔn tập: máy tính đơn giản4Thuộc tính của lớp
Thành viên đối tượng và thành viên tĩnhHàm truy xuất và hàm thiết lậpHàm thành viên hằngTừ khóa mutablePhương thức và biến tĩnhHàm và lớp bạnÔn tập: Trình quản lý tài khoản ngân hàng7Kế thừa
Kế thừa cơ bảnMức truy cập trong kế thừaThứ tự gọi hàm khởi tạo và hàm hủyGhi đè phương thứcHàm ảo và VTableĐa kế thừaKế thừa ảoÔn tập: hệ phân cấp nhân viên2Quản lý bộ nhớ
Bộ nhớ ngăn xếp và heapCon trỏ và tham chiếuBộ nhớ động (new/delete)Con trỏ thông minh trong C++RAII trong C++Ôn tập: Trình quản lý mảng động5Tính đóng gói
Phạm vi truy cập trong C++Tìm hiểu sâu về phạm vi truy cậpẨn thông tinStruct và lớpLớp lồng nhau và lớp bên trongÔn tập: hệ thống hồ sơ sinh viên8Đa hình
Đa hình lúc biên dịch và khi chạyNạp chồng hàmÔn lại hàm ảoHàm ảo thuần túyLớp trừu tượngThiết kế interface trong C++Ép kiểu động và RTTIÔn tập: Máy tính hình học3Hàm khởi tạo và hàm hủy
Hàm khởi tạo mặc địnhHàm khởi tạo có tham sốHàm khởi tạo sao chépHàm khởi tạo di chuyểnDanh sách khởi tạoHàm khởi tạo ủy quyềnTìm hiểu sâu về hàm hủyQuy tắc 3 / 5 / 0Ôn tập: lớp chuỗi6Nạp chồng toán tử
Giới thiệu về nạp chồng toán tửNạp chồng toán tử số họcNạp chồng toán tử so sánhToán tử luồngNạp chồng toán tử gánNạp chồng toán tử [] và ()Toán tử chuyển đổi kiểuÔn tập: lớp ma trận9Mẫu
Mẫu hàmMẫu lớpChuyên biệt hóa mẫuMẫu biến tham sốCơ bản về SFINAE và đặc điểm kiểuÔn tập: vùng chứa tổng quátTự luyện tập: Trình biên dịch C++ online