Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Проблема с перегрузкой оператора =


Автор: Antarn 7.12.2008, 18:52
Здравствуйте.

Объясните, в чем ошибка перегрузки оператора = с параметром char ?
Код

class A
{
public:
    int field;

    A()
    {
        field = 0;
    }

    A& operator = (A& obj)
    {
        this->field = obj.field;

        return *this;
    }

    A& operator = (char c)
    {
        this->field = 10;

        return *this;
    }
    
};

class B:public A
{
    int field2;
};

void main()
{
    B obj, obj2;

    obj = obj2;

    obj = 'c';
}


Первый перегруженный оператор для 
Код

obj = obj2;

успешно вызывается.

На 
Код

obj = 'c';

Выдает ошибку
Цитата

error C2679: binary '=' : no operator found which takes a right-hand operand of type 'char' (or there is no acceptable conversion)

В чем проблема ?

Автор: Annihilator 7.12.2008, 20:02
Цитата(Antarn @  7.12.2008,  22:52 Найти цитируемый пост)

Первый перегруженный оператор для 
   
obj = obj2;

успешно вызывается.

 С чего ты взял, что вызывается именно перегруженный оператор? Это вызывается оператор присваивания по умолчанию, который создают побитовые копии объектов (не веришь - пройдись дебаггером). А проблема вся в том что ты перегрузил операторы для класса A, а пытаешься их использовать для класса B

Автор: J0ker 7.12.2008, 20:02
операторы, конструкторы и деструкторы не наследуются
в первом случае вызывается оператор предка и дефолтный shallow-copy operator=
и надо писать так:
Код

A& operator=(const A& obj)


Добавлено @ 20:06
Цитата(Annihilator @  7.12.2008,  20:02 Найти цитируемый пост)
который создают побитовые копии объектов

побитовые копии только для PODS
для классов вызывается operator= для предка и каждого мембера класса

Автор: Antarn 7.12.2008, 20:36
Цитата("Annihilator")

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

Добавил в перегрузку cout и смотрел в консоль smile

Цитата("J0ker")

в первом случае вызывается оператор предка и дефолтный shallow-copy operator=

По аналогии подумал что также вызовется оператор предка (для первого же вызвал).

Спасибо за ответы  smile 

Автор: Annihilator 7.12.2008, 21:04
Цитата(J0ker @  8.12.2008,  00:02 Найти цитируемый пост)
побитовые копии только для PODS
для классов вызывается operator= для предка и каждого мембера класса

А можно, пожалуйста, кодом проиллюстрировать. Пока не очень въехал (различия POD и не-POD знаю)

Автор: J0ker 7.12.2008, 23:05
Цитата(Annihilator @ 7.12.2008,  21:04)
Цитата(J0ker @  8.12.2008,  00:02 Найти цитируемый пост)
побитовые копии только для PODS
для классов вызывается operator= для предка и каждого мембера класса

А можно, пожалуйста, кодом проиллюстрировать. Пока не очень въехал (различия POD и не-POD знаю)

Код

class A
{
public:
    A &operator=(const A &aa) {
        cout << "A=" << endl;
        return *this;
    }
};


class C
{
public:
    C &operator=(const C &a) {
        cout << "C=" << endl;
        return *this;
    }
};

class B: public A
{
public:
    C c;
};



B b1, b2;
b1 = b2;


Автор: Antarn 7.12.2008, 23:05
Вопрос вдогонку - как вызвать оператор перезагрузки класса А из метода перезагрузки класса B ?

Я сделал так:
Код

    B& operator = (char c)
    {
        A::operator=(c);

        return *this;
    }

Но правильно ли это ? Не может ли наследник класса А вызывать его как-то по-другому ?

Автор: J0ker 8.12.2008, 03:14
Цитата(Antarn @  7.12.2008,  23:05 Найти цитируемый пост)
Я сделал так:

ну все прально

Автор: Kallikanzarid 8.12.2008, 08:54
Antarn, можно проще:

Код

class B {
public:
    using A::operator=;
};

Автор: UnrealMan 8.12.2008, 12:56
Цитата(J0ker @  7.12.2008,  20:02 Найти цитируемый пост)
операторы, конструкторы и деструкторы не наследуются

Страуструп не прав smile - оператор присваивания наследуется.

Автор: J0ker 8.12.2008, 17:54
Цитата(UnrealMan @ 8.12.2008,  12:56)
Цитата(J0ker @  7.12.2008,  20:02 Найти цитируемый пост)
операторы, конструкторы и деструкторы не наследуются

Страуструп не прав smile - оператор присваивания наследуется.

так-же как конструкторы и деструкторы  smile 
иначе мне твоя мысль не ясна

Добавлено через 8 минут и 27 секунд
Цитата(J0ker @  7.12.2008,  20:02 Найти цитируемый пост)
операторы, конструкторы и деструкторы не наследуются

о, вот тут упс
операторы присваивания имелось ввиду

Автор: UnrealMan 8.12.2008, 23:07
Цитата(J0ker @  8.12.2008,  17:54 Найти цитируемый пост)
иначе мне твоя мысль не ясна

Цитата(10/1)
The base class members are said to be inherited by the derived class.

Цитата(13.5/6)
Operator functions are inherited in the same manner as other base class functions.

Если моя мысль тебе до сих пор не ясна, попробуй, руководствуясь стандартом, выяснить, является ли класс D в примере ниже

Код
struct B
{
    virtual B &operator =(const B &) = 0;
};

struct D : B
{
};

struct DD : D
{
    virtual B &operator =(const B &) { return *this; }
    void f() {}
};

int main()
{
    DD dd;
    D &rd = dd;
    dynamic_cast<DD &>(rd).f(); // well-formed only if D is polymorphic
    D d;                        // ill-formed if D is abstract
}

1) полиморфным
2) абстрактным.

Автор: J0ker 9.12.2008, 03:15
Цитата(UnrealMan @  8.12.2008,  23:07 Найти цитируемый пост)
1) полиморфным

да

Цитата(UnrealMan @  8.12.2008,  23:07 Найти цитируемый пост)
2) абстрактным. 

да

потерто потерто потерто


все понял
спасибо  smile 
полностью с тобой согласен
был не прав

ЗЫЖ то, что потер - не въехал, что implicit оператор присваивания скрывает все остальные - отсюда и кажущаяся разность поведения  smile 

Автор: J0ker 9.12.2008, 03:45
Цитата(Antarn @ 7.12.2008,  18:52)
Здравствуйте.

Объясните, в чем ошибка перегрузки оператора = с параметром char ?
Код

class A
{
public:
    int field;

    A()
    {
        field = 0;
    }

    A& operator = (A& obj)
    {
        this->field = obj.field;

        return *this;
    }

    A& operator = (char c)
    {
        this->field = 10;

        return *this;
    }
    
};

class B:public A
{
    int field2;
};

void main()
{
    B obj, obj2;

    obj = obj2;

    obj = 'c';
}


Первый перегруженный оператор для 
Код

obj = obj2;

успешно вызывается.

На 
Код

obj = 'c';

Выдает ошибку
Цитата

error C2679: binary '=' : no operator found which takes a right-hand operand of type 'char' (or there is no acceptable conversion)

В чем проблема ?

в связи с поправкой UnrealMan'a  smile 

operator= наследуется, но при отсутствии operator= в классе наследника существует implicit operator=, который и скрывает унаследованный
пример:

Код

struct B
{
    void foo(char c) {}
};

struct D: B
{
    void foo() {}
};

int main()
{
    D d;
    d.foo('A');

    return 0;
}

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)