Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 25.09.2014, 12:46   #21
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,327
По умолчанию

Немного теории

Важно, чтобы вы запомнили разницу между двумя случаями: стек и куча (new)

Если в классе память выделяется только из стека, то самому писать конструктор копирования не надо. Он автоматически сам создаётся. Вот пример класса, где есть только выделение в стеке и где не нужно самому писать конструктор копирования:

Код:
#include <iostream>
#include <string.h>

#define STRSIZE 30

class Student
{
public:
    Student( const char *name )
    {
        setName( name );
    }

    void setName( const char *name )
    {
        strcpy( m_name, name );
    }

    char *name()
    {
        return m_name;
    }

private:
    char m_name[STRSIZE];
};

int main()
{
    Student ivan( "Ivan" );
    Student ivan2( ivan );

    std::cout << ivan2.name() << std::endl;

    return 0;
}
А в примере из предыдущего моего сообщения используется выделение из кучи с помощью оператора new. Там обязательно нужен деструктор, чтобы удалить то, что выделено с помощью new из кучи, чтобы возвращать операционной системе занятый участок памяти. И ещё нужен конструктор копирования. А вот зачем он нужен - почитайте, например, здесь (первое, что нагуглил) http://cppstudio.com/post/9903/ Ну или ещё где-нибудь

P.S. Ждём ваш код

Последний раз редактировалось 8Observer8; 25.09.2014 в 12:56.
8Observer8 вне форума Ответить с цитированием
Старый 25.09.2014, 13:03   #22
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,327
По умолчанию

Я там протупил немного с передачей размера в setName(). Этого не надо делать. Ориентируйтесь на этот код:

Код:
#include <string.h>
#include <iostream>

class Student
{
public:
    Student() :
        defaultSize( 30 )
    {
        this->setDefaultName();
    }

    void setName( const char *name )
    {
        delete m_name;
        m_name = new char[ strlen( name ) + 1 ];
        strcpy( m_name, name );
    }

    Student( const Student &student ) :
        defaultSize( 30 )
    {
        this->setDefaultName();
        this->setName( student.name(), strlen( student.name() ) );
    }

    char *name() const
    {
        return m_name;
    }

    ~Student()
    {
        delete m_name;
    }

private:
    void setDefaultName()
    {
        m_name = new char[defaultSize];
        char *defaultName = "emptyName";
        strcpy( m_name, defaultName );
    }

private:
    char *m_name;
    const int defaultSize;
};

int main()
{
    Student ivan;
    char *name = "Ivan";
    ivan.setName( name );
    std::cout << ivan.name() << std::endl;

    Student ivan2( ivan );
    std::cout << ivan2.name() << std::endl;

    return 0;
}
8Observer8 вне форума Ответить с цитированием
Старый 25.09.2014, 15:18   #23
ACE Valery
Сама себе режиссер
Старожил
 
Аватар для ACE Valery
 
Регистрация: 27.04.2007
Сообщений: 3,365
По умолчанию

Цитата:
А точно надо? - я не уверен (поправьте если не прав), но мне кажется, что если конструктор копирования вообще не объявлять, то он будет создан автоматически и будет вести себя именно так, как вы описали.
Может, уже кто и ответил на этот вопрос, сорри тогда, я тему не читала, мельком глянула. Конструктор копирования создан будет, если его не создавать руками. Но динамические переменные он очень коряво копирует. Поэтому если мы используем динамическую память, нам ручками надо делать корректное копирование.
Если я вас напрягаю или раздражаю, вы всегда можете забиться в угол и поплакать
ACE Valery вне форума Ответить с цитированием
Старый 25.09.2014, 16:26   #24
rrrFer
Санитар
Старожил
 
Аватар для rrrFer
 
Регистрация: 04.10.2008
Сообщений: 2,577
По умолчанию

ACE Valery
Цитата:
Может, уже кто и ответил на этот вопрос, сорри тогда, я тему не читала, мельком глянула. Конструктор копирования создан будет, если его не создавать руками. Но динамические переменные он очень коряво копирует. Поэтому если мы используем динамическую память, нам ручками надо делать корректное копирование.
Я про это и говорил. В коде из первого поста динамически память не выделялась. Ну вот обсервер уже описал про это с примерами ))

