2011-12-11 44 views
14

Tôi đã tự hỏi liệu có thể tạo ra một mảng các đối tượng khi đối tượng cần những thứ được truyền vào nó cho hàm tạo. Tôi muốn một cái gì đó như thế này:cách tự động khai báo một mảng các đối tượng với một hàm dựng trong C++

MyClass *myVar; 
myVar = new MyClass[num]; // I would like to specify the array size after declaration 
int i = 0; 
for(i = 0;i < num;i++) 
    myVar[i] = new MyClass(0,0); // I would also like to populate the array with new objects 

Tôi biết rằng công trình này:

MyClass *myVar; 
myVar = new MyClass[num]; 

nhưng điều này chỉ hoạt động khi các nhà xây dựng không có gì thông qua vào nó. Là những gì tôi đang cố gắng để làm có thể? Nếu vậy, làm thế nào để làm điều đó?

EDIT: Tôi đã tìm hiểu cách thực hiện bằng cách sử dụng mảng. Đây là cách tôi đã làm điều đó:

MyClass **myVar; 
myVar = new MyClass *[num]; 
for(i = 0;i < num;i++) 
    myVar[0] = new MyClass(0,0); 

Tôi sẽ sử dụng vectơ và như vậy nhưng giáo viên của tôi đã yêu cầu chúng tôi sử dụng mảng cơ bản bất cứ khi nào có thể. Các giải pháp trên tôi thực sự nhận được từ một số mã giáo viên của tôi đã viết. Cảm ơn mọi sự giúp đỡ của bạn!

Trả lời

21
MyClass *myVar; 
myVar = new MyClass[num]; 

Thực tế trong biểu mẫu này, bạn không thể gọi hàm tạo có tham số. Nó không được phép theo đặc tả ngôn ngữ.

Tuy nhiên, nếu bạn sử dụng std::vector, mà tôi khuyên bạn nên sử dụng, sau đó bạn có thể tạo một vector gọi constructor không mặc định như:

#include <vector> //header file where std::vector is defined 

std::vector<MyClass> arr(num, MyClass(10,20)); 

Nó tạo ra một vector của num yếu tố, mỗi yếu tố được tạo ra bằng cách gọi copy-constructor của lớp, chuyển số MyClass(10,20) làm đối số cho nó.

Vectơ cũng tốt vì bây giờ bạn không cần tự quản lý bộ nhớ. Không phân bổ thủ công, cũng không phải phân bổ thủ công. Ngoài ra, bạn có thể biết số lượng thành phần bằng cách gọi arr.size() bất kỳ lúc nào. Bạn luôn biết có bao nhiêu phần tử chứa trong vector. Bạn cũng có thể thêm các yếu tố bất cứ lúc nào, chỉ cần bằng cách gọi hàm .push_back() thành viên như:

arr.push_back(MyClass(20,30)); 

Và bây giờ bạn có thể truy cập vào các yếu tố, giống như bạn truy cập mảng, tức là bằng cách sử dụng chỉ mục:

f(arr[i]); // 0 <= i < arr.size(); 

Ngoài ra, bạn có thể sử dụng trình vòng lặp để tạo điều kiện lập trình thành ngữ, cho phép bạn sử dụng các hàm thuật toán khác nhau từ <algorithm> tiêu đề là:

#include <algorithm> //header file where std::for_each is defined 

std::for_each(arr.begin(), arr.end(), f); 

wher e f là hàm lấy một đối số thuộc loại MyClass& (hoặc MyClass const &) tùy thuộc vào những gì bạn muốn làm trong f.

Trong C++ 11, bạn có thể sử dụng lambda như:

std::for_each(arr.begin(), arr.end(), [](const MyClass & m) 
             { 
              //working with m 
             }); 
+1

Cám ơn các bạn giúp đỡ! Tôi đã thực sự tìm kiếm một cách tiếp cận bằng cách sử dụng mảng thay vì vectơ vì giáo viên của tôi đã muốn lớp sử dụng mảng thay thế. Tôi tìm thấy câu trả lời mặc dù. – user972276

+0

@ user972276: Đối với mảng, cách tiếp cận đầu tiên của bạn là những gì người ta có thể làm, nếu bạn muốn gọi hàm tạo không mặc định. Tuy nhiên, trong tương lai, nếu bạn cần mảng, * đầu tiên * xem xét sử dụng 'std :: vector'. Nó là một container tuyệt vời, với rất nhiều tính năng tuyệt vời. – Nawaz

6

Trong C++ 0x, ngữ pháp này hoạt động, có thể gọi các nhà xây dựng không phải mặc định trong biểu hiện mới:

MyClass *myVar; 
myVar = new MyClass[2]{{10, 20},{20, 30}}; 

Nhưng tôi nghi ngờ nếu nó hoạt động khi số lượng các phần tử chỉ có sẵn trong thời gian chạy.

Phương pháp tiếp cận véc tơ sẽ tốt hơn, như được thể hiện trong câu trả lời của Nawaz.

2

Một cách tôi đã thực hiện điều này trong quá khứ là sử dụng một con trỏ kép.

MyClass ** myvar; 
myvar = new Myclass*[num] 
for(int i = 0; i < 4; i++){ 
*(myvar+i) = new Myclass(i);} 

Làm việc với nhiều cấu trúc điều khiển bạn có thể tưởng tượng, trở ngại duy nhất là các đối tượng không nhất thiết phải liên tục trên heap.

0

Trên thực tế, bạn có thể sử dụng một vị trí mới để xử lý này:

MyClass * myVar; 
myVar = reinterpret_cast<MyClass *>(new char[num * sizeof(MyClass)]); 
int i = 0; 
for (i = 0; i < num; i++) { 
    new(&myVar[i]) MyClass(0,0); 
} 
+0

Bạn nên sử dụng 'std :: aligned_storage' thay vì' new char [] '. –

+0

Ngoài ra, cần lưu ý rằng để giải phóng bộ nhớ này, bạn phải lặp lại và gọi hàm hủy của mỗi đối tượng và sau đó gọi 'delete [] reinterpret_cast (myVar);'. –

0

Bạn có thể làm một cái gì đó giống như quá này:

MyClass *myVar[num]; 

for(int i = 0; i < num; i += 1) 
{ 
    myVar[i] = new MyClass(0, 0); 
} 
Các vấn đề liên quan