30/09/2018, 23:40

Gán giá trị cho const member bằng constructor trong C++?

mình có đoạn chương trình sau
biến const songuyen trong class, k thể thay đổi bằng setter, hay friend function, friend method, hay nhập giá trị, hoặc dùng constructor kiểu

number(int songuyen = 1){
          this->songuyen = songuyen;
	}

thì đều lỗi

nhưng nếu sử dụng constructor kiểu

number(int songuyen = 1):songuyen(songuyen){

	}

thì lại được, tại sao nhỉ

#include <iostream>
using namespace std;

class number{
private:
	const int songuyen = 0;
public:
	void xuat(){
		cout << songuyen << endl ;
	}
	number(int songuyen = 1):songuyen(songuyen){
	}
};

int main(){
	number a;
	a.xuat();
	system("pause");
	return 0;
}
Nguyễn Xuân Phúc viết 01:54 ngày 01/10/2018

constant không thể thay đổi giá trị sau khi được tạo ra
vì vậy, việc thay đổi bằng setter hay friend function hay member functions đều thực hiện sau khi object được tạo, mà như thế thì không thể thay đổi được giá trị của const.
tuy nhiên, constructor không phải được gọi sau khi object được tạo, mà nó thực hiện ngay khi object đang được tạo, tức là lúc này const mới bắt đầu được tạo ra, nên việc gán giá trị lúc này là hoàn toàn hợp lệ, còn cái value trong lúc mình define class set cho const, value đó chỉ là default mà thôi.

abcxyz viết 01:51 ngày 01/10/2018
number(int songuyen = 1):songuyen(songuyen){

	}

với

number(int songuyen = 1){
        this->songuyen = songuyen;
	}

2 hàm khởi tạo này khác nhau ntn, là 2 cách gán giá trị khác nhau nhưng tại sao 1 cái được ,1 cái không, 2 hàm khởi tạo này đều chạy khi đối tượng được tạo ra

Nguyễn Xuân Phúc viết 01:48 ngày 01/10/2018

à sorry, hôm qua đọc k kỹ, chỉ thấy có constructor init bên dưới nên nói không rõ chỗ thời điểm được tạo của const.
Tức là ngay sau khi bước vào constructor thì các biến - member variable cần thiết đều đã được tạo ra để sẵn sàng cho việc khởi tạo trong constructor.

 number(int songuyen = 1){
     this->songuyen = songuyen;
 }

như vậy, ở hàm này , khi bước vào lệnh this->songuyen = songuyen thì lúc này số nguyên đã tồn tại, là const -> xem lại định nghĩa

number(int songuyen = 1):songuyen(songuyen){
}

nhưng ở đây thì khác, songuyen(songuyen) là 1 preprocess trước khi bước vào hàm, là chúng ta đang init class members variables, tức là lúc này đang init ngay khi object được tạo, khi biến đang được tạo

Mai Anh Dũng viết 01:48 ngày 01/10/2018

Thảo luận thêm một tí.

Câu hỏi này có thể sửa lại và mở rộng:

  1. Sửa: Gán giá trị cho const member bằng constructor trong C++

  2. Mở rộng: Gán giá trị cho non-static const và reference member của class trong C++.

  • non-static const tức là chỉ là const mà không có tính static.
int const soNguyen;
  • static const tức là const và có tính static.
static int const soNguyen;

Static trong class là để tất cả các thực thể (instances) của class đó xài chung một biến soNguyen này. Nhưng giá trị soNguyen này không đổi.

Cái static const này thì phải được khởi tạo ngoài class, trong 1 file .cpp. Hoặc cách khác là dùng constexpr C++11.

  • Reference là một dạng khác, tương đối giống với con trỏ, nhưng khác con trỏ rất nhiều.
  1. Có thể mở rộng hơn tí nữa, nhưng mà trở thành nhiều quá. Đọc bài này hay hơn: http://www.geeksforgeeks.org/when-do-we-use-initializer-list-in-c/

Nói ngắn gọn: Không chỉ non-static const member mà reference member cũng phải sử dụng Initialization list.

Initialization list tức là cái dấu : đi kèm theo sau là ten_member(bien_khoi_tao)

class DayNhauHoc {
    private:
        int & numMember;
    public:
        DayNhauHoc(int & numMem) : numMember(numMem) { }
};
Nguyễn Xuân Phúc viết 01:55 ngày 01/10/2018

non-static const tức là const và có tính static.

edit đoạn này a ơi

Mai Anh Dũng viết 01:45 ngày 01/10/2018

haha, thank Phúc

Ba Van viết 01:48 ngày 01/10/2018

Hello.
Tôi có chút thắc vde chưa hiểu lắm của a Đạt.
1.static const tức là const và có tính static.

  • a có thể giải thích rõ hơn về const và lại có tính static là ntn?
    2.[quote=“ltd, post:6, topic:34211”]
    Cái static const này thì phải được khởi tạo ngoài class, trong 1 file .cpp. Hoặc cách khác là dùng constexpr C++11.
    [/quote]

-Tại sao tôi thấy một số khai báo static constexpr char const * const. (tức dùng constexpr c++11) trong file.h
-Nhưng vẫn phải khai báo constexpr char const * const ở file.cpp.
Xin cảm ơn!

Bài liên quan
0