2010-01-20 22 views
6

Hãy cân nhắc những điều sau đây:C chứa ++ STL và xây dựng tại chỗ

class CMyClass 
{ 
public: 
    CMyClass() 
    { 
    printf("Constructor\n"); 
    } 
    CMyClass(const CMyClass&) 
    { 
    printf("Copy constructor\n"); 
    } 
}; 

int main() 
{ 
    std::list<CMyClass> listMyClass; 

    listMyClass.resize(1); 

    return 0; 
} 

Nó tạo ra kết quả như sau:

Constructor

Sao chép constructor

Bây giờ tôi câu hỏi là: Làm cách nào để tránh trình tạo bản sao? Hoặc để đặt nó theo một cách khác: Làm thế nào tôi có thể tạo các đối tượng bên trong một container STL mà không cần thao tác sao chép không cần thiết. Có cách nào để làm một "tại chỗ" xây dựng bằng cách sử dụng constructor mặc định?


Update - câu trả lời cho đến nay:

  1. Nó không thể được thực hiện
  2. Sử dụng con trỏ hoặc gợi ý thông minh để thay thế.

Con trỏ thông minh là quá mức cần thiết cho ứng dụng của tôi. Nhưng tôi thực sự tự hỏi tại sao điều này không thể được thực hiện. Nó có vẻ như một điều rõ ràng như vậy muốn làm. Bất kỳ ý tưởng nào khác? Tôi thậm chí sẽ chấp nhận một hack khó chịu nếu nó hoạt động ...


Giải pháp

Tôi nghĩ rằng tôi chỉ tìm thấy một giải pháp cho vấn đề của tôi từ tất cả các ý kiến ​​và câu trả lời được đặt ra ở đây. Giải pháp là xây dựng một đối tượng trống và giữ nó xung quanh với mục đích duy nhất là sử dụng nó sau này để tạo các bản sao sạch. Sau đó, bạn có thể sử dụng một trong các phương thức lấy tham chiếu (như push_back hoặc chèn). Đây vẫn gọi các nhà xây dựng bản sao cho mỗi đối tượng mới chèn, nhưng ít nhất nó không phải là tất cả các nhà xây dựng mặc định AND copy constructor:

int main() 
{ 
    CMyClass Empty; 

    std::list<CMyClass> listMyClass; 

    for (int c=0; c<10; ++c) 
    { 
    listMyClass.push_back(Empty); 
    } 

    return 0; 
} 
+0

Nó có thể có vẻ một điều hiển nhiên, nhưng từ quan điểm chức năng, không quan trọng và một số thuật toán (sắp xếp, xóa, ...) cũng sử dụng sao chép, vì vậy hãy chuẩn bị để sao chép;) (Xem thêm http: //www.devx .com/tips/Tip/13606) – stefaanv

+0

Một điều hiển nhiên phải làm? Tại sao vậy? Tại sao sao chép một vấn đề? – jalf

+0

Rõ ràng? Nếu bạn gọi là 'mylist.resize (10)', làm thế nào bạn mong đợi để kết thúc với mười đối tượng riêng biệt nếu chúng không phải là bản sao? – visitor

Trả lời

8

Theo thiết kế, tất cả các thư viện C++ Standard Library đều lưu trữ bản sao. Do đó, không thể tránh được lời gọi đến hàm tạo bản sao nếu bạn muốn lưu trữ các giá trị trong vùng chứa - cách duy nhất để lưu trữ con trỏ thay thế. Nếu bạn muốn giảm thiểu chi phí sao chép, hãy điều tra việc sử dụng tính tham chiếu.

1

sử dụng con trỏ

std::list<CMyClass*> listMyClass; 
+2

thậm chí tốt hơn: sử dụng con trỏ thông minh, tự động tạo/hủy đối tượng được đề cập – user231967

+2

Chỉ cần không phải là auto_ptr. Điều đó sẽ gây ra những điều xấu xảy ra. –

1

Xin lỗi, hiện không có std :: danh sách và các vùng chứa tương tự. (Tuy nhiên, bạn có thể viết chứa riêng hơi khác nhau của bạn nếu bạn thực sự cần điều này, và vẫn theo phần còn lại của giao diện STL.)

Bạn không cần phải sử dụng ctor mặc định, tuy nhiên:

std::list<CMyClass> listMyClass; 
listMyClass.resize(1, obj_to_copy_from); 

Chẳng hạn như:

std::list<CMyClass> listMyClass; 
listMyClass.resize(1, CMyClass(use, specific, ctor)); 

Resize trông giống như:

void list<T>::resize(size_type new_size, T copy_from = T()); 

nào tạo ra một đối tượng mới (u hát ctor mặc định) theo mặc định.

0

sử dụng một con trỏ hoặc con trỏ thông minh (tăng :: shared_ptr và không auto_ptr)

1

Nó sẽ là hữu ích nếu vector cho phép khởi tạo các yếu tố mới với constructor mặc định đã đổi kích thước vì hiệu suất, nhưng điều này không được hỗ trợ. Nếu bạn thực sự cần điều này, hãy triển khai vùng chứa tùy chỉnh - không có cách nào khác.

0

bạn có thể làm trong C11, cho các phiên bản cũ, vesry đơn giản có thể được cải thiện

vector

myclas: public vector<A> 
{ 
    push_back(Aconstructor_parameters) 
    { 
     new(_Mylast++) A(Aconstructor_parameters); 
    } 
}; 

khi sử dụng đảm bảo rằng bạn đã sử dụng reserve() để cấp phát bộ nhớ

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