Оператор Overloading <<-C++

Вы не указали никаких серверных характеристик, запись 9ГБ может быть довольно быстрой на последнем оборудовании.

Вы должны быть в порядке с одним длинным обновлением - , если у вас нет одновременных записей в эту таблицу.

Распространенная уловка для решения этой проблемы (очень длинная транзакция, блокировка записи в таблицу) заключается в разделении UPDATE на диапазоны, основанные на первичном ключе, выполняемом в отдельных транзакциях.

/* Use PK or any attribute with a known distribution pattern */
UPDATE schema.table SET ... WHERE id BETWEEN 0 AND 1000000;
UPDATE schema.table SET ... WHERE id BETWEEN 1000001 AND 2000000;

Для высокого уровня одновременной записи люди используют более тонкие приемы (такие как: SELECT FOR UPDATE / NOWAIT, облегченные блокировки, логика повторных попыток и т. Д.).

5
задан Navaneeth K N 2 March 2009 в 04:29
поделиться

7 ответов

Перегрузка оператора записана правильно?

Это, но можно добиться большего успеха. Как кто-то еще упомянутый, Ваша функция может быть определена полностью из существующих, государственных функций. Почему бы не заставить его использовать только их? Прямо сейчас это - друг, что означает, что это принадлежит деталям реализации. То же верно при помещении оператора <<как участник в класс. Однако сделайте свой оператор <<нечленом, недруг функцией.

class ExtendedVector {
    ...
};

// note, now it is *entirely decoupled* from any private members!
ExtendedVector& operator<<(ExtendedVector& cont, const std::string& str){
    cont.AddChar(str);
    return cont;
}

При изменении класса Вы не будете уверены, что тот Ваш оператор <<будет все еще работать. Но если Ваш оператор <<полностью зависит только от государственных функций, то можно быть уверены, что он будет работать после того, как изменения были внесены в детали реализации класса только. Yay!

Действительно ли это - хорошая практика для перегрузки операторов в таких ситуациях?

Поскольку другой парень повторил, это спорно. Во многих ситуациях перегрузка оператора будет выглядеть "аккуратной" на первый взгляд, но будет похожа на ад в следующем году, потому что у Вас больше нет подсказки, что Вы имели в виду при предоставлении некоторым символам специальной любви. В случае оператора <<, я думаю, что это - использование OK. Его использование в качестве оператора вставки для потоков известно. И я знаю о QT и приложениях KDE, которые используют его экстенсивно в случаях как

QStringList items; 
items << "item1" << "item2";

Подобный случай boost.format который также повторные использования operator% для передающих аргументов в пользу заполнителей в его строке:

format("hello %1%, i'm %2% y'old") % "benny" % 21

Это, конечно, также спорно для использования его там. Но его использование для printf формата указывает, известны и таким образом, его использование в порядке там также, по моему скромному мнению. Но как всегда, стиль также субъективен, так возьмите его с мелкой частицей соли :)

Как я могу принять аргументы переменной длины безопасным с точки зрения типов способом?

Ну, существует способ принять вектор при поиске гомогенных аргументов:

void AddChars(std::vector<std::string> const& v) {
    std::vector<std::string>::const_iterator cit =
        v.begin();
    for(;cit != v.begin(); ++cit) {
        AddChar(*cit);
    }
}

Это не действительно удобно для передачи его все же. Необходимо создать вектор вручную и затем передать... Я вижу, что у Вас уже есть правильное чувство о функциях стиля vararg. Не нужно использовать их для этого вида кода и только при взаимодействии через интерфейс с кодом C или функциями отладки если вообще. Другой способ обработать этот случай состоит в том, чтобы применить программирование препроцессора. Это - усовершенствованная тема и вполне hacky. Идея состоит в том, чтобы автоматически генерировать перегрузки некоторый верхний предел примерно как это:

#define GEN_OVERLOAD(X) \
void AddChars(GEN_ARGS(X, std::string arg)) { \
    /* now access arg0 ... arg(X-1) */ \
    /* AddChar(arg0); ... AddChar(arg(N-1)); */ \
    GEN_PRINT_ARG1(X, AddChar, arg) \
}

/* call macro with 0, 1, ..., 9 as argument
GEN_PRINT(10, GEN_OVERLOAD)

Это - псевдо код. Можно взглянуть на библиотеку препроцессора повышения здесь.

Следующая версия C++ предложит намного лучшие возможности. Списки инициализатора могут использоваться:

void AddChars(initializer_list<std::string> ilist) {
    // range based for loop
    for(std::string const& s : ilist) {
        AddChar(s);
    }
}

...
AddChars({"hello", "you", "this is fun"});

Также возможно в следующем C++ поддерживать произвольный много (смешанный тип) аргументы с помощью variadic шаблоны. GCC4.4 будет иметь поддержку их. GCC 4.3 уже частично поддерживает их.

8
ответ дан 18 December 2019 в 08:31
поделиться

1) Да, кроме, так как AddChar общедоступен нет никакой причины, это должен быть a friend.

2) Это спорно. << вид в положении того, чтобы быть оператором, перегрузка которого для "странных" вещей по крайней мере неохотно принята.

3) Ничто очевидное. Как всегда, профилирование является Вашим другом. Можно хотеть рассмотреть передачу строковых параметров к AddChar и operator<< ссылкой константы (const std::string&) избегать ненужного копирования.

3
ответ дан 18 December 2019 в 08:31
поделиться

Действительно ли это - хорошая практика для перегрузки операторов в таких ситуациях?

Я так не думаю. Это сбивает с толку как ад кого-то, кто не знает, что Вы перегрузили оператор. Просто придерживайтесь описательных имен методов и забудьте о дополнительных символах, которые Вы вводите, его просто не стоящий того. Ваш специалист по обслуживанию (или Вы сами через 6 месяцев) поблагодарит Вас.

3
ответ дан 18 December 2019 в 08:31
поделиться

Оператор правильно не перегружается здесь. Нет никакой причины сделать оператор другом, так как это может быть член класса. Друг для функций, которые не являются фактическими членами класса (такой, перегружаясь <<для ostream, таким образом, объект может быть произведен в суд или ofstreams).

Чем Вы на самом деле хотите, чтобы оператор был:

ExtendedVector& operator<<(const std::string str){
    AddChar(str);
    return *this;
}

Это обычно считают плохой практикой для перегрузки операторов способом, который сделал, чтобы они сделали что-то, чем они обычно делают. <<обычно сдвиг разряда, таким образом перегружая его, этот путь может сбивать с толку. Очевидно, перегрузки STL <<для "потоковой вставки" и так, наряду с которым могло бы иметь смысл перегружать его для Вашего использования похожим способом. Но это не походит на то, что Вы делаете, таким образом, Вы, вероятно, хотите избежать его.

Нет никаких проблем производительности, так как перегрузка оператора совпадает с вызовом регулярной функции, просто вызов скрыт, потому что это сделано автоматически компилятором.

1
ответ дан 18 December 2019 в 08:31
поделиться

Я предпочел бы не перегружать его тот путь лично, потому что векторы обычно не имеют перегруженного левого оператора смещения - это не действительно, это - идиома ;-)

Я, вероятно, возвратил бы ссылку из AddChar вместо этого как так:

ExtendedVector& AddChar(const std::string& str) {
    container.push_back(str);
    return *this;
}

таким образом, можно затем сделать

container.AddChar("First").AddChar("Second");

который не действительно намного больше, чем операторы сдвига разряда.

(также см. комментарий Логана о передаче строк в ссылкой вместо значением).

2
ответ дан 18 December 2019 в 08:31
поделиться

Оператор, перегружающийся в этом случае, не является хорошей практикой, поскольку это делает код менее читаемым. Стандарт std::vector не имеет его ни одним для продвижения элементов, на серьезных основаниях.

Если Вы волнуетесь по поводу кода вызывающей стороны, являющегося слишком длинным, Вы могли бы рассмотреть это вместо перегруженного оператора:

container.AddChar("First").AddChar("Second");

Это будет возможно, если Вы будете иметь AddChar() вернуть *this.

Это забавно, что у Вас есть это toString() функция. В этом случае, operator<< производить к потоку было бы стандартной вещью использовать вместо этого! Таким образом, если Вы хотите использовать операторы, делают toString() функция operator<<.

2
ответ дан 18 December 2019 в 08:31
поделиться

Это собирается сделать вещи довольно сбивающими с толку, я использовал бы тот же синтаксис в качестве станд.:: cin в переменную:

std::cin >> someint;

"First" >> container;

Таким образом, это - по крайней мере, оператор вставки. Мне, когда что-либо имеет <<перегруженный оператор, я ожидаю, что это произведет что-то. Точно так же, как станд.:: суд.

0
ответ дан 18 December 2019 в 08:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: