Копирование elision - это метод оптимизации компилятора, который устраняет ненужное копирование / перемещение объектов.
В следующих случаях компилятору разрешено пропускать операции копирования / перемещения и, следовательно, не вызывать связанный конструктор:
#include <iostream>
using namespace std;
class ABC
{
public:
const char *a;
ABC()
{ cout<<"Constructor"<<endl; }
ABC(const char *ptr)
{ cout<<"Constructor"<<endl; }
ABC(ABC &obj)
{ cout<<"copy constructor"<<endl;}
ABC(ABC&& obj)
{ cout<<"Move constructor"<<endl; }
~ABC()
{ cout<<"Destructor"<<endl; }
};
ABC fun123()
{ ABC obj; return obj; }
ABC xyz123()
{ return ABC(); }
int main()
{
ABC abc;
ABC obj1(fun123());//NRVO
ABC obj2(xyz123());//NRVO
ABC xyz = "Stack Overflow";//RVO
return 0;
}
**Output without -fno-elide-constructors**
root@ajay-PC:/home/ajay/c++# ./a.out
Constructor
Constructor
Constructor
Constructor
Destructor
Destructor
Destructor
Destructor
**Output with -fno-elide-constructors**
root@ajay-PC:/home/ajay/c++# g++ -std=c++11 copy_elision.cpp -fno-elide-constructors
root@ajay-PC:/home/ajay/c++# ./a.out
Constructor
Constructor
Move constructor
Destructor
Move constructor
Destructor
Constructor
Move constructor
Destructor
Move constructor
Destructor
Constructor
Move constructor
Destructor
Destructor
Destructor
Destructor
Destructor
Даже когда происходит копирование и конструктор copy / move (как будто никакой оптимизации вообще не было), в противном случае программа плохо сформирована.
Вы должны разрешить такое копирование только в тех местах, где это не повлияет наблюдаемое поведение вашего программного обеспечения. Копирование elision - единственная форма оптимизации, которая позволяет иметь (то есть elide) наблюдаемые побочные эффекты. Пример:
#include <iostream>
int n = 0;
class ABC
{ public:
ABC(int) {}
ABC(const ABC& a) { ++n; } // the copy constructor has a visible side effect
}; // it modifies an object with static storage duration
int main()
{
ABC c1(21); // direct-initialization, calls C::C(42)
ABC c2 = ABC(21); // copy-initialization, calls C::C( C(42) )
std::cout << n << std::endl; // prints 0 if the copy was elided, 1 otherwise
return 0;
}
Output without -fno-elide-constructors
root@ajay-PC:/home/ayadav# g++ -std=c++11 copy_elision.cpp
root@ajay-PC:/home/ayadav# ./a.out
0
Output with -fno-elide-constructors
root@ajay-PC:/home/ayadav# g++ -std=c++11 copy_elision.cpp -fno-elide-constructors
root@ajay-PC:/home/ayadav# ./a.out
1
GCC предоставляет возможность -fno-elide-constructors
отключить копирование. Если вы хотите избежать возможного копирования, используйте -fno-elide-constructors
.
Теперь почти все компиляторы обеспечивают копирование при разрешении оптимизации (и если для его отключения не установлен другой параметр).
С каждым экземпляром копии исключается одна конструкция и одно совпадение с уничтожением копии, что позволяет сэкономить время процессора, а один объект не создан, что позволяет сэкономить место в стеке кадр.
"sample.zip" был действительно создан с gZip? .zip расширение обычно используется для архивов, созданных WinZip. Те могут также быть распакованы с помощью zLib, но необходимо было бы проанализировать заголовок и использовать другие стандартные программы.
Для проверки взгляните на первые два байта файла. Если это - 'PK', это - WinZip, если это - 0x1F8B, это - gZip.
, поскольку это - конкретный iPhone, взгляните на этот обсуждение форума iPhone SDK , где мини-zip упоминается. Кажется, что это может обработать файлы WinZip.
, Но если это - действительно файл WinZip, необходимо взглянуть на спецификация WinZip и попытка проанализировать файл сами. Это в основном должно анализировать некоторые значения заголовка, ища сжатое потоковое положение и с помощью zLib стандартные программы для распаковки его.
Действительно трудно разархивировать любой произвольный zip-файл. Это - сложный формат файла, и существует потенциально много различных стандартных программ сжатия, которые, возможно, привыкли внутренне к файлу. Информационный ZIP имеет некоторый свободно licencable код, чтобы сделать это ( http://www.info-zip.org/UnZip.html ), который может быть сделан работать над iPhone с некоторым взламыванием, но API откровенно ужасен - это включает передающие параметры командной строки к фальшивке, 'основной', который моделирует выполнение UnZIP (чтобы быть справедливым поэтому, что их код никогда не разрабатывался, чтобы использоваться как это во-первых, функциональность библиотеки была соединена болтом на впоследствии).
, Если Вы имеете какой-либо контроль над тем, где файлы Вы пытаетесь разархивировать, прибывают из, я высоко рекомендую использовать другую систему сжатия вместо ZIP. Это - гибкость, и повсеместность делают его большим для того, чтобы раздать архивы файлов в от человека к человеку, но это очень неудобно автоматизировать.
zlib не предназначен для открытия .zip файлов, но Вы находитесь в удаче: contrib каталог zlib включает мини-zip, которая в состоянии использовать zlib для открытия .zip файлов.
Это не может быть связано в SDK, но можно, вероятно, использовать комплектную версию zlib, используют его. Захватите копию zlib источника и взгляда в contrib/minizip.
Я не использовал iPhone, но можно хотеть посмотреть GZIP, который является очень портативной библиотекой zip с открытым исходным кодом, доступной для многих платформ.
Этот код хорошо работал у меня для gzip:
база данных была подготовлена следующим образом: gzip foo.db
ключ перебирал gzread (). В приведенном выше примере считываются только первые байты CHUNK.
#import <zlib.h>
#define CHUNK 16384
NSLog(@"testing unzip of database");
start = [NSDate date];
NSString *zippedDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"foo.db.gz"];
NSString *unzippedDBPath = [documentsDirectory stringByAppendingPathComponent:@"foo2.db"];
gzFile file = gzopen([zippedDBPath UTF8String], "rb");
FILE *dest = fopen([unzippedDBPath UTF8String], "w");
unsigned char buffer[CHUNK];
int uncompressedLength;
while (uncompressedLength = gzread(file, buffer, CHUNK) ) {
// got data out of our file
if(fwrite(buffer, 1, uncompressedLength, dest) != uncompressedLength || ferror(dest)) {
NSLog(@"error writing data");
}
}
fclose(dest);
gzclose(file);
NSLog(@"Finished unzipping database");
Между прочим, я могу распаковать 33 МБ в 130 МБ за 77 секунд или около 1,7 МБ без сжатия в секунду.
Мне повезло, тестируя это на симуляторе iPhone:
NSArray *paths =
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *saveLocation =
[documentsDirectory stringByAppendingString:@"myfile.zip"];
NSFileManager* fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:saveLocation]) {
[fileManager removeItemAtPath:saveLocation error:nil];
}
NSURLRequest *theRequest =
[NSURLRequest requestWithURL:
[NSURL URLWithString:@"http://example.com/myfile.zip"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
NSData *received =
[NSURLConnection sendSynchronousRequest:theRequest
returningResponse:nil error:nil];
if ([received writeToFile:saveLocation atomically:TRUE]) {
NSString *cmd =
[NSString stringWithFormat:@"unzip \"%@\" -d\"%@\"",
saveLocation, documentsDirectory];
// Here comes the magic...
system([cmd UTF8String]);
}
Это выглядит проще, чем возиться с zlib ...
Мне нужно было простое решение, но я не нашел здесь того, что мне понравилось бы, поэтому я изменил библиотеку, чтобы делать то, что я хотел. Вы можете найти SSZipArchive полезным. (Кстати, он также может создавать zip-файлы.)
Использование:
NSString *path = @"path_to_your_zip_file";
NSString *destination = @"path_to_the_folder_where_you_want_it_unzipped";
[SSZipArchive unzipFileAtPath:path toDestination:destination];