Menu
CoddyTech

Hàm khởi tạo có tham số

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 19 trên 104.

Hàm khởi tạo có tham số nhận các đối số, cho phép bạn khởi tạo đối tượng với những giá trị cụ thể ngay khi tạo. Thay vì dựa vào các giá trị mặc định, bạn có thể tùy chỉnh trạng thái ban đầu của từng đối tượng.

class Player {
    std::string name;
    int health;
    int level;
public:
    Player(std::string n, int h, int lvl) {
        name = n;
        health = h;
        level = lvl;
    }
};

Player hero("Archer", 100, 5);
Player mage("Wizard", 80, 7);

Bạn có thể định nghĩa nhiều hàm khởi tạo có tham số với các danh sách tham số khác nhau. Đây gọi là nạp chồng hàm khởi tạo, và trình biên dịch sẽ chọn hàm phù hợp dựa trên các đối số bạn cung cấp.

class Rectangle {
    int width, height;
public:
    Rectangle(int side) {          // Hình vuông
        width = height = side;
    }
    
    Rectangle(int w, int h) {      // Rectangle
        width = w;
        height = h;
    }
};

Rectangle square(10);        // Gọi hàm khởi tạo (constructor) thứ nhất
Rectangle rect(10, 20);      // Gọi hàm khởi tạo thứ hai

Tham số có thể có giá trị mặc định, nhờ đó một số đối số trở thành tùy chọn. Điều này giúp giảm nhu cầu tạo nhiều hàm khởi tạo nạp chồng.

class Enemy {
    std::string type;
    int damage;
public:
    Enemy(std::string t, int d = 10) : type(t), damage(d) {}
};

Enemy goblin("Goblin");       // damage mặc định là 10
Enemy dragon("Dragon", 50);   // damage có giá trị 50

Hãy nhớ từ bài học trước: khi bạn định nghĩa một hàm khởi tạo có tham số, trình biên dịch sẽ không còn tự động tạo hàm khởi tạo mặc định nữa. Nếu cần cả hai, bạn phải định nghĩa hàm khởi tạo mặc định một cách tường minh.

challenge icon

Thử thách

Dễ

Hãy xây dựng một hệ thống quản lý hàng tồn kho để tìm hiểu cách hàm khởi tạo có tham số (parameterized constructor) giúp bạn tạo đối tượng với các giá trị ban đầu cụ thể, và cách nạp chồng hàm khởi tạo (constructor overloading) giúp linh hoạt hơn khi tạo đối tượng.

Bạn sẽ tạo hai tệp để sắp xếp code:

  • Product.h: Định nghĩa lớp (class) Product đại diện cho các mặt hàng trong kho. Lớp của bạn cần có:
    • Các thuộc tính (attribute) riêng tư gồm name (chuỗi), price (số thực) và quantity (số nguyên)
    • Một hàm khởi tạo nhận cả ba tham số (name, price, quantity) để khởi tạo đầy đủ một sản phẩm
    • Một hàm khởi tạo chỉ nhận name và price, với quantity mặc định là 1
    • Một hàm khởi tạo chỉ nhận name, với price mặc định là 0.0 và quantity mặc định là 0
    • Một phương thức (method) display() in thông tin sản phẩm theo định dạng: "<name>: $<price> (x<quantity>)"
    • Một phương thức getTotalValue() trả về giá nhân với số lượng
  • main.cpp: Minh họa cả ba hàm khởi tạo bằng cách đọc dữ liệu đầu vào và tạo sản phẩm theo nhiều cách khác nhau. Đọc các thông tin sau từ đầu vào:
    • Dòng đầu tiên: tên, giá và số lượng sản phẩm, được phân tách bằng dấu cách
    • Dòng thứ hai: tên và giá sản phẩm, được phân tách bằng dấu cách
    • Dòng thứ ba: chỉ có tên sản phẩm
    Tạo ba đối tượng Product bằng hàm khởi tạo phù hợp với từng dữ liệu đầu vào, gọi display() cho từng đối tượng, sau đó in tổng giá trị của cả ba sản phẩm theo định dạng: "Total inventory value: $<value>"

Khi in giá, hãy hiển thị hai chữ số thập phân. Ví dụ, nếu bạn tạo một sản phẩm "Laptop" có giá 999.99 và số lượng 5, phần hiển thị phải là "Laptop: $999.99 (x5)".

Thêm tệp tiêu đề vào main.cpp bằng #include "Product.h".

Tự làm thử

#include <iostream>
#include <iomanip>
#include <string>
#include "Product.h"

using namespace std;

int main() {
    // Đọc sản phẩm thứ nhất: tên, giá và số lượng
    string name1;
    double price1;
    int quantity1;
    cin >> name1 >> price1 >> quantity1;
    
    // Đọc sản phẩm thứ hai: tên và giá
    string name2;
    double price2;
    cin >> name2 >> price2;
    
    // Đọc sản phẩm thứ ba: chỉ tên
    string name3;
    cin >> name3;
    
    // TODO: Tạo ba đối tượng Product, mỗi đối tượng dùng hàm khởi tạo phù hợp
    
    // TODO: Gọi display() cho từng sản phẩm
    
    // TODO: Tính và in ra tổng giá trị hàng tồn kho
    // Định dạng: "Total inventory value: $<value>"
    // Dùng fixed và setprecision(1) để hiển thị một chữ số sau dấu thập phân
    
    return 0;
}
quiz iconTự kiểm tra

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

Tự luyện tập: Trình biên dịch C++ online