2008-11-26 77 views
10

Tôi đã tự hỏi liệu có thể khai báo một mảng (kích cỡ không biết tại thời điểm này), như một thành viên riêng của một lớp và sau đó đặt kích thước trong hàm tạo của lớp. Ví dụ:Khai báo mảng C++ trong tiêu đề

class Test { 
int a[]; 
public: 
Test(int size); 
}; 

Test::Test(int size) { 
a[size]; // this is wrong, but what can i do here? 
} 

Tôi có thể sử dụng mảng động hay không? Cảm ơn!

Trả lời

13

Không điều này là không thể. Khai báo mảng trong tiêu đề phải có giá trị có kích thước không đổi. Nếu không, nó không thể cho các cấu trúc như "sizeof" hoạt động đúng. Bạn sẽ cần khai báo mảng như một kiểu con trỏ và sử dụng [] mới trong hàm tạo. Thí dụ.

class Test { 
    int *a; 
public: 
    Test(int size) { 
     a = new int[size]; 
    } 
    ~Test() { delete [] a; } 
private: 
    Test(const Test& other); 
    Test& operator=(const Test& other); 
}; 
+0

Cần thêm CopyConstructor và toán tử gán và gọi đúng phiên bản xóa bỏ. Hoặc sử dụng một vector. –

+0

Drat. Tôi thường gọi người khác ra ngoài cho cùng một vấn đề ... Sẽ sửa chữa ngay – JaredPar

+0

Bạn quên sửa xóa. Tôi cũng vậy. –

3

Trước hết, tốt hơn hết là khởi tạo mọi thứ trong danh sách khởi tạo của hàm tạo, chứ không phải trong phần thân của hàm tạo.

Bạn chỉ có thể khởi tạo một mảng có giới hạn được xác định trước nếu bạn biết rằng giới hạn tại thời gian biên dịch. Trong tình huống này, bạn sẽ cần phải tự động phân bổ không gian.

Bạn phải nhớ sau đó để có một destructor sẽ xóa mảng khi đối tượng bị phá hủy hoặc bạn sẽ nhận được một rò rỉ bộ nhớ.

17

trả lời ngắn: Không (Kích thước của một mảng được xác định tại thời gian biên dịch chỉ)
dài trả lời:

Bạn có thể sử dụng một vector để đạt được kết quả tương tự:

class Test 
{ 
    std::vector<int> a; 
    public: 
     Test(std::size_t size): 
      a(size) 
     {} 
}; 
+0

Tôi muốn mọi người thêm nhận xét khi đánh dấu câu trả lời. Ít nhất bạn quay lại 0 – JaredPar

+1

Người ghét thích ghét danh tính. Ghét người ghét! Tôi cho bạn một điểm. –

+0

+1 Đối với một câu trả lời thực tế tốt, nếu ai đó có một vấn đề với nó giải thích tại sao (vì vậy chúng tôi có thể chỉ cho bạn Martin là đúng) – orip

0

Không, điều này là không thể. Bạn nên sử dụng mảng động chẳng hạn như std::vector. C99 cho phép cấu trúc có mảng chưa được đánh dấu là chỉ thành viên cuối cùng, nhưng ngay cả khi bạn làm điều này, bạn vẫn phải tự phân bổ bộ nhớ, ví dụ: với malloc().

4

Như câu trả lời khác đã chỉ ra, kích thước của một mảng được cố định tại thời gian biên dịch. Tuy nhiên, bằng cách sử dụng các mẫu bạn có thể parameterise kích thước tại thời gian biên dịch:

template <int N> class Test { 
    int a[N]; 
public: 
    Test() { } 
}; 

Test<5> test; 
Test<40> biggertest; 

Kỹ thuật này không cho phép bạn tính toán kích thước tại chạy thời gian (như các giải pháp năng động std::vector làm), nhưng tùy thuộc vào nhu cầu của bạn này có thể là đủ.

+0

Điều đó làm việc, nhưng mỗi phiên bản của Kiểm tra bây giờ là một lớp khác nhau. truy cập để sao chép, vv) –

+0

Không phải là bạn có thể sao chép Bài kiểm tra <2> vào Bài kiểm tra <1> anyway - nó không phù hợp. Ngoài ra, không có đa hình - Kiểm tra <1> và Kiểm tra <2> là các loại không tương thích, vì vậy mọi chức năng xử lý chúng để được templated quá. –

+0

không phải lo lắng. anh ta vẫn có thể tạo mẫu operator = và cctor. –

0

Điều bạn đang nói đến là không thể. Các lớp luôn có kích thước không đổi. Bạn có thể có lớp của bạn sử dụng một con trỏ đến một mảng động được phân bổ hoặc bạn có thể sử dụng một std :: vector.

2

Xem Martin giải pháp (sử dụng std::vector), và nhớ rằng ngay cả khi bạn cần phải vượt qua một bộ đệm để một API C std::vector cho phép bạn làm điều đó bằng cách thông qua &vec[0]:

std::vector<char> vec(10); 
memset(&vec[0], 0, vec.size()); 

Nó được bảo đảm để làm việc, nhưng chỉ nếu vectơ không trống (C++ quirks, < sigh>).

+0

Tôi sử dụng thủ thuật & vec [0] rất nhiều, mặc dù memset() trong trường hợp này là không cần thiết vì vec đã được khởi tạo cho tất cả các số không. –

+0

memset chỉ là một ví dụ, nhưng bạn nói đúng :) – orip

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