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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> какой из 2-х способов выбрать 
V
    Опции темы
yngwie19
Дата 6.11.2008, 16:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 15.6.2008
Где: Новгород

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



Всем привет. Есть сласс Employee реализованный двумя способами:
1) Выделение памяти для данных-элементов в динамической памяти.
2) Выделение памяти для данных-элементов в стеке.


Код

class Employee  // Пример 1. 
{
    public:
        Employee(char*, char*);
        void Print();
    private:
        char* fn, *ln;
};

int main()
{    
    Employee e1("Yngwie","Malmsteen");
    e1.Print();
    
    return 0;
}

Employee::Employee(char* firstname, char* lastname)
{
    fn = firstname;
    ln = lastname;
}

void Employee::Print()
{
    cout<<fn<<endl;
    cout<<ln<<endl;
}


Пример 2 (Пямять выделена динамически)

Код

class Employee // Пример 2
{
    public:
        Employee(char*, char*);
        ~Employee();
        void Print();
    private:
        char* fn, *ln;
};
int main()
{    
    Employee e1("Yngwie","Malmsteen");
    e1.Print();
    
    return 0;
}

Employee::Employee(char* firstname, char* lastname)
{
    fn = new char[strlen(firstname)+1];
    strcpy(fn,firstname);
    
    ln = new char[strlen(lastname)+1];
    strcpy(ln,lastname);
}
Employee::~Employee()
{
    delete []fn;
    delete []ln;
}
void Employee::Print()
{
    cout<<fn<<endl;
    cout<<ln<<endl;
}


Собственно что бы посоветовали использовать с точки зрения быстродействия и производительности в данной ситуации, динамическую память или стек?

