简体   繁体   中英

open ofstream as class attribute

I would like to add an open ofstream as a class ( Barcode ) attribute. The goal is to implement several Barcodes in my main() that will each be able to write into a specific file. Also, I decided to stock all the barcodes in a vector, which belongs to a Barcodes class, although it is maybe not useful.

Here is my code:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <sys/stat.h>

using namespace std;

class Barcode {
    public:
        // Constructor
        Barcode(string bcName, string bcSeq, string end, string const & fileName): 
            m_bcName(bcName), m_bcSeq(bcSeq), m_end(end), m_ofStream(fileName.c_str(), ios::app) {}

        // Getters
        string getBCName() const {
            return m_bcName;
        }        
        string getBCSeq() const {
            return m_bcSeq;
        }

        //setter
        void reportRead(string toReport) {
            m_ofStream << toReport;
        }

    private:
        string m_bcName;
        string m_bcSeq;
        string m_end;
        ofstream m_ofStream;
};


class Barcodes {
    public:
        // Constructor
        Barcodes(string barcodesFile, string end): m_barcodesFile(barcodesFile), m_end(end) {
            initializeBarcodes();  
        }

        // Getters
        vector<Barcode> getBCs() {
            return m_barcodes;
        }

        // Other
        void initializeBarcodes() {
            ifstream flow(m_barcodesFile);
            if(!flow) {
                cerr << "ERROR: Could'n find the \"barcode.txt\" file." << endl;
            }

            else {
                string line, name, seq;
                // parse each line of the barcode file
                while(getline(flow, line)) {
                    //get the name and sequence of the barcodes
                    name = line.substr(0, 4);
                    seq = line.substr(5, 6);

                    //create the corresponding Barcode
                    string fileName = "Demultiplexed_Reads/" + name + "." + m_end + ".fastq";
                    Barcode bc(name, seq, m_end, fileName);
                    //add them in the corresponding vector
                    m_barcodes.push_back(bc);
                }
            }
        }

    private:
        string m_barcodesFile;
        string m_end;
        vector<Barcode> m_barcodes;
};

int main(int argc, char* argv[]) {

    //Create a new "Demultiplexed_Reads" folder
    system("rm -rf Demultiplexed_Reads");
    if(mkdir("Demultiplexed_Reads", 0755) != 0) {
        cerr << "ERROR: Couldn't create the Demultiplexed folder." << endl;
        return 1;
    }

    else {

        // Get the files to demultiplex
        string f1 = argv[1];
        string f2 = argv[2];

        // Generate the vectors of barcodes
        Barcodes bcs1("barcodes.txt", "end1");
        vector<Barcode> barcodes1(bcs1.getBCs());
        Barcodes bcs2("barcodes.txt", "end2");
        vector<Barcode> barcodes2(bcs2.getBCs());

        // Demultiplex the reads of the end1
        Demultiplexer dm1(f1, barcodes1, "end1");
        dm1.demultiplex();
        cout << "Reads of end1 demultiplexed" << endl;

        // Demultiplex the reads of the end2
        Demultiplexer dm2(f2, barcodes2, "end2");
        dm2.demultiplex();
        cout << "Reads of end2 demultiplexed" << endl;    

        return 0;
    }
}

However, I encounter errors that I don't understand about deleted methods when I am trying to compile g++ --std=c++11 myProg.cpp -o myProg :

In file included from /usr/include/x86_64-linux-gnu/c++/5/bits/c++allocator.h:33:0,
                 from /usr/include/c++/5/bits/allocator.h:46,
                 from /usr/include/c++/5/string:41,
                 from /usr/include/c++/5/bits/locale_classes.h:40,
                 from /usr/include/c++/5/bits/ios_base.h:41,
                 from /usr/include/c++/5/ios:42,
                 from /usr/include/c++/5/ostream:38,
                 from /usr/include/c++/5/iostream:39,
                 from Demultiplex.cpp:1:
/usr/include/c++/5/ext/new_allocator.h: In instantiation of ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = Barcode; _Args = {const Barcode&}; _Tp = Barcode]’:
/usr/include/c++/5/bits/alloc_traits.h:530:4:   required from ‘static void std::allocator_traits<std::allocator<_CharT> >::construct(std::allocator_traits<std::allocator<_CharT> >::allocator_type&, _Up*, _Args&& ...) [with _Up = Barcode; _Args = {const Barcode&}; _Tp = Barcode; std::allocator_traits<std::allocator<_CharT> >::allocator_type = std::allocator<Barcode>]’
/usr/include/c++/5/bits/stl_vector.h:917:30:   required from ‘void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = Barcode; _Alloc = std::allocator<Barcode>; std::vector<_Tp, _Alloc>::value_type = Barcode]’
Demultiplex.cpp:85:44:   required from here
/usr/include/c++/5/ext/new_allocator.h:120:4: error: use of deleted function ‘Barcode::Barcode(const Barcode&)’
  { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
    ^
Demultiplex.cpp:18:7: note: ‘Barcode::Barcode(const Barcode&)’ is implicitly deleted because the default definition would be ill-formed:
 class Barcode {
       ^
Demultiplex.cpp:18:7: error: use of deleted function ‘std::basic_ofstream<_CharT, _Traits>::basic_ofstream(const std::basic_ofstream<_CharT, _Traits>&) [with _CharT = char; _Traits = std::char_traits<char>]’
In file included from Demultiplex.cpp:2:0:
/usr/include/c++/5/fstream:723:7: note: declared here
       basic_ofstream(const basic_ofstream&) = delete;
       ^
In file included from /usr/include/c++/5/vector:62:0,
                 from Demultiplex.cpp:4:
/usr/include/c++/5/bits/stl_construct.h: In instantiation of ‘void std::_Construct(_T1*, _Args&& ...) [with _T1 = Barcode; _Args = {const Barcode&}]’:
/usr/include/c++/5/bits/stl_uninitialized.h:75:18:   required from ‘static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<const Barcode*, std::vector<Barcode> >; _ForwardIterator = Barcode*; bool _TrivialValueTypes = false]’
/usr/include/c++/5/bits/stl_uninitialized.h:126:15:   required from ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<const Barcode*, std::vector<Barcode> >; _ForwardIterator = Barcode*]’
/usr/include/c++/5/bits/stl_uninitialized.h:281:37:   required from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = __gnu_cxx::__normal_iterator<const Barcode*, std::vector<Barcode> >; _ForwardIterator = Barcode*; _Tp = Barcode]’
/usr/include/c++/5/bits/stl_vector.h:322:31:   required from ‘std::vector<_Tp, _Alloc>::vector(const std::vector<_Tp, _Alloc>&) [with _Tp = Barcode; _Alloc = std::allocator<Barcode>]’
Demultiplex.cpp:63:20:   required from here
/usr/include/c++/5/bits/stl_construct.h:75:7: error: use of deleted function ‘Barcode::Barcode(const Barcode&)’
     { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }

Does anybody know what the problem is ?

Thank you so much !

So I found a way to overcome my problem so I just write the solution I used here in case it would be useful for somebody.

Finally, I created a vector of ofstreams in the method that write into output files instead of putting the streams in the objects. I did it just before the loop that reads ans sorts lines from the input file.

As you said, the trick is no to try to copy the stream since it is not possible. But their reference can be moved into the vector. So I used the move function, which is in the standard since C++11:

ofstream ofs(fileName);
ofStreams.push_back(move(ofs));

I worked for me and allowed my program to be way faster than opening a stream and closing it for every line that I need to sort.

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