Bỏ qua để đến nội dung

Struct trong C++

struct cho phép gộp nhiều biến có kiểu dữ liệu khác nhau lại thành một kiểu dữ liệu mới, dùng để biểu diễn một thực thể có nhiều thuộc tính - ví dụ một điểm tọa độ, một sinh viên, hay một sản phẩm.

#include <iostream>
struct Point {
int x;
int y;
};
int main() {
Point p1; // Tạo một biến kiểu Point
p1.x = 10;
p1.y = 20;
std::cout << p1.x << ", " << p1.y << std::endl; // 10, 20
return 0;
}

Dấu . dùng để truy cập từng thành viên (member) của struct.

struct Point {
int x;
int y;
};
int main() {
Point p1 = {10, 20}; // Khởi tạo theo thứ tự khai báo thành viên
Point p2{30, 40}; // Cú pháp khởi tạo hiện đại (uniform initialization, C++11)
std::cout << p1.x << ", " << p1.y << std::endl; // 10, 20
std::cout << p2.x << ", " << p2.y << std::endl; // 30, 40
return 0;
}

Struct với nhiều kiểu dữ liệu khác nhau

Phần tiêu đề “Struct với nhiều kiểu dữ liệu khác nhau”
#include <iostream>
#include <string>
struct Student {
std::string name;
int age;
double gpa;
};
int main() {
Student s1 = {"Alice", 20, 3.8};
std::cout << s1.name << ", " << s1.age << " tuoi, GPA: " << s1.gpa << std::endl;
return 0;
}
#include <iostream>
#include <string>
struct Student {
std::string name;
int age;
};
int main() {
Student students[3] = {
{"Alice", 20},
{"Bob", 22},
{"Charlie", 21}
};
for (const Student& s : students) {
std::cout << s.name << " - " << s.age << " tuoi" << std::endl;
}
return 0;
}

Khi có con trỏ trỏ đến struct, dùng toán tử -> (arrow operator) thay vì . để truy cập thành viên - cách viết ngắn gọn của (*ptr).thanh_vien:

#include <iostream>
struct Point {
int x;
int y;
};
int main() {
Point p1 = {10, 20};
Point* ptr = &p1;
std::cout << (*ptr).x << std::endl; // 10 - cách viết dài
std::cout << ptr->x << std::endl; // 10 - cách viết gọn, tương đương
ptr->x = 100; // Thay đổi giá trị thông qua con trỏ
std::cout << p1.x << std::endl; // 100
return 0;
}

Vì struct có thể chứa nhiều dữ liệu, nên truyền theo const& để tránh sao chép không cần thiết (giống như với std::string):

#include <iostream>
struct Point {
int x;
int y;
};
double distance_from_origin(const Point& p) {
return std::sqrt(p.x * p.x + p.y * p.y);
}
int main() {
Point p1 = {3, 4};
std::cout << distance_from_origin(p1) << std::endl; // 5
return 0;
}

Struct với hàm thành viên (giới thiệu nhanh)

Phần tiêu đề “Struct với hàm thành viên (giới thiệu nhanh)”

struct trong C++ (khác với C) cũng có thể chứa hàm, không chỉ dữ liệu - đây là bước đệm dẫn đến khái niệm class trong lập trình hướng đối tượng:

#include <iostream>
struct Circle {
double radius;
double area() { // Hàm thành viên
return 3.14159 * radius * radius;
}
};
int main() {
Circle c = {5.0};
std::cout << c.area() << std::endl; // 78.53975
return 0;
}

Sự khác biệt duy nhất giữa structclass trong C++ là mức truy cập mặc định: thành viên của struct mặc định là public, còn của class mặc định là private. Chi tiết về lập trình hướng đối tượng (class, kế thừa, đa hình…) sẽ được trình bày trong một phần học riêng.

  • struct gộp nhiều biến (thành viên) có kiểu khác nhau thành một kiểu dữ liệu mới
  • Truy cập thành viên bằng . với biến struct thường, và -> với con trỏ đến struct
  • Nên truyền struct vào hàm bằng const& để tránh sao chép dữ liệu không cần thiết
  • struct trong C++ cũng có thể chứa hàm thành viên, khác biệt duy nhất với class là mức truy cập mặc định