나는 op = 및 copy 생성자를 올바르게 수행하는 방법을 알고 있으므로, 적절하게 sort()
으로 테스트 케이스를 작성했습니다. 작동 시키면, op =가 모든 data_
을 하드 카피하고 있다는 것을 깨달았습니다.힙 할당 버퍼가있는 객체의 정렬 컨테이너 최적화 - 버퍼를 하드 복사하지 않으려면 어떻게해야합니까?
이 구조로 컨테이너를 정렬하려면 (힙 버퍼에 char 버퍼 배열이 할당되어 있음) 포인터를 교체하는 것이 더 빠를 것입니다. 그렇게 할 수있는 방법이 있습니까? 내 자신의 정렬/스왑 함수를 작성해야합니까?
#include <deque>
//#include <string>
//#include <utility>
//#include <cstdlib>
#include <cstring>
#include <iostream>
#include <fstream>
#include <algorithm> // I use sort(), so why does this still compile when commented out?
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
using namespace std;
namespace fs = boost::filesystem;
class Page
{
public:
// constructor
Page(const char* path, const char* data, int size) :
path_(fs::path(path)),
size_(size),
rawdata_(new char[size])
{
// cout << "Creating Page..." << endl;
strncpy(rawdata_, data, size);
// cout << "done creating Page..." << endl;
}
// copy constructor
Page(const Page& other) :
path_(fs::path(other.path())),
size_(other.size()),
rawdata_(new char[other.size()])
{
// cout << "Copying Page..." << endl;
strncpy(data_, other.data(), size_);
// cout << "done copying Page..." << endl;
}
// destructor
~Page() { delete[] data_; }
// accessors
const fs::path& path() const { return path_; }
const char* data() const { return rawdata_; }
int size() const { return size_; }
// operators
Page& operator = (const Page& other) {
if (this == &other)
return *this;
char* newImage = new char[other.size()];
strncpy(newImage, other.data(), other.size());
delete[] data_;
rawdata_ = newImage;
path_ = fs::path(other.path());
size_ = other.size();
return *this;
}
bool operator < (const Page& other) const { return path_ < other.path(); }
private:
fs::path path_;
int size_;
char* rawdata_;
};
class Book
{
public:
Book(const char* path) :
path_(fs::path(path))
{
cout << "Creating Book..." << endl;
cout << "pushing back #1" << endl;
// below, the RawData will be coming from methods like
// fstream.read(char* buffer, int filesize); or
// unzReadCurrentFile(unzFile zipFile, char* buffer, int size);
pages_.push_back(Page("image1.jpg", "firstImageRawData", 17));
cout << "pushing back #3" << endl;
pages_.push_back(Page("image3.jpg", "thirdImageRawData", 17));
cout << "pushing back #2" << endl;
pages_.push_back(Page("image2.jpg", "secondImageRawData", 18));
cout << "testing operator <" << endl;
cout << pages_[0].path().string() << (pages_[0] < pages_[1]? " < " : " > ") << pages_[1].path().string() << endl;
cout << pages_[1].path().string() << (pages_[1] < pages_[2]? " < " : " > ") << pages_[2].path().string() << endl;
cout << pages_[0].path().string() << (pages_[0] < pages_[2]? " < " : " > ") << pages_[2].path().string() << endl;
cout << "sorting" << endl;
BOOST_FOREACH (Page p, pages_)
cout << p.path().string() << endl;
sort(pages_.begin(), pages_.end());
cout << "done sorting\n";
BOOST_FOREACH (Page p, pages_)
cout << p.path().string() << endl;
cout << "checking datas" << endl;
BOOST_FOREACH (Page p, pages_) {
char data[p.size() + 1];
strncpy((char*)&data, p.data(), p.size());
data[p.size()] = '\0';
cout << p.path().string() << " " << data << endl;
}
cout << "done Creating Book" << endl;
}
const Page& getFirstPage() { return pages_[0]; }
private:
deque<Page> pages_;
fs::path path_;
};
int main() {
Book* book = new Book("/some/path/");
// below is an example of where the rawdata is used
// by a method that has a char* parameter
ofstream outFile("outimage.jpg");
outFile.write(book->getFirstPage().data(), book->getFirstPage().size());
}
'std :: string'을 사용하지 않는 이유가 있습니까? – GManNickG
또한, main에서'book'을 절대 삭제하지 않으므로 모든 작업이 훼손됩니다. :) – GManNickG
메인의 책은 실제로 초점이 아닙니다. 파일 스트림에 std :: string을 사용해야합니까? 읽을 수있는 문자 스트림이 아닙니다. 파일 I/O를 배웠을 때 항상 fstream을 사용하고 char 버퍼를 만들었습니다. 게다가, 나는 압축되지 않은 unrar 라이브러리에서 스트림을 얻고 있는데, 원시 char *를 요청한다. – Kache