С Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 30, средняя оценка - 4.93
_lacrimosa_
1 / 1 / 0
Регистрация: 10.06.2010
Сообщений: 26
#1

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

12.06.2010, 00:01. Просмотров 4149. Ответов 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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.06.2010, 00:01
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Переопределение оператора присваивания (C++):

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

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

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

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

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

Перегрузка оператора присваивания - C++
Вот есть такой класс template<typename TT> class Matrix { public: ...

2
easybudda
Модератор
Эксперт CЭксперт С++
9700 / 5650 / 964
Регистрация: 25.07.2009
Сообщений: 10,873
12.06.2010, 00:36 #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
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
_lacrimosa_
1 / 1 / 0
Регистрация: 10.06.2010
Сообщений: 26
12.06.2010, 00:42  [ТС] #3
Спасибо. Особенно за строчку 62 =) Навело на правильную мысль.

Мне видимо нужно было вместо C=D использовать *C=*D. То есть в первом случае я копировал адрес объекта, а не сам объект. Теперь дошло.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.06.2010, 00:42
Привет! Вот еще темы с ответами:

Перегрузка оператора присваивания - C++
Приветствую всех. Не могли бы подсказать как переопределить оператор присваивания. То что искал, так там написано в общем о...

Перегрузка оператора присваивания - C++
Добрый вечер. Есть задание: Нужно так перегрузить оператор =, чтобы можно было элементу одного класса, присваивать значение элемента...

Перегрузка оператора присваивания - C++
Доброго времени суток! Возник вопрос по поводу перегрузки оператора присваивания. Пример перегрузки по канону: class Integer { ...

Перегрузка оператора присваивания - C++
мне надо было реализовать конструкторы, деструктор, оператор присваивания, функции ввода / вывода объектов; кто сможет дописать...


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

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.