2013-05-23 45 views
5

tại sao hàm tạo mặc định không được trình biên dịch thêm vào cho lớp có chứa các thành viên dữ liệu không đổi. xin vui lòng xem mã dưới đây, trong đó tôi đã tuyên bố thành viên dữ liệu liên tục 'a' và trong khi cố gắng tạo đối tượng cho một lớp 'ClassA' nó nói rằng không có hàm tạo mặc định thích hợp có sẵn. Hãy giúp tôi.tại sao hàm tạo mặc định không có mặt cho một lớp chứa các thành viên dữ liệu const

#include "stdafx.h" 
#include <iostream> 
using namespace std; 

class ClassA 
{ 
    private: 
    const int a; 
    public : 
    void print() 
    { 
     cout << "hello world" << endl; 
    } 
}; 

int main() 
{ 
    ClassA obj; 
    obj.print(); 
    return 0; 
} 
+4

Bạn phải khởi tạo 'a'. – chris

+0

Mặc dù có ý kiến ​​ở nơi khác, khởi tạo rõ ràng cho 'a' là với trình khởi tạo mặc định, cụ thể là' int() ', sẽ khởi tạo bằng 0. Có, đây là (gần như) vô nghĩa, nhưng không ai có một tham chiếu là tại sao nó không phải là có thể cho các nhà xây dựng mặc định? – Keith

+0

@Keith Nó chỉ là một sự lựa chọn của ngôn ngữ. Các thành viên dữ liệu tích hợp không được khởi tạo theo mặc định. – juanchopanza

Trả lời

2

Vì giá trị const không thể thay đổi sau khi được khởi tạo như thế nào một nhà xây dựng mặc định chọn giá trị cho nó. Vì vậy, hàm tạo mặc định không được tạo

0

Tôi tin rằng bạn phải khởi tạo rõ ràng thành viên const trong hàm tạo, bạn phải đặt chúng ở đâu đó và vì chúng là const, bạn có thể đặt nó ở bất cứ nơi nào bạn thích!

2

Kể từ a là một biến const, bạn có thể khai báo nó như tĩnh và khởi tạo nó, mà không sử dụng một constructor như sau,

class ClassA 
{ 
    private: 
    const static int a=10; 
    public : 
    void print() 
    { 
     cout << "hello world" << endl; 
    } 
}; 

int main() 
{ 
    ClassA obj; 
    obj.print(); 
    return 0; 
} 
1

Loại int không có một giá trị mặc định trong C hoặc C++, do đó giá trị của a sẽ không được xác định. Ví dụ, VC++ sẽ điền giá trị a với một giá trị mặc định khác nếu nó chạy trong gỡ lỗi nếu nó được chạy trong chế độ phát hành.

Trong debug, VC++ populates uninitialized memory với các giá trị sau:

  • 0xCCCCCCCC - Được sử dụng bởi Microsoft C++ gỡ lỗi thư viện thời gian chạy và nhiều môi trường DOS để đánh dấu bộ nhớ ngăn xếp chưa được khởi tạo.
  • 0xCDCDCDCD - Được sử dụng bởi C của Microsoft/C++ debug malloc() để đánh dấu bộ nhớ heap uninitialized, thường trở về từ HeapAlloc()

Vì vậy, bằng không khởi a chương trình của bạn sẽ có giá trị const khác nhau mỗi thời gian.

4

Quy tắc C++ 03 được chỉ định trong 12.6.2/4 [class.base.init]. Nếu một thành viên không tĩnh của một lớp không được đề cập trong danh sách initializer thành viên của một constructor thì nếu nó là const đủ điều kiện, nó sẽ phải là loại không POD với một constructor do người dùng khai báo nếu không chương trình sẽ bị bệnh - hình thành. Một hàm tạo ngầm được định nghĩa được định nghĩa với một danh sách khởi tạo thành viên rỗng (và phần thân trống), trong trường hợp này, gây ra hàm tạo ngầm mặc định được khai báo ngầm định, nó cũng sẽ làm cho chương trình bị hỏng.

Quy tắc C++ 11 tương đương với điều tương tự. Các thành viên dữ liệu không tĩnh không được chỉ định trong danh sách khởi tạo thành viên là mặc định được khởi tạo. Trong C++ 11 8.5/6 [dcl.init], "[...] Nếu chương trình yêu cầu khởi tạo mặc định của đối tượng thuộc loại đủ điều kiện const T, T phải là loại lớp với người dùng được cung cấp nhà xây dựng mặc định." trong đó trường hợp này sẽ rơi xuống cùng một quy tắc.

+0

+1 để tham khảo tiêu chuẩn. – Keith

Các vấn đề liên quan