Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.73/33: Рейтинг темы: голосов - 33, средняя оценка - 4.73
1 / 1 / 2
Регистрация: 10.06.2010
Сообщений: 26

Переопределение оператора присваивания

12.06.2010, 00:01. Показов 6645. Ответов 2
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Имеется такой простой класс:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class TClass
{
    private:
        float* A;
        int N;
    public:
        TClass(int _N)                      //конструктор
        {
            N = _N;
            A = new float [N];
        }
        ~TClass()                           //деструктор
        {
            delete [] A;
        }
        TClass& operator= (const TClass& B) //переопределённый оператор =
        {
            if (this == &B)
                return *this;
 
            N = B.N;
            delete [] A;
            A = new float [N];
            memcpy(A,B.A,N*sizeof(float));
            
            return *this;
        }
};
Суть проблемы в поведении операции присваивания. Примеры использования объектов класса:

1) В случае, если объекты класса статические, то всё ОК:

C++
1
2
3
4
5
6
void main()
{
    TClass C(10);
    TClass D(5);
    C=D;
}
2) В случае, если объекты класса создаются динамически:

C++
1
2
3
4
5
    TClass* C = new TClass(10);
    TClass* D = new TClass(5);
    C=D;  // FAIL
    delete C;
    delete D;
После выполнения операции присваивания во 2-ом случае, объекты C и D идентичны. Более того, расположены на одном участке памяти, причём массивы, содержащиеся в C и D, также расположены на одном участке памяти. При вызове delete C память освобождается. При вызове delete D получается ситуация, когда нужно удалить ту же самую память (удалённую при помощи delete C, так как C=D). Отмечу, что оператор = вообще не вызывается при выполнении программы, что странно. Если не ошибаюсь, то вызывается оператор присваивания по умолчанию и объекты становятся копиями. Всё работает как надо, если:

вместо

C++
1
C=D;  // FAIL
использовать

C++
1
C->operator=(*D);
Собственно вопрос, как такого избежать и что предпринять? Требуемый результат: данные в C и D должны быть одинаковые, но адреса объектов различны.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
12.06.2010, 00:01
Ответы с готовыми решениями:

Для чего нужно переопределение оператора присваивания?
HumansClass& operator=(const HumansClass& right); //переопределение операции присваивания Для чего нужно переопределение оператора...

Избыточное копирование объекта при реализации оператора умножения и оператора присваивания
Есть класс работы с матрицами. Есть операция умножения матриц, описанная как оператор класса. В данном коротком примере я просто моделирую...

Неправильная работа оператора присваивания после работы оператора суммирования
Доброго времени суток. У меня есть класс вектор class TVector {//ewde public: TVector(); //Vector(Vector &v); ...

2
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,973
12.06.2010, 00:36
вот так вроде работает:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <iostream>
#include <algorithm>
 
class TClass {
private:
    float* A;
    int N;
public:
    TClass() : N(0), A(0) { }
    TClass(int _N) {
        N = _N;
        A = new float [N];
    }
    TClass(const TClass & t) {
        *this = t;
    }
    ~TClass() {
        if ( A )
            delete [] A;
    }
    const TClass& operator= (const TClass& B) {
        if (this == &B)
            return *this;
 
        N = B.N;
        if ( A )
            delete [] A;
        A = new float [N];
        std::copy(B.A, B.A + B.N, A);
//      memcpy(A,B.A,N*sizeof(float));
                       
        return *this;
    }
    
    friend std::ostream & operator << (std::ostream & ost, const TClass & t) {
        for ( int i = 0; i < t.N; ++i )
            ost << t.A[i] << std::endl;
        return ost;
    }
    
    friend std::istream & operator >> (std::istream & ist, TClass & t) {
        for ( int i = 0; i < t.N; ++i )
            ist >> t.A[i];
        return ist;
    }
};
 
int main(){
    TClass * a, * b, * c;
    const int size = 3;
    
    std::cout << "enter " << size << " double values: " << std::endl;
    a = new TClass(size);
    std::cin >> *a;
    std::cout << "\nA values:\n" << *a << std::endl;
    
    b = new TClass(*a);
    delete a;
    std::cout << "B values:\n" << *b << std::endl;
    
    c = new TClass();
    *c = *b;
    delete b;
    std::cout << "C values:\n" << *c << std::endl;
    
    delete c;
    return 0;
}
Добавлено через 4 минуты
Цитата Сообщение от _lacrimosa_ Посмотреть сообщение
C=D;
ну ещё бы! копировать нужно не указатели, а их значения!
C++
1
*C = *D;
0
1 / 1 / 2
Регистрация: 10.06.2010
Сообщений: 26
12.06.2010, 00:42  [ТС]
Спасибо. Особенно за строчку 62 =) Навело на правильную мысль.

Мне видимо нужно было вместо C=D использовать *C=*D. То есть в первом случае я копировал адрес объекта, а не сам объект. Теперь дошло.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
12.06.2010, 00:42
Помогаю со студенческими работами здесь

Переопределение операции присваивания
Есть вот такой класс: #ifndef cd_h #define cd_h class Cd { private: char* performance; char* label; int selections;

Переопределение операции присваивания
В случае, когда в классе есть члены, память под которые выделяется динамически, операцию присваивания, как и конструкторы с деструкторами...

Проверка оператора присваивания
Программа должна находить и проверять правильность написания операторов присваивания в исходном тексте программы. Результатом работы...

Насчет оператора присваивания
Есть следующий код : #include &lt;iostream&gt; using namespace std; class Array { private: size_t mysize; int *mydata; ...

Перегрузка оператора присваивания
Здравствуйте, недавно читал про перегрузку операторов и решил поупражняться с этим, однако на практике возникла проблема. Ниже приведен код...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка. Рецензия / Мнение/ Перевод https:/ / **********/ gallery/ thinkpad-x220-tablet-porn-gzoEAjs . . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru