2013-05-23 13 views
5

Khi tôi tạo ra một mảng của một lớp người dùng định nghĩa như thế này, nó sẽ mặc định-xây dựng mỗi phần tử:Làm thế nào để tôi gọi nó là hàm tạo đúng?

S s[5]; // calls default constructor five times, one for each S object 

Nhưng nếu lớp học của tôi không được mặc định-construable? Làm thế nào tôi có thể nhanh chóng và sau đó sử dụng mảng này?

Ví dụ, lớp học của tôi S có thể không mặc định-construable, nhưng nó không có một nhà xây dựng như thế này:

S(int, int); 

Làm thế nào để làm cho nó gọi constructor này thay vì một mặc định?

+2

Sử dụng một container thay vì một mảng. – chris

+0

Sử dụng một vùng chứa _and_ xây dựng từ các trình vòng lặp hoặc một vòng lặp 'emplace_back', hoặc đơn giản là xây dựng chúng một lần. –

+1

Hoặc cung cấp cho lớp một constructor mặc định, trừ khi bạn có một lý do * thực sự tốt * không làm như vậy. – cdhowie

Trả lời

6
struct S 
{ 
    const int m; 
    S(int p, int k) : m(p) {} 
}; 

S arr[4] = {S(1,1), S(1,2), S(1,3), S(1,4)}; 

Không sao chép ctor, bạn vẫn có thể sử dụng sau C++ 11 list-khởi tạo - như Andy Prowl points out ctor có thể không explicit cho việc này:

S arr[4] = {{1,1}, {1,2}, {1,3}, {1,4}}; 

Để có giải pháp có thể mở rộng hơn, bạn có thể sử dụng hoặc std::array hoặc std::vector:

std::array<S,4> make_array() 
{ 
    // create array... and return 
} 

std::array<S,4> arr = make_array(); 
+2

Xin vui lòng để lại một bình luận nếu bạn downvote. Tôi vừa kiểm tra biên dịch btw này. – dyp

+1

Thực ra, tôi đã nghĩ lại suy nghĩ của mình. OP yêu cầu làm điều này mà không có một hàm tạo mặc định, do đó không để lại nhiều tùy chọn. Đã xóa Downvote. –

+0

Cảm ơn bạn, bạn và câu trả lời của Andy đã giúp rất nhiều.:) – user2030677

4

Sử dụng số std::vector và điền vào các đối tượng bạn quyết định cách được xây dựng.

Ví dụ, trong C++ 11 bạn có thể sử dụng chức năng emplace_back() thành viên để viết một cái gì đó như thế này:

#include <vector> 

std::vector<S> v; 
v.emplace_back(42, 1729); 
v.emplace_back(0, 6); 
// ... 

Hoặc thậm chí:

std::vector<S> v = { {42, 1729}, {0, 6} }; 

Nếu constructor của S không được đánh dấu là explicit. Nếu đúng như vậy, bạn sẽ phải viết:

std::vector<S> v = { S{42, 1729}, S{0, 6} }. 

Trở lại trong C++ 03, nơi emplace_back() và khởi tạo thống nhất đã không tồn tại, bạn có thể làm:

#include <vector> 

std::vector<S> v; 
v.push_back(S(42, 1729)); 
v.push_back(S(0, 6)); 
// ... 

Nhưng lớp học của bạn nên được sao chép để có thể biên dịch.

2

trong quá khứ tôi đã làm một số:

S** s = new S*[5]; 

s[0] = new S(1, 2); 
s[1] = new S(1, 2); 

chỉ để có thể gọi các nhà thầu khác

+0

@ Joel Không, nó sẽ không sử dụng con trỏ thay vì các đối tượng thực tế. Mảng sẽ khởi tạo các con trỏ, và chúng ta gán một đối tượng được hiểu đúng cho chúng. – user2030677

+0

Um, tại sao bạn thay đổi lại? Nó vẫn sẽ là 'S ** s' ... – user2030677

+0

@ user2030677 xin lỗi, tôi đã ở xa trình biên dịch và không thể thử :) cố định – Exceptyon