Копирование 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
.
Теперь почти все компиляторы обеспечивают копирование при разрешении оптимизации (и если для его отключения не установлен другой параметр).
С каждым экземпляром копии исключается одна конструкция и одно совпадение с уничтожением копии, что позволяет сэкономить время процессора, а один объект не создан, что позволяет сэкономить место в стеке кадр.
Необходимо посмотреть на то, как распределенное управление изменениями работает. Взгляд на SVN, CVS и другие репозитории, которые справляются с работой дельт.
у Вас есть несколько вариантов использования.
Синхронизируют изменения. Ваш журнал изменений (или история дельты) подход выглядит хорошим для этого. Клиенты отправляют свои дельты на сервер; сервер консолидирует и распределяет дельты клиентам. Это - типичный случай. Базы данных называют эту "репликацию транзакции".
Клиент потерял синхронизацию. Или через резервное копирование/восстановление или из-за ошибки. В этом случае клиент должен получить текущее состояние от сервера, не проходя дельты. Это - копия от ведущего устройства для детализации, дельты и производительность быть проклятым. Это - одноразовая вещь; клиент повреждается; не пытайтесь оптимизировать это, просто реализовать надежную копию.
Клиент подозрителен. В этом случае необходимо сравнить клиент с сервером, чтобы определить, актуален ли клиент и нуждается в каких-либо дельтах.
необходимо следовать за базой данных (и SVN) шаблон разработки последовательной нумерации каждого изменения. Тем путем клиент может выполнить тривиальный запрос ("Какой пересмотр я должен иметь?") прежде, чем попытаться синхронизироваться. И даже тогда, запрос ("Все дельты с тех пор 2149") восхитительно прост для клиента и сервера обработать.
То, в чем Вы действительно нуждаетесь, Операционное Преобразование (OT). Это может даже обслужить конфликты во многих случаях.
Это - все еще активная область исследования, но существуют реализации различных алгоритмов OT вокруг. Я вовлекался в такое исследование в течение многих лет теперь, таким образом сообщите мне, интересует ли этот маршрут Вас, и я буду рад поставить Вас к соответствующим ресурсам.
Вопрос не совершенно прозрачен, но я изучил бы оптимистическая блокировка на вашем месте. Это может быть реализовано с порядковым номером, который сервер возвращает для каждой записи. Когда клиент попытается сохранить запись назад, она будет включать порядковый номер, который она получила от сервера. Если порядковый номер соответствует тому, что находится в базе данных в то время, когда обновление получено, обновление позволяется, и порядковый номер увеличен. Если порядковые номера не соответствуют, обновление запрещено.