Так то я стараюсь конструкторы копирования вообще не писать и память динамически не выделять. Обычно это получается и конструктора по умолчанию хватает. А еще утечек не бывает, с исключениями проблем нет и т.п.

Задача некорректно стоит. Требуют от ТС писать руками то, что компилятор сам автоматически напишет. Ну если в этой задаче string вместо С-строк юзать.
rrrFer вне форума Ответить с цитированием
Старый 25.09.2014, 17:12   #25
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,327
По умолчанию

Цитата:
Задача некорректно стоит. Требуют от ТС писать руками то, что компилятор сам автоматически напишет. Ну если в этой задаче string вместо С-строк юзать.
У меня такое предположения, что условия задачи так поставлены, чтобы познакомить с конструктором копирования, показать зачем он нужен. Задача неудачно выбрана. Здесь, конечно, надо использовать С++-строки вместо С-строк:
Код:
#include <iostream>
#include <string>

class Student
{
public:
    Student( const std::string &name = "emptyName" ) :
        m_name( name )
    {
    }

    void setName( const std::string &name )
    {
        m_name = name;
    }

    std::string name() const
    {
        return m_name;
    }

private:
    std::string m_name;
};

int main()
{
    Student ivan;

    // Пустое имя
    std::cout << "Emty name: " << ivan.name() << std::endl;

    // Установленное имя
    std::string name( "ivan" );
    ivan.setName( name );
    std::cout << "Set name: " << ivan.name() << std::endl;

    // Конструктор копирования поумолчанию
    Student ivan2( ivan );
    std::cout << "With copy-constuctor: " << ivan2.name() << std::endl;

    return 0;
}
Вывод:
Цитата:
Emty name: emptyName
Set name: ivan
With copy-constuctor: ivan
P.S. Но с C-строками тоже надо уметь работать. Вот цитата из книжки "Professinal C++":
Цитата:
One of the most common situations is where
a C++ program has to call a C-based interface
in some third-party library or as part of
interfacing to the operating system.
То есть для работы с сторонними библиотеками (которые написаны на Си) и для взаимодействия с операционной системой, например, с Windows через WinAPI или с Linux через его системные вызовы

Последний раз редактировалось 8Observer8; 25.09.2014 в 17:16.
8Observer8 вне форума Ответить с цитированием
Старый 25.09.2014, 21:32   #26
rrrFer
Санитар
Старожил
 
Аватар для rrrFer
 
Регистрация: 04.10.2008
Сообщений: 2,577
По умолчанию

Цитата:
P.S. Но с C-строками тоже надо уметь работать
...
То есть для работы с сторонними библиотеками (которые написаны на Си) и для взаимодействия с операционной системой, например, с Windows через WinAPI или с Linux через его системные вызовы
Чтобы не работать с ними и с WinAPI и прочим есть высокоуровневые библиотеки.

Добрая половина матерых программистов рекомендует вместо прямого использования какого бы то ни было АПИ в своей программе, завернуть его в красивый фантик (шаблон типа Адаптер), покрыть фантик тестами и пользоваться им не зная бед.

Ну фантик нужен если например таки приходится работать со страшным АПИ.
Всякие С-строки кнешно будут нужны пока бы будешь обертку писать, но потом про них можно будет забыть.
rrrFer вне форума Ответить с цитированием
Старый 26.09.2014, 20:27   #27
Otar4ik
Форумчанин
 
Регистрация: 16.04.2010
Сообщений: 123
По умолчанию

Большое спасибо за помощь!
Otar4ik вне форума Ответить с цитированием
Старый 26.09.2014, 21:24   #28
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,327
По умолчанию

Цитата:
Сообщение от Otar4ik Посмотреть сообщение
Большое спасибо за помощь!
Cheers Otar4ik!
8Observer8 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Вероятность того, что студент забросит мяч в корзину, равна 0,4. Студент произвел 24 броска. Найти наивероятнейшее число попаданий now2 Помощь студентам 1 25.03.2014 17:48
структура и класс нона Помощь студентам 2 30.03.2012 07:42
класс Студент Alexander1205 Общие вопросы C/C++ 3 07.07.2011 23:06
Где скачать в электронном виде "ATL 8. Внутренняя структура и применение" graviator Обсуждение статей 3 07.04.2010 22:10
Применение конструкторов [Java] [CODER] Помощь студентам 2 28.03.2010 21:29