简体   繁体   中英

Using vectors with classes that contain non-copyable data types

My issue is that I have a class which contains a std::ifstream, std::ofstream, and std::mutex. None of these objects can be directly copied as shown in the example below.

std::ifstream stream1;
std::ifstream stream2;
stream1 = stream2; //<-Compiler Error!

My problem is not that I want to copy any instances of my class, but that the push_back() function in vectors is trying to call the copy constructor for my class. I have designed an example that replicates my issue and pasted it below.

#include <fstream> //for std::ifstream // std::ofstream
#include <vector> //for std::vector
#include <mutex> //for std::mutex

class MyClass
{
public:
    MyClass(int ID) : ID(ID) { }
    std::ofstream outputstream;
    std::ifstream inputstream;
    std::mutex mymutex;
private:
    int ID;
};

int main()
{
    std::vector<MyClass> MyVector;
    MyVector.push_back(MyClass(1)); //<-- Error C2280 'MyClass::MyClass(const MyClass &)': attempting to reference a deleted function

    return 0;
}

I am having issues trying to figure out how to get around this error. Any help would be greatly appreciated. Keep in mind, I will never be directly calling the copy constructor as I have no need in my actual scenario to ever copy an instance of this class, but it seems that push_back is calling it and I have been unsuccessful in my attempts to override it.

Edit: I think one way to fix it would be to use pointers instead of ifstream,ofstream, and mutex objects but I would prefer to avoid this at all costs.

Since you have access to C++11 features, you could use emplace_back to construct the element in place.

MyVector.emplace_back(1);

However, there is some problem with std::mutex . This member has to be a pointer in order for the above to work. Otherwise, you could change all the elements of the class to be types that are copyable (eg, pointers).

The real problem here is that this class contains a std::mutex member. Which cannot be copied/moved. This means that classes that have mutex members don't like to live inside vectors.

You need a custom copy and/or move constructors, for your class, and implement the appropriate semantics to copy the streams, and figure out what you want to do with the mutex.

You might try using a vector of pointers to your objects. It is better to use some kind of smart pointer, rather than a vector of raw pointers.

ie std::vector< std::shared_ptr< MyClass >> MyVector;

now you have a container of pointers to MyClass objects.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM