Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Первые опыты в C++, анализ кода  
:(
    Опции темы
UnrealMan
Дата 7.11.2007, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



Цитата(archimed7592 @  7.11.2007,  11:34 Найти цитируемый пост)
35 правил, оч известная книга.

55 smile
Если точнее: Эффективное использование C++. 55 верных советов улучшить структуру и код ваших программ
Правило 26: Откладывайте определение переменных насколько возможно.

Есть ещё в "Стандарты программирования на C++. 101 правило и рекомендация" (Герб Саттер, Андрей Александреску)
18. Объявляйте переменные как можно локальнее.
PM MAIL   Вверх
MAKCim
Дата 7.11.2007, 12:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(archimed7592 @  7.11.2007,  12:40 Найти цитируемый пост)
К примеру, если scope ограничен, он может вообще воспользоваться регистрами.

первый раз все равно идет чтение в регистр
и неважно, где расположена при этом переменная


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
archimed7592
Дата 7.11.2007, 13:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Цитата(UnrealMan @  7.11.2007,  12:45 Найти цитируемый пост)
55 smile

55 я начал читать, но когда понял, что это то же самое что и 35 читать стало лень(а в магазине сказали "они дополняют друг друга") smile.


MAKCim, в принципе ты можешь писать в стиле Си smile. У меня сейчас не соображает голова чтобы дать тебе весомые аргументы, что писать нужно иначе... Возьми что ли Мейрса с Александреску у кого-нибудь, пролистай указаные правила.


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
MAKCim
Дата 7.11.2007, 13:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



archimed7592, 
Цитата(archimed7592 @  7.11.2007,  13:09 Найти цитируемый пост)
MAKCim, в принципе ты можешь писать в стиле Си

спасибо  smile 
на самом деле я просто хочу разобраться
Цитата(archimed7592 @  7.11.2007,  13:09 Найти цитируемый пост)
Возьми что ли Мейрса с Александреску у кого-нибудь, пролистай указаные правила. 

эх, если бы кто-нибудь здесь цитату привел
а то искать лень  smile 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
GrayCardinal
Дата 7.11.2007, 14:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Фигасе
****


Профиль
Группа: Завсегдатай
Сообщений: 3039
Регистрация: 9.11.2003

Репутация: 2
Всего: 58



SaDFromSpb, 
ООП ? Да там проблемы какие-то с распределением памяти были... Да и на самом деле - не нужно оно для ядра...


--------------------
PM MAIL WWW   Вверх
UnrealMan
Дата 7.11.2007, 14:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



Цитата(MAKCim @  7.11.2007,  11:36 Найти цитируемый пост)
archimed7592, 
zkv, 
можно подробнее об этом

Аргументов 2:
1) производительность - в случае неиспользования переменных не должны зря вызываться конструкторы и деструкторы,
2) читабельность/самодокументируемость кода выше, когда переменная объявлена ближе к месту использования и инициализируется в месте объявления (хорошо видно, когда и для чего нужна переменная).


Это сообщение отредактировал(а) UnrealMan - 7.11.2007, 14:24
PM MAIL   Вверх
tatan
Дата 7.11.2007, 14:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 70
Регистрация: 31.10.2007

Репутация: нет
Всего: 1



Внимательно все прочитал
Лично я наверное буду по-паскалевски объявлять переменные в начале а для лучшей читаемости кода давать переменным 
осмысленные имена, ну, видимо, это вера.у каждого подхода есть +-smile Оставляю решение на потом, видимо с приобретением новых знаний
я получу аргументы в пользу той или иной доктриныsmile

Жалко, что мы отвлеклись. и если позволите еще важный вопрос, скоре всего из разряда RTFM но не получается у меня.

Вынес описание класса в файл dbft.hpp, реализацию в файл dbft.cpp, создал проект с main() в файле dbfex.cpp.
В файле dbft.cpp сделал #include "dbft.hpp", в файле dbfex.cpp  - тоже.
При компиляции получаю ошибку "In file included from dbfex.cpp" на строке #include "dbft.hpp" в файле dbft.cpp
То есть видимо ругается что 2 раза включен
Как надо правильно сделать?  
PM MAIL   Вверх
zkv
Дата 7.11.2007, 15:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

Репутация: 26
Всего: 92



Цитата(tatan @  7.11.2007,  14:44 Найти цитируемый пост)
Лично я наверное буду по-паскалевски объявлять переменные в начале а для лучшей читаемости кода давать переменным 
осмысленные имена, ну, видимо, это вера.у каждого подхода есть +

что то пока я не заметил ни одного плюса у предварительного объявления переменных
Цитата(tatan @  7.11.2007,  14:44 Найти цитируемый пост)
То есть видимо ругается что 2 раза включен

защитить хедер от двойного подключения, 
добавь первой строкой 
Код

#pragma once 


либо обрами весь код в хедере таким макросом:
Код

#ifndef MYHEADER_H
#define MYHEADER_H

//весь код тут

#endif//MYHEDER_H


Это сообщение отредактировал(а) zkv - 7.11.2007, 16:08
PM MAIL   Вверх
tatan
Дата 7.11.2007, 15:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 70
Регистрация: 31.10.2007

Репутация: нет
Всего: 1



Пробовал оба варианта
Нет, наверное ругается по другому поводу
ошибки в dbft.hpp дальше описываются - типа fstream does not name a type, и тд
 я правильно сделал включив в файл dbft.hpp  строки ?

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <sstream> 

Без них собствено те же ошибки
Блин

Добавлено через 11 минут и 15 секунд
Ура, заработало!smile
инклюдить  надо после using namespace std а то компилер ничего не находитsmile
Всем спасибо
PM MAIL   Вверх
zkv
Дата 7.11.2007, 16:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

Репутация: 26
Всего: 92



Цитата(tatan @  7.11.2007,  15:41 Найти цитируемый пост)
using namespace std

лучше не использовать - плохой тон
Цитата(MAKCim @  7.11.2007,  13:15 Найти цитируемый пост)
эх, если бы кто-нибудь здесь цитату привел

из дежавю копировал, поэтому на форматирование не жаловаться smile
Цитата(Правило 26: Откладывайте определение переменных насколько возможно )

