2009-06-22 25 views
5

Tôi muốn trả về hai giá trị, một trong số đó là một đối tượng mới. Tôi có thể làm điều này bằng std::pair:Trả lại một đối tượng mới cùng với một giá trị khác

class A { 
//... 
}; 

std::pair<A*, int> getA() 
{ 
    A* a = new A; 
    //... 
} 

Để làm cho đoạn code ngoại lệ an toàn, tôi muốn làm:

std::pair<std::auto_ptr<A>, int> getA() 
{ 
    std::auto_ptr<A> a(new A); 
    //... 
} 

Nhưng điều này sẽ không biên dịch như auto_ptr không thể sao chép mà không sửa đổi auto_ptr đang được sao chép. Ok, điều này có nghĩa là auto_ptr không sáng tác tốt như các loại khác (theo một cách khác). Một cách tốt để trả về một đối tượng mới trong trường hợp này là gì?

Một giải pháp thay thế là trả lại shared_ptr và một cách khác là tham chiếu inout. Nhưng tôi đang tìm kiếm một số thay thế khác. Tôi có thể làm điều gì đó như:

class AGetter 
{ 
    void getAExecute() 
    { 
     //... 
     // set a_ and i_ 
    } 
    std::auto_ptr<A> getA() const 
    { 
     return a_.release(); 
    } 
    int getInt() const 
    { 
     return i_; 
    } 
    private: 
    std::auto_ptr<A> a_; 
    int i_; 
}; 

Có cách nào tốt hơn không?

Trả lời

2

Chỉ cần tạo một lớp mới và trở về lớp mà

class Result 
{ 
    A* a; 
    int i; 
public: 
    Result(A*a, int i) : a(a), i(i) { 
    } 
    ~Result() { 
     delete a; 
    } 
    // access functions, copy constructor, ... 
}; 

Result getA() { 
    //...  
    return Result(new A, intValue); 
} 
1

Nó không đẹp, nhưng bạn có thể trả về giá trị khác thông qua một con trỏ hoặc tham chiếu đối số:

int i; 
std::auto_ptr<A> a = getA(&i); 
5

Có hai cách chính để xử lý vấn đề này:

  1. Làm sạch chính mình, thông qua try/catch.
  2. Sử dụng một số loại quản lý bộ nhớ tự động, như shared_ptr.

auto_ptr không thực sự hoạt động trong những trường hợp này, nhưng tiêu chuẩn mới và Boost đều chứa con trỏ được tham chiếu làm những gì bạn muốn. Hãy cho chúng tôi biết những gì bạn không thích về shared_ptr và có thể chúng tôi đề xuất một giải pháp thay thế.

+0

shared_ptr là hơi/trivially kém hiệu quả và virus. Không phải là những lập luận rất mạnh mẽ đối với shared_ptr, nhưng vẫn tạo ra một yếu tố chống lại chúng (trong 10% các trường hợp). –

+1

may mắn thay, tiêu chuẩn tiếp theo chứa unique_ptr, có thể được di chuyển cùng với cặp chứa nó. –

1

Tại sao không thông qua hai tham số tham chiếu?

class AGetter 
{ 
    // .. 
    void get(std::auto_ptr<A>& a, int& i) 
    { 
     a = a_.release(); 
     i = i_; 
    } 
    // .. 
}; 
+0

Đó là những gì tôi có nghĩa là bằng cách tham khảo inout. Tham chiếu inout là ok, nhưng bạn sẽ đồng ý vẫn là một thỏa hiệp (chữ ký chức năng không làm rõ tác dụng của việc gọi hàm). –

3

Một shared_ptr sẽ là lý tưởng trong tình huống đó, nhưng nếu bạn thực sự không muốn sử dụng những người bạn có thể trở lại một auto_ptr để một cặp có chứa các đối tượng và các int để thay thế.

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