2012-02-25 26 views
6

Tôi mới dùng C++, và tiếc là tôi không thể ngừng suy nghĩ trong C# (ngôn ngữ cũ của tôi). Tôi đọc một số sách, diễn đàn và trang web tham khảo C++, nhưng tôi không thể tìm thấy câu trả lời cho câu hỏi của mình, vì vậy tôi nghĩ tôi cũng có thể thử ở đây trước khi từ bỏ và viết gì đó xấu xí.C++ đúng cách để trả lại bộ sưu tập chung loại

Ok, chúng ta có thể bắt đầu. Tôi có một lớp học với phương pháp trừu tượng succesorsFunction và tôi muốn nó trả về bộ sưu tập các con trỏ đến Tiểu bang. Tôi không muốn ép buộc những người triển khai vào một container cụ thể; Tôi thà để họ chọn (vectơ, danh sách, vv).

Vì vậy, nó trông như thế này:

class Problem 
{ 
public: 
    virtual list<const State*>::iterator succesorsFunction(const State &state, list<const State*>::iterator result) const = 0; 
}; 

các vấn đề ở đây là việc sử dụng rõ ràng của danh sách. Làm thế nào để bạn làm điều đó trong C + +?

Tôi đã nghĩ đến việc sử dụng mẫu, nhưng sau đó tôi gặp phải hai vấn đề: 1) Có vẻ như bạn không thể làm điều đó bằng phương pháp trừu tượng (hoặc tôi sai?) 2) Làm cách nào để nói mẫu cho tiểu bang?

+2

kiểu xóa dãy Boost.Range của thể giúp đây. – Xeo

+0

Bạn có thể mở rộng về chức năng này và chức năng ảo được cho là đạt được không? Có thể có các cách tiếp cận khác. –

+2

Vì vậy, bạn muốn trả lại một cái gì đó tương tự như 'IEnumerable '? – svick

Trả lời

2

Bạn không thể quá tải phương thức dựa trên kiểu trả về trong C++.

Ngoài ra, "vùng chứa" trong C++ không có cùng cơ sở (như Collection trong Java), do đó bạn không thể trả lại vùng chứa chung.

Tôi e rằng không có cách nào để làm điều này một cách rõ ràng.

Tôi sẽ chỉ viết quá tải (theo tham số) hoặc tên hàm khác.

Đối với câu hỏi của bạn:

1) Bạn có thể. Điều gì khiến bạn nghĩ rằng bạn không thể?

2) Tương tự như cách bạn khai báo list: list<const State*> - const là tùy chọn.

+4

Tôi không nghĩ anh ta nói gì về việc quá tải bởi giá trị trả về; có nhiều triển khai có cùng kiểu trả về. Anh ta chỉ muốn kiểu trả về đủ chung để không hạn chế việc thực thi. –

+0

@ ErnestFriedman-Hill câu hỏi của ông nói rằng ông muốn trả lại một bộ sưu tập và ông không muốn hạn chế bộ sưu tập (mặc dù mã trả về một trình lặp). –

+0

... không nói gì về quá tải theo kiểu trả về. –

0

Bạn không thể có một hàm thành viên mẫu đó là ảo, nhưng bạn có thể thử thực hiện bạn chức năng chung chung như thế này:

template <typename yourType> 
yourType& succesorsFunction(const State &a, yourType &result){//Your return type can be without reference 
    //Your body 
    return result; 
} 

Nếu bạn gọi chức năng của bạn ví dụ với vector<State> a lập luận như thế này:

sucessorsFunction(b,a);// b is your State object 

quá trình khấu trừ sẽ tự động kết luận rằng yourType thực ra là vector<State> loại, mà tôi nghĩ là giải quyết được sự cố của bạn. Ngoài ra, arhitecture này giúp bạn tạo ra ví dụ như lớp mới MyVector (giữ các mảng States) và vượt qua đối tượng MyVector đối tượng succesorsFunction.

+0

Tôi đã cố gắng làm điều đó nhưng nó không hoạt động với phương pháp trừu tượng. Tôi cũng có thể loại bỏ các = 0 ở cuối và làm cho nó hơn với. Cảm ơn bạn đã trả lời – wolfovercats

+0

@wolfovercats bạn sẽ cư trú như thế nào nếu bạn không biết loại? –

+0

@LuchianGrigore Tôi biết loại; đó là Tiểu bang *. – wolfovercats

0

Nếu bạn thực sự muốn thực thi việc sử dụng STL container, hãy thử như sau:

template <template <typename, 
        typename = std::allocator<const State *> > class Container> 
Container<const State*> successorsFunction(const State &state, const Container<const State*> &c) const 
{ 
    // return something useful. 
} 

Nếu bạn nhấn mạnh vào việc có chức năng này là ảo, sau đó nó không thể là một hàm thành viên mẫu, chỉ quá tải nó với các loại bạn có ý định hỗ trợ, sau đó bạn có thể làm cho chúng ảo.

0

Đây chỉ là công thức cho câu trả lời C.T's. Hãy nhớ rằng nếu bạn trả lại một container con trỏ thì bạn sẽ phải giải phóng chúng một cách rõ ràng hoặc sử dụng std::unique_ptr.
Chỉ cần một FYI .. khi bạn đến từ nền C#.

Bạn cũng có thể sử dụng trạng thái hoặc templatize nó.

template<typename Type, 
     template< typename, typename = std::allocator<Type*> > class Container 
     > 
Container<Type*> Successor(const Type& x) 
{ 
    Container<Type*> cont; 
    // something. 
    cont.push_back(new Type(x)); 
    return cont; 
} 

và gọi nó là

vector<State*> states = Successor<State, vector>(State(10)); 
Các vấn đề liên quan