Всякий раз при объявлении переменной, принадлежащий типу, в котором есть 
конструктор или деструктор, программа тратит время на ее конструирование, 
когда поток управления достигнет определения переменной, и на уничтожение - 
при выходе переменной из области видимости. Эти накладные расходы  
приходится нести даже тогда, когда переменная не используется, и, разумеется, их  
хотелось бы избежать. 
Вероятно, вы думаете, что никогда не объявляете неиспользуемых  
переменных, но так ли это? Рассмотрим следующую функцию, которая возвращает  
зашифрованный пароль при условии, что его длина не меньше некоторого  
минимума. Если пароль слишком короткий, функция возбуждает исключение типа 
logicerror, определенное в стандартной библиотеке C++ (см. правило 54): 
// эта функция объявляет переменную encrypted слишком рано 
std::string encryptPassword(conSt std::strings password) 
{ 
using namespace std; 
string encrypted; 
if(password.length() < MinimumPasswordLength) { 
throw logic_error("Слишком короткий пароль"); 
Реализация 
// сделать все, что необходимо для помещения 
// зашифрованного пароля в переменную encrypted 
return encrypted; 
Нельзя сказать, что объект encrypted в этой функции совсем уж не  
используется, но он не используется в случае, когда возбуждается исключение. Другими 
словами, вы платите за вызов конструктора и деструктора объекта encrypted, 
даже если функция encryptPassword возбуждает исключение. Так не лучше ли 
отложить определение переменной encrypted до того момента, когда вы будете 
знать, что она нужна? 
// в этой функции определение переменной encrypted отложено до момента, 
// когда в ней возникает надобность 
std::string encryptPassword(const std::strings password) 
{ 
using namespace std; 
if(password.length() < MinimumPasswordLength) { 
throw logic_error("Слишком короткий пароль"); 
string encrypted; 
// сделать все, что необходимо для помещения 
// зашифрованного пароля в переменную encrypted 
return encrypted; 
} 
Этот код все еще не настолько компактный, как мог бы быть, потому что  
переменная encrypted определена без начального значения. А значит, будет  
использован ее конструктор по умолчанию. Часто первое, что нужно сделать с объектом, - 
это дать ему какое-то значение, нередко посредством присваивания. В правиле 4 
объяснено, почему конструирование объектов по умолчанию с последующим 
присваиванием значения менее эффективно, чем инициализация нужным  
значением с самого начала. Это относится и к данному случаю. Например,  
предположим, что для выполнения «трудной» части работы функция encryptPassword  
вызывает следующую функцию: 
void encrypt(std::strings s); // шифрует s по месту 
Тогда encryptPassword может быть реализована следующим образом, хотя и 
это еще не оптимальный способ: 
// в этой функции определение переменной encrypted отложено до момента, 
// когда в ней возникает надобность, но и этот вариант еще недостаточно 
// эффективен 
std::string encryptPassword(const std::stringS password) 
... // проверка длины 
string encrypted; // конструктор по умолчанию 
encrypted = password; // присваивание encrypted 
encrypt(encrypted) ; 
return encrypted; 

Еще лучше инициализировать encrypted параметром password, избежав  
таким образом потенциально дорогостоящего конструктора по умолчанию: 
// а это оптимальный способ определения и инициализации encrypted 
std::string encryptPassword(const std::string& password) 
{ 
... // проверка длины 
string encrypted(password); // определение и инициализация 
// конструктором копирования 
encrypt(encrypted); 
return encrypted; 
} 
Это и означает «откладывать насколько возможно» (как сказано в заголовке 
правила). Вы не только должны откладывать определение переменной до того 
момента, когда она используется, нужно еще постараться отложить определение 
до получения аргументов для инициализации. Поступив так, вы избегаете  
конструирования и разрушения ненужных объектов, а также излишних вызовов  
конструкторов по умолчанию. Более того, это помогает документировать назначение 
переменных за счет инициализации их в том контексте, в котором их значение 
понятно без слов. 
«А как насчет циклов?» - можете удивиться вы. Если переменная  
используется только внутри цикла, то что лучше: определить ее вне цикла и выполнять 
присваивание на каждой итерации или определить ее внутри цикла? Другими 
словами, какая из следующих конструкций предпочтительнее? 
// Подход А: определение вне цикла 
Widget w; 
for(int 1=0; Kn; ++i) { 
w = некоторое значение, зависящее от i; 
II Подход В: определение внутри цикла 
fordnt i=0; i<n; ++i) { 
Widget «(некоторое значение, зависящее от i); 
Здесь я перехожу от объекта типа string к объекту типа Widget, чтобы избежать 
любых предположений относительно стоимости конструирования, разрушения 
и присваивания. 
В терминах операций Widget накладные расходы вычисляются так: 
Q Подход А: 1 конструктор + 1 деструктор + п присваиваний 
? Подход В: п конструкторов + п деструкторов 
Для классов, в которых стоимость операции присваивания меньше, чем пары 
конструктор-деструктор, подход А обычно более эффективен. Особенно это  
верно, когда значение п достаточно велико. В противном случае, возможно, подход В 
лучше. Более того, в случае А имя w видимо в более широкой области  
(включающей в себя цикл), чем в случае В, а иногда это делает программу менее понятной 
и удобной для сопровождения. Поэтому если A) нет априорной информации 
Реализация 
о том, что присваивание обходится дешевле, чем пара конструктор-деструктор, и 
B) речь идет о части программы, производительность которой критична, то по 
умолчанию рекомендуется использовать подход В. 
Что следует помнить 
Ш Откладывайте определение переменных насколько возможно. Это  
делает программы яснее и повышает их эффективность. 

PM MAIL   Вверх
SergeCpp
Дата 7.11.2007, 17:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


 
**


Профиль
Группа: Участник
Сообщений: 955
Регистрация: 8.8.2005
Где: At Home

Репутация: 15
Всего: 124



Цитата(MAKCim @  7.11.2007,  14:36 Найти цитируемый пост)
EBP не меняется в пределах функции, так что, имхо, все равно, откуда обращаться к локальной переменной

Использовать EBP в качестве того, для чего он предназначен изначально — расточительство.
Visual Studio 6, к примеру (Release), использует EBP как регистр общего назначения.
Переменные адресуются по ESP (да, это сложнее, на то он и компилятор, чтобы справиться, он и справляется).
Подозреваю, что и другие компиляторы не разбрасываются регистрами.

PM MAIL WWW ICQ   Вверх
MAKCim
Дата 7.11.2007, 18:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата(SergeCpp @  7.11.2007,  17:00 Найти цитируемый пост)
Переменные адресуются по ESP (да, это сложнее, на то он и компилятор, чтобы справиться, он и справляется).
Подозреваю, что и другие компиляторы не разбрасываются регистрами

использование ESP, +1 байт к каждой инструкции
расточительно, однако  smile (учитывая, что локальных переменных обычно много)
тут надо соблюдать равновесие между оптимизацией по скорости и размеру

Добавлено через 3 минуты и 29 секунд
zkv, 
спасибо за ссылку



--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0595 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.