STDIO
Tìm kiếm gần đây
    • Nội dung
    • QR Code
    • 0
    • Bình luận
    • Sao chép

    Thao Tác Với Constant trong C++

    Tìm hiểu về các thao tác với constant trong C++.
    21/07/2015
    06/09/2020
    6 phút đọc
    Thao Tác Với Constant trong C++

    Mở đầu

    const (Constant – Hằng) là từ khóa để chỉ định một biến hay đối tượng nào đó là hằng, tức là không thay đổi được giá trị, mọi hành động thay đổi giá trị của hằng đều được compiler báo lỗi.

    Sử dụng biến hằng khi muốn giá trị của biến, đối tượng đó không bị thay đổi trong mọi trường hợp, ví dụ như số PI luôn bằng 3.14.

    Cơ bản

    Bắt đầu với những khai báo đơn giản nhất:

    int main()
    {
    	const int x = 10;
    	int const y = 50;
    
    	x = 5;	// Báo lỗi
    	y = 7;	// Báo lỗi
    
    	return 0;
    }

    Vị trí đặt const dù trước hay sau int thì đều có chung một chức năng là chỉ định x, y là hằng, thay đổi giá trị của 2 biến đó sẽ bị báo lỗi.

    Biến tham chiếu

    Biến tham chiếu là biến có thể thay đổi giá trị của vùng nhớ mà nó tham chiếu tới một cách trực tiếp. Trong trường hợp biến tham chiếu là hằng thì sao? Xét ví dụ sau:

    int main()
    {
    	int x = 10;
    	const int &A = x;	// Khai báo A là hằng tham chiếu tới vùng nhớ của x
    
    	A = 6;	// Báo lỗi do A là biến tham chiếu hằng
    	x = 6;	// Không báo lỗi do x là một biến bình thường
    
    	return 0;
    }

    Hằng tham chiếu A sẽ không thể thay đổi giá trị của x được nữa, cũng có thể khai báo int const &A = x;

    Biến con trỏ

    Biến con trỏ là biến lưu địa chỉ vùng nhớ mà nó trỏ tới. Khi biến con trỏ có thêm từ khóa const thì chuyện gì sẽ xảy ra? Xét ví dụ sau:

    int main()
    {
    	int x = 7;
    	int y = 13;
    
    	const int *p = &x;	// Đọc là Non-const pointer to a const value
    
    	*p = 100;	// Báo lỗi
    	p = &y;	// Không báo lỗi
    
    	return 0;
    }

    Không thể thay đổi giá trị vùng nhớ mà p chỉ tới thông qua p,  nhưng vẫn có thể thay đổi được địa chỉ vùng nhớ mà p trỏ tới.

    Xét ví dụ tiếp theo:

    int main()
    {
    	int x = 7;
    	int y = 13;
    
    	int *const p = &x;	// Đọc là Const pointer to a non-const value
    
    	*p = 100;	// Không báo lỗi
    	p = &y;	// Báo lỗi
    
    	return 0;
    }

    p đã có thể thay đổi giá trị vùng nhớ mà nó trỏ tới, nhưng không thể thay đổi địa chỉ mà nó trỏ tới được nữa.

    Nếu muốn con trỏ p vừa không thể thay đổi địa chỉ của vùng nhớ, vừa không thể thay đổi giá trị vùng nhớ đó thì sao?

    const int *const p = &x;    // Đọc là Constant pointer to a const value

    Tham số hàm là const reference

    Khi xây dựng một hàm, đôi lúc hay sử dụng tham số truyền vào là tham chiếu do tác dụng tiết kiệm chi phí của nó, một ưu điểm nữa của nó là có thể thay đổi được giá trị của tham số truyền vào, nhưng đôi khi lại không mong muốn có bất kì sự thay đổi nào. Khi muốn sử dụng tham chiếu để vừa tiết kiệm chi phí, vừa ngăn được tình trạng thay đổi giá trị thì sẽ dùng tới tham số const reference. Cách dùng như sau:

    int func(const int &number)
    {
    	//Your Codes
    }

    Constant trong lập trình hướng đối tượng

    Sử dụng lớp sau làm tiền đề để giải thích:

    class MyClass
    {
    private:
    	int m_Data;
    
    public:
    	MyClass(int Data) : m_Data(Data) {}
    
    	// Message() Function for non-const object
    	void Message()
    	{
    		cout << "This is non-const object" << endl;
    	}
    
    	// Message() Function for const object
    	void Message() const
    	{
    		cout << "This is const object" << endl;
    	}
    
    	// Get value of m_Data to use or modify
    	int &getData()
    	{
    		return m_Data;
    	}
    };

    Phương thức Message() thứ 2 có một từ khóa const ở cuối, nghĩa là Message() đó là một phương thức hằng thành viên. Khi một phương thức là phương thức hằng, thì tất cả các thuộc tính (biến thành viên) của lớp đó sẽ không được thay đổi giá trị trong quá trình hiện thực hàm, mọi hành động thay đổi giá trị của thuộc tính trong hàm compiler đều báo lỗi, trừ khi thuộc tính đó được khai báo với từ khóa mutable đằng trước. Hơn nữa, đối với các đối tượng hằng, thì đối tượng hằng chỉ sử dụng được các phương thức hằng.

    Có hàm main như sau:

    int main()
    {
    	MyClass obj1(13);
    	const MyClass obj2(100);
    
    	obj1.getData() = 86;
    	//obj2.getData() = 1;	//báo lỗi do getData() không phải phương thức hằng
    
    	obj1.Message();
    	obj2.Message();
    
    	return 0;
    }

    Khi chương trình được thực thi, kết quả in ra màn hình như sau:

    This is non-const object
    This is const object

    Như vậy đối tượng obj1 đã gọi phương thức Message() thứ nhất, còn obj2 gọi phương thức Message() thứ 2. Lý do đơn giản: obj1 là đối tượng bình thường, còn obj2 là đối tượng hằng nên chỉ có thể gọi hàm Message() thứ 2.

    Lưu ý: Phương thức hằng có thể luôn được gọi. Tức là obj1 vẫn có thể gọi được phương thức Message() thứ 2, khi phương thức Message() thứ 1 bị xóa đi, thì kết quả in ra màn hình sẽ là:

    This is const object
    This is const object

    Một vấn đề nữa, thấy obj2 không thể dùng phương thức getData(). Vậy nếu muốn dùng thì sao? Theo như nãy giờ đã nói thì chỉ cần thêm const vào sau getData() là xong. Nhưng do getData() trả về tham chiếu, nên giá trị nó trả về phải là 1 Lvalue có thể thay đổi giá trị, nên nếu chỉ thêm const vào sau thì nhất định sẽ có lỗi. Hãy overload lại 1 phương thức getData() như sau:

    const int &getData() const
    {
    	return m_Data;
    }

    Như vậy có thể dùng obj2 để gọi getData() được, nhưng do trả về hằng tham chiếu nên không thể dùng getData() để thay đổi giá trị của m_Data giống như đối với obj1 được.

    Const Cast

    Xét hàm sau:

    int func(int &number)
    {
    	number += 100;
    	return number;
    }

    Khi truyền một biến int vào hàm func(), thì hàm sẽ tăng giá trị của số đó thêm 100, đồng thời trả về giá trị đó. Nhưng trong trường hợp có một biến const, muốn sử dụng hàm func() để trả về số lớn hơn 100, nhưng do biến đó là const nên khi truyền vào compiler sẽ báo lỗi? Dùng toán tử const_cast để giải quyết như sau:

    int main()
    {
    	const int x = 13;
    	int y;
    
    	//y = func(x);	// Báo lỗi
    
    	y = func(const_cast<int &>(x));	// Dùng const_cast
    
    	printf("y = %d\n", y);
    	printf("x = %d\n", x);
    
    	return 0;
    }

    Kết quả xuất ra màn hình như sau:

    y = 113;
    x = 13;

    Như vậy là vẫn có giá trị của y như mong muốn và giá trị của x vẫn giữ nguyên, đã có thể sử dụng hàm func().

    Modern C++

    Modern C++

    STDIO Training - Đào Tạo Lập Trình C++.

    Phù hợp cho bạn

    Đề xuất

    Thao Tác Với Chuỗi Trong C/C++

    Thao Tác Với Chuỗi Trong C/C++

    Kiến thức cơ bản trong thao tác xử lý chuỗi trong C++.

    Modern C++C++98

    28/07/2015

    Thao Tác với Tài Liệu PDF Sử Dụng Thư Viện iTextSharp trong C#

    Thao Tác với Tài Liệu PDF Sử Dụng Thư Viện iTextSharp trong C#

    Giới thiệu thư viện iTextSharp, hướng dẫn cài đặt và thao tác với tài ...

    C# for AutomationKiến Thức

    16/10/2015

    Khám phá thêm

    Thao Tác với XML Sử Dụng TinyXML trong C++

    Thao Tác với XML Sử Dụng TinyXML trong C++

    Hướng dẫn thao tác với XML sử dụng TinyXML trong C++.

    Modern C++Win32 API

    21/10/2015

    GameObject - Thao Tác với C# Script

    GameObject - Thao Tác với C# Script

    Giới thiệu các thành phần chung của 1 GameObject và các thao tác với C# ...

    Lập Trình GameUnity

    08/08/2015

    Định Dạng Ảnh Bitmap - Giới Thiệu và Các Thao Tác Cơ Bản

    Định Dạng Ảnh Bitmap - Giới Thiệu và Các Thao Tác Cơ Bản

    Trong đời thường, bạn sẽ gặp các file ảnh có định dạng .PNG, .JPG, .TGA, ...

    Phan Tấn Phúc

    13/09/2017

    Thao Tác với MySQL Database Sử Dụng MySQLi Extension trong PHP

    Thao Tác với MySQL Database Sử Dụng MySQLi Extension trong PHP

    Hướng dẫn cách thao tác với MySQL database sử dụng MySQLi Extension ...

    PHPCheat Sheet

    07/11/2015

    Nhập Xuất Cơ Bản trong C/C++

    Nhập Xuất Cơ Bản trong C/C++

    Bài viết là tiền đề giúp cho người đọc làm quen các thao tác cơ bản với ...

    Modern C++C++98

    18/03/2016

    Làm Quen với SQL Server

    Làm Quen với SQL Server

    Giới thiệu SQL Server của Microsoft và hướng dẫn thao tác với dữ liệu ...

    Rye Nguyen

    30/07/2015

    9 Tính Năng Quan Trọng Trong C++11

    9 Tính Năng Quan Trọng Trong C++11

    C++11 là một phiên bản cải tiến và nâng cấp từ C++98 (hay các bạn vẫn ...

    Modern C++C++0x

    13/08/2015

    Các Hàm memset() - memcpy() - memcmp() Trong C

    Các Hàm memset() - memcpy() - memcmp() Trong C

    Giới thiệu về các hàm thao tác trên bộ nhớ trong thư viện string.h trong ...

    Modern C++C++98

    21/07/2015

    STDIO
    Trang chính
    Công ty TNHH STDIO

    30, Trịnh Đình Thảo, Hòa Thạnh, Tân Phú, Hồ Chí Minh
    +84 28.36205514 - +84 942.111912
    developer@stdio.vn

    383/1 Quang Trung, Phường 10, Quận Gò Vấp, Hồ Chí Minh
    Số giấy phép ĐKKD: 0311563559 do sở Kế hoạch và Đầu Tư TPHCM cấp ngày 23/02/2012

    ©STDIO, 2013 - 2020