2009-03-17 25 views
5

Tôi có một lớp tạo một đối tượng bên trong một phương thức công khai. Đối tượng là riêng tư và không hiển thị cho người dùng của lớp. Phương pháp này sau đó gọi khác tin phương pháp bên trong cùng lớp và vượt qua các đối tượng được tạo ra như một tham số:Truyền con trỏ thông minh làm đối số bên trong một lớp: scoped_ptr hoặc shared_ptr?

class Foo { 
    ... 
}; 

class A { 
    private: 
     typedef scoped_ptr<Foo> FooPtr; 

     void privateMethod1(FooPtr fooObj); 

    public: 
     void showSomethingOnTheScreen() { 
      FooPtr fooObj(new Foo); 
      privateMethod1(fooObj); 
     }; 
}; 

Tôi tin rằng con trỏ thông minh đúng trong trường hợp này sẽ là một scoped_ptr, tuy nhiên, tôi không thể làm được vì scoped_ptr điều này làm cho lớp không copyable nếu được sử dụng theo cách đó, vì vậy tôi nên làm cho các phương pháp như thế này:

void privateMethod1(FooPtr& fooObj); 

privateMethod1 không lưu trữ các đối tượng, không phải giữ tài liệu tham khảo của nó. Chỉ truy xuất dữ liệu từ lớp Foo.

Cách chính xác có thể không sử dụng con trỏ thông minh và phân bổ đối tượng trong ngăn xếp, nhưng điều đó là không thể vì nó sử dụng thư viện không cho phép đối tượng trên ngăn xếp, chúng phải nằm trên Heap .

Sau khi tất cả, tôi vẫn còn bối rối về việc sử dụng thực tế của scoped_ptr.

+1

Tôi tò mò về thư viện 'không cho phép các đối tượng trên ngăn xếp'. Các đối tượng được phân bổ bên trong thư viện trên heap với một nhà máy? Thư viện có sở hữu con trỏ và xóa nó không?Lý do tại sao bạn không thể sử dụng các đối tượng được cấp phát stack là gì? –

Trả lời

1

Sử dụng tại đây std đơn giản :: auto_ptr vì bạn không thể tạo đối tượng trên ngăn xếp. Và nó là tốt hơn để chức năng riêng của bạn chỉ đơn giản là chấp nhận con trỏ nguyên.

Sử dụng thực tế là bạn không phải bắt tất cả các ngoại lệ có thể xảy ra và thực hiện xóa thủ công.

Trong thực tế nếu đối tượng của bạn là không thay đổi đối tượng và đối tượng trở lại API của bạn chắc chắn bạn muốn tốt hơn để sử dụng

void privateMethod1(const Foo& fooObj); 

và vượt qua các đối tượng đó như

privateMethod1(*fooObj.get()); 
+0

Kết thúc chính xác giống như với scoped_ptr, chỉ cần nó không buộc bạn khai báo các tham số phương thức của bạn làm tham chiếu. Nhưng nếu bạn không, nó sẽ phá vỡ theo những cách đáng ngạc nhiên (fooObj sẽ là một con trỏ Null khi privateMethod1 trả về, ngay cả khi có nhiều thứ bạn muốn làm với nó). – sth

+0

đồng ý với sth nếu khóa học. tại sao sử dụng auto_ptr nếu scoped_ptr rõ ràng là lựa chọn tốt hơn? chuyển quyền sở hữu không được dự định. –

+0

Các bạn, tôi không tăng cường dự án của mình. Vì vậy, đó là lý do tại sao tôi đề xuất giải pháp stl như vậy. Bạn thấy 'chuyển quyền sở hữu' ở đâu? –

1

tôi m nghi ngờ về bình luận "nó sử dụng một thư viện mà không cho phép các đối tượng trên ngăn xếp, họ phải được trên Heap."

Tại sao? Điều đó thường có nghĩa là chúng phải được deallocated theo một cách đặc biệt - vì vậy có lẽ không có giải pháp nào trong số này sẽ hoạt động.

+0

@Earwicker trình biên dịch chúng tôi đang sử dụng là Borland C++ và thư viện mà chúng tôi đang sử dụng là thư viện GUI VCL đi kèm với C++. Điều đó sẽ sớm thay đổi, nhưng tôi phải gắn bó với điều này ngay bây giờ. Vì lý do nào đó, VCL phải được phân bổ trên Heap, tôi không có ý tưởng thực sự tại sao. –

+0

Có thể điều đó có nghĩa là thư viện có các phương thức nhà máy trả về các con trỏ tới các đối tượng đã tạo và chuyển quyền sở hữu cho người dùng. –

+0

Bạn có chắc chắn cần xóa các đối tượng không? Tôi đã không bao giờ được sử dụng VCL nhưng tôi đã có một khái niệm mơ hồ rằng nó sẽ xóa các thành phần tự động khi cha mẹ của họ bị xóa. –

3

Một khả năng nữa là để tạo ra các đối tượng như một static_ptr để dễ quản lý bộ nhớ, nhưng chỉ cần vượt qua con trỏ thô đến những phương pháp riêng khác:

void privateMethod1(Foo *fooObj); 

void showSomethingOnTheScreen() { 
    scoped_ptr<Foo> fooObj(new Foo); 
    privateMethod1(fooObj.get()); 
}; 
3

Tôi sẽ sử dụng scoped_ptr bên showSomethingOnTheScreen, nhưng vượt qua một con trỏ thô (hoặc tham chiếu) tới privateMethod1, ví dụ

scoped_ptr <Foo> fooObj (new Foo);
riêngMethod1 (fooObj.get());

+0

Đó là dự đoán thực sự của tôi, nhưng thực hành này có được khuyến cáo không? Nếu đó là những gì tôi sẽ làm –

0

Trong trường hợp đó, bạn chỉ phải thay thế cơ chế phân bổ.
Tạo đối tượng trên heap, nhưng chuyển đối tượng đó làm tham chiếu đến phương thức riêng tư.

class A { 
    private: 
     void privateMethod1(Foo& fooObj); 

    public: 
     void showSomethingOnTheScreen() { 
      scoped_ptr<Foo> fooObj(new Foo); 
      privateMethod1(*(fooObj.get())); 
     }; 
}; 
Các vấn đề liên quan