2011-10-31 34 views
24

Tôi có một vectơ (thứ tự quan trọng) của các đối tượng (cho phép gọi chúng là lớp myobj), nơi tôi đang cố xóa nhiều đối tượng cùng một lúc.C++ remove_if trên vectơ của các đối tượng

class vectorList 
{ 

    vector<*myobj> myList; 
}; 

class myobj 
{ 

    char* myName; 
    int index; 
    bool m_bMarkedDelete; 
} 

Tôi đã nghĩ rằng cách tốt nhất để làm điều này là đánh dấu các đối tượng myobj cụ thể để xóa và sau đó gọi myList.remove_if() trên vectơ. Tuy nhiên, tôi không chắc chắn chính xác làm thế nào để sử dụng các vị từ và như vậy cho việc này. Tôi có nên tạo biến thành viên trong đối tượng cho phép tôi nói rằng tôi muốn xóa myobj và sau đó tạo một biến vị ngữ để kiểm tra xem biến thành viên đã được đặt chưa?

Làm cách nào để triển khai biến vị ngữ như một phần của lớp vectorList?

+1

Nó có thể không có liên quan nhưng một std :: danh sách giữ lại trật tự và có chức năng remove_if riêng của nó nhanh hơn nhiều và không cần xóa riêng biệt. – Ant

+0

@Ant: 'danh sách :: remove_if' nhanh hơn xóa và xóa trên vectơ? Trong bất kì trường hợp nào? Đó chắc chắn không phải là trường hợp trên nhiều bài kiểm tra hợp lý mà tôi từng làm. Đừng cho rằng chỉ vì xóa là một hoạt động liên tục trong thời gian cho danh sách, nó sẽ nhanh hơn. Bảo đảm tiếp cận và truy cập ngẫu nhiên của 'std :: vector' mua nó rất nhiều hiệu suất. –

Trả lời

34

Tôi có nên tạo một biến thành viên trong đối tượng cho phép tôi nói mà tôi muốn xóa myObj và sau đó tạo ra một vị mà kiểm tra xem nếu biến thành viên được thành lập?

Bạn chưa làm điều đó chưa? Đó không phải là những gì m_bMarkedDelete là dành cho? Bạn sẽ viết vị như thế này:

bool IsMarkedToDelete(const myobj & o) 
{ 
    return o.m_bMarkedDelete; 
} 

Sau đó:

myList.erase(
    std::remove_if(myList.begin(), myList.end(), IsMarkedToDelete), 
    myList.end()); 

Hoặc, sử dụng lambdas:

myList.erase(
    std::remove_if(myList.begin(), myList.end(), 
     [](const myobj & o) { return o.m_bMarkedDelete; }), 
    myList.end()); 

Nếu lớp học của bạn không thực sự có thành viên đó, và bạn' lại hỏi chúng tôi có nên không, sau đó tôi sẽ nói không. Bạn đã sử dụng tiêu chí nào để quyết định đánh dấu nó để xóa? Sử dụng tiêu chuẩn như nhau trong ngữ của bạn, ví dụ:

bool IndexGreaterThanTen(const myobj & o) 
{ 
    return o.index > 10; 
} 

lưu ý - Các chức năng tôi đã viết tất nhiên là không hợp lệ vì tất cả các thành viên của bạn là tư nhân. Vì vậy, bạn sẽ cần một số cách để truy cập chúng.

+0

Tôi nhận được lỗi sau bởi vì đó là một con trỏ: lỗi C2662: 'myobj :: IsMarkedToDelete': không thể chuyển đổi 'this' pointer from 'const myobj' thành 'myobj &. Tôi đánh dấu nó để xóa kể từ khi tôi đang làm nó từ một lớp học có một lưới điện được đồng bộ hóa với vector của tôi. Tôi phải loại bỏ các hàng trong lưới và sau đó loại bỏ các hàng được chọn tương ứng trong vectơ. – Jordan

+0

@Jordan: Nó không phải là một thành viên, nó phải là một chức năng miễn phí. –

+0

IsMarkedToDelete phải là một chức năng miễn phí? Có vẻ như vấn đề là với "const-ness" của đối tượng mặc dù ... – Jordan

8

Một vị từ về cơ bản là so sánh có điều kiện. Nó có thể là một hàm hoặc đối tượng. Dưới đây là một ví dụ bằng cách sử dụng lambda mới C++. Mã này sẽ đi qua các vector và loại bỏ các giá trị tương đương 3.

int arg[6] = {1, 2, 3, 3, 3, 5}; 
std::vector<int> vec(arg, arg+6); 
vec.erase(
    std::remove_if(
     vec.begin(), vec.end(), 
     [](int i){ return i == 3;}), 
    vec.end()); 

Edit: Đối với con trỏ giả sử bạn đã có một vector hoặc giao diện bạn có thể đặt chúng vào nullptr sau đó loại bỏ chúng trong một lô với khá nhiều mã giống nhau. Trong VS2008 bạn sẽ không có lambdas do đó, hãy tạo một hàm biến vị ngữ so sánh hoặc struct.

bool ShouldDelete(IAbstractBase* i) 
{ 
    return i == nullptr; 
    // you can put whatever you want here like: 
    // return i->m_bMarkedDelete; 
} 

std::vector<IAbstractBase*> vec; 
vec.erase(
    std::remove_if(
     vec.begin(), vec.end(), 
     ShouldDelete), 
    vec.end()); 
+0

Làm cách nào để làm điều đó nếu vectơ là danh sách các con trỏ myobj *? Đó là một trong những điều mà tôi đang bối rối. Và điều này có hiệu quả trong VS 2008 không? Cảm ơn! – Jordan

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