Это сообщение отредактировал(а) yngwie19 - 6.11.2008, 16:59
PM MAIL   Вверх
mes
Дата 6.11.2008, 17:04 (ссылка) |    (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

Репутация: 79
Всего: 250



Класс из первого примера не корректен. Вы инициализируете указатели, адресом внешнего объекта. И поэтомуу уследить когда указатель станет невалидным Вы не сможете.

Добавлено через 6 минут и 56 секунд
во втором Вы храните копию строки - правильно... но Вам не хватает конструктора копий и Вас будет ждать сюрприз, когда Вы после копирования объекта :
Вначале оба объекта (оригинал и копия( будут разделять общие строки, а после удаления одного из них (удалятся и данные) указатели второго будут не валидны.

Вобщем  всегда следите , если в классе есть указатель то должен быть либо свой конструктор копий, либо запрет на копирование..)

Добавлено через 8 минут и 11 секунд
а вобще лучше вместо char * используйте std::string.

Добавлено через 13 минут и 49 секунд
Цитата(yngwie19 @  6.11.2008,  16:58 Найти цитируемый пост)

Собственно что бы посоветовали использовать с точки зрения быстродействия и производительности в данной ситуации, динамическую память или стек?

Я бы посоветовал не думать о быстродействии и производительности как о самоцели. Выйгрыша тут Вы не найдете. 

Это сообщение отредактировал(а) mes - 6.11.2008, 17:05


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


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



yngwie19, поддерживаю mes. А по поводу стрингов:
Код
class Employee // Пример 2
{
public:
    Employee(const std::string &f, const std::string &l) : fn(f), ln(l) {}
    void Print() { std::cout << fn << '\n' << ln << std::endl; }
private:
    std::string fn;
    std::string ln;
};

int main()
{    
    Employee e1("Yngwie","Malmsteen");
    e1.Print();
    
    return 0;
}
Видишь, как все просто?
PM   Вверх
yngwie19
Дата 6.11.2008, 18:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 15.6.2008
Где: Новгород

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



Мне просто хотелось реализовать по возвожности без включения дополнительных библиотек, т.к это ведет в увеличению кода при компоновке
PM MAIL   Вверх
J0ker
Дата 6.11.2008, 19:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: 9
Всего: 14



Цитата(yngwie19 @ 6.11.2008,  18:31)
Мне просто хотелось реализовать по возвожности без включения дополнительных библиотек, т.к это ведет в увеличению кода при компоновке

тогда вам надо все это написать в машинных кодах - тогда вы даже без компилятора и линкера сможете обойтись  smile

Добавлено через 3 минуты и 9 секунд
да, и пример 1 - кривой по определению - вы не можете гарантировать, что в конструктор будут переданы статические данные


--------------------
user posted image
PM MAIL   Вверх
yngwie19
Дата 6.11.2008, 20:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 15.6.2008
Где: Новгород

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



J0ker, а если их сделать статичскими, определить в файле?
PM MAIL   Вверх
mes
Дата 6.11.2008, 20:42 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

Репутация: 79
Всего: 250



Цитата(yngwie19 @  6.11.2008,  18:31 Найти цитируемый пост)
Мне просто хотелось реализовать по возвожности без включения дополнительных библиотек, т.к это ведет в увеличению кода при компоновке 

если пишете обычную программу для обычного (персонального) компа, то 
1. увеличенный (в разумных пределах) размер не ухудшает прогу
2. использование стандартной библиотеки stl (std:: ) не приведет к значительному увеличению кода, так как она шаблонная.
3. функцию которая реализована в библиотеке, все равно Вы будете реализовывать, и увеличение кода неизбежно.
4. принципиально отказавшись от библиотек Вы обрекаете себя на  изготовление велосипеда.
5..
 smile 


Это сообщение отредактировал(а) mes - 6.11.2008, 20:43


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


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 15.6.2008
Где: Новгород

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



mes, Спасибо большое за объяснение, мне все же не очень понятно, почему первый пример моего класса не коректен
PM MAIL   Вверх
mes
Дата 6.11.2008, 20:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

Репутация: 79
Всего: 250



Цитата(yngwie19 @  6.11.2008,  20:25 Найти цитируемый пост)
если их сделать статичскими, определить в файле? 

сравните разницу использования char* и std::string для строки . 
Вы хотите все контролировать вручную, как в случае с char* и делать кучу черной работы или просто управлять автоматизированным процессом, как в случае с std::string
Если Вы выбрали первое, то задайте себе вопрос зачем Вам вобще Cpp , если не хотите использовать преимуществ которые он дает?



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


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 15.6.2008
Где: Новгород

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



mes, Я может и буду использовать все возможности, которые дает С++, но мне хочется также разобраться в процессе контроля вручную, поясните пожалуйста в чем может быть ошибка при проектировании первого варианта класса Employee.

Спасибо
PM MAIL   Вверх
J0ker
Дата 6.11.2008, 20:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: 9
Всего: 14



Цитата(yngwie19 @ 6.11.2008,  20:25)
J0ker, а если их сделать статичскими, определить в файле?

статическими где?

объясняю
когда вы передаете в конструктор char* то внутри конструктора невозможно определить, статически данные размещены в памяти по этому адресу или нет. Т.е. в конструктор вы с тем-же успехом можете передать указатель на временные данные, которые рано или поздно станут невалидны, но в объекте на них останется ссылка, что в итоге приведет к неприятностям.


--------------------
user posted image
PM MAIL   Вверх
yngwie19
Дата 6.11.2008, 21:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 15.6.2008
Где: Новгород

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



J0ker, ну дак смотри, когда Я передаю конструктору временные объекты char*, далее они копируются в данные элементы (fn и ln). После завершения работы конструктора локальные переменные уничтожаются, но в объекте я имею нужные значения в полях fn и ln, т.к я скопировал значения до завершения работы конструктора. В чем тогда проблема?
PM MAIL   Вверх
mes
Дата 6.11.2008, 21:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

Репутация: 79
Всего: 250



Цитата(yngwie19 @  6.11.2008,  20:47 Найти цитируемый пост)
почему первый пример моего класса не коректен 


Попробуйте с двумя своими классами этот тест  и думаю  почувствуете разницу :

Код

int main()
{    
   char str[] =  "Yngwie";

    Employee e1(str,"Malmsteen");
    e1.Print();

    str[0] = '_';
    e1.Print();     
    
    return 0;
}

Также можете попробовать инициализировать ваш объект динамической строкой, после удалять строку за ненадобностью и выводить имя работника. Без краша не обойдется smile



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


Опытный
**


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

Репутация: 9
Всего: 14



вот вам элементарный пример
Код

Employee *foo()
{
    char b[] = "test";
    return new Employee(b, b);
}

int main()
{
    Employee *e = foo();
    ......
    return 0;
}


Добавлено через 1 минуту и 18 секунд
Цитата(yngwie19 @ 6.11.2008,  21:01)
J0ker, ну дак смотри, когда Я передаю конструктору временные объекты char*, далее они копируются в данные элементы (fn и ln). После завершения работы конструктора локальные переменные уничтожаются, но в объекте я имею нужные значения в полях fn и ln, т.к я скопировал значения до завершения работы конструктора. В чем тогда проблема?

я говорю про первый вариант - вы там сохраняете указатели, а не копируете


--------------------
user posted image
PM MAIL   Вверх
mes
Дата 6.11.2008, 21:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

Репутация: 79
Всего: 250



Цитата(yngwie19 @  6.11.2008,  21:01 Найти цитируемый пост)
далее они копируются в данные элементы (fn и ln)

Вы копируете значение указателя, а не строку на которую он указывает. 
Например, некто Вам дал почитать конспект.. Вы сделали себе заметку, что на 22й странице есть что-то интересное.
Потом некто вырвал эту страницу. Вы решив обратиться к нужной странице ее не находите .. А завтра экзамен  smile  
Ну а если сделаете копию нужной странички, то дальнейшая судьба оригинала Вас  уже не затронет.  smile 

Это сообщение отредактировал(а) mes - 6.11.2008, 22:02


--------------------
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


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

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


 




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


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

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