std::map<int,int> mapy;
++mapy[5];
Có an toàn không khi giả định rằng mapy[5]
sẽ luôn là 1? Ý tôi là, sẽ mapy[5]
luôn nhận giá trị mặc định là 0 trước '++', ngay cả khi không được khai báo rõ ràng, như trong mã của tôi?
std::map<int,int> mapy;
++mapy[5];
Có an toàn không khi giả định rằng mapy[5]
sẽ luôn là 1? Ý tôi là, sẽ mapy[5]
luôn nhận giá trị mặc định là 0 trước '++', ngay cả khi không được khai báo rõ ràng, như trong mã của tôi?
Câu trả lời:
Ngay sau khi bạn truy cập bản đồ bằng toán tử [], nếu khóa không tồn tại, nó sẽ được thêm vào. Bộ khởi tạo mặc định của kiểu int được gọi - vì vậy nó sẽ nhận giá trị 0.
int
giá trị ban đầu của một nguyên thủy chưa được khởi tạo là không xác định - đó có thể là 0 hoặc có thể là -99765521. Đã bao giờ có một int
biến lớp chưa được khởi tạo và có một trong những giá trị kỳ lạ đó xuất hiện trong chương trình của bạn? Điều đó nói rằng, tôi đã thử nghiệm điều này và nó có vẻ hoạt động. #include <stdio.h> #include <map> using namespace std; int main() { map<int,int> m ; for( int i = 0 ; i < 100 ; i++ ) m[i]++ ; for( const pair<int,int>& p : m ) printf( "m[%d] => %d\n", p.first, p.second ) ; }
Vâng, nó là an toàn để giả định.
Do đó, bản đồ operator[]
được chỉ định: ([map.access])
Hiệu ứng: Nếu không có khóa tương đương
x
trong bản đồ, hãy chènvalue_type(std::move(x), T())
vào bản đồ.
Trả về: Tham chiếu đếnmapped_type
tương ứng vớix
in*this
.
T()
sử dụng khởi tạo giá trị cho tất cả T
ngoại trừ void
([expr.type.conv] / 2) và khởi tạo giá trị cho một kết quả ban đầu trong khởi tạo bằng 0 ([dcl.init] / 7) .
Do đó, biểu thức đánh giá một tham chiếu đến một đối tượng có giá trị bằng không ([dcl.init] / 5) .
Sau operator++
đó, cuộc gọi tăng đối tượng đó thành một và đánh giá thành một.
(Tất cả các tham chiếu đều là C ++ 11.)
Có, giá trị mặc định sẽ là giá trị mặc định của loại đó. Nếu bạn muốn một mặc định khác, bạn có thể tạo một lớp hoạt động giống như một int nhưng có một phương thức khởi tạo mặc định khác.
Câu trả lời của Rep_Movsd được đơn giản hóa quá mức và có khả năng dẫn đến nhiều quan niệm sai lầm cực kỳ nguy hiểm. Các kiểu dữ liệu ban đầu trong C ++ không có bộ khởi tạo. Louis Brandy đã có một buổi nói chuyện tuyệt vời, trong đó anh ấy thảo luận về nhiều lỗi C ++ phổ biến ở Facebook và sự hiểu lầm về cách hoạt động của std :: map <> [] là một trong những lỗi mà anh ấy đã thảo luận, đây là một nguồn tuyệt vời mặc dù anh ấy không đi vào chi tiết về cách thức hoạt động của std :: map <> [].
Nói chung, int không được khởi tạo và không được xác định giống như tất cả các kiểu nguyên thủy. Điều đó đang được nói khi được sử dụng với std :: map <> [], int có giá trị mặc định bằng 0 được thiết lập thông qua một quá trình gọi là khởi tạo giá trị. Khởi tạo giá trị là một quá trình thực sự hoạt động với các cấu trúc nói chung. Ví dụ,
struct Struct {
Struct() : memberVariable() {}
int memberVariable;
};
Sẽ luôn khởi tạo số nguyên bằng 0. Nếu các biến thành viên là các kiểu nguyên thủy khác, chúng cũng sẽ có các giá trị khởi tạo cụ thể. Ví dụ: các kiểu sau được khởi tạo, thông qua việc khởi tạo giá trị như vậy:
bool = false
float = 0.0f
enum = (enum type) 0
pointer = null pointer
pointer to member = null member pointer
Hãy cực kỳ cẩn thận khi làm việc với dữ liệu không được khởi tạo rõ ràng. Một điều cuối cùng, hãy xem xét đoạn mã sau
map<string, int> myMap;
cout << myMap["Foo"];
Mã này không chỉ luôn khởi tạo số nguyên thành 0 mà còn chèn số 0 vào bản đồ. Tóm lại, các kiểu dữ liệu nguyên thủy là không xác định nếu không được khởi tạo, nhưng trong một số trường hợp, chẳng hạn như khởi tạo giá trị cấu trúc hoặc bản đồ sẽ khởi tạo dữ liệu nguyên thủy với một giá trị cụ thể.
struct
từ khóa kế thừa . Mã bạn đã hiển thị chứa một lớp . C ++ không có cấu trúc. Đọc thêm: stackoverflow.com/a/36917400/560648 stackoverflow.com/a/34108140/560648