Optimistic76 Ответов: 4

С++ перегрузка оператора =


Всем привет,

У меня есть к вам вопрос о перегрузке operator = для производных классов.
Предположим, например, что два класса A, B определены следующим образом:

class A
{
protected:
	double v_;

public:

	A(double initVal = 0.0)
	: v_(initVal)
	{}

	virtual ~A() {}
	
	double v() 
        {
	   return v_;
	}

	void v(double val) { v_ = val; }


	A& operator=(A& src)
	{
	   this->v(src.v());
	}

};


//defining sum 
A operator+(A& add1, A& add2)
{
	A res;
	res.v(add1.v() + add2.v());
	return res;
}


class B : public A
{
public:

	B(double initVal = 0.0)
		: A(initVal)
	{}

	virtual ~B() {}

	B(B& src)
		: A(src.v())
	{}
	
	B(A& src)
		: A(src.v())
	{}


	B& operator=(B& src)
	{
		B res;
		res.v(src.v());
		return res;
	}

	B& operator=(A& src)
	{	
		B res;
		res.v(src.v());
		return res;
	}
};


теперь если я отлажу следующие строки:

A a(1.0);
B b(2.0);	
B c;
//first Assignemnt
c = a;
//second assignment
c = a + b;


я вижу что оба задания проходят через это

B& B::operator=(A& src)


Теперь, если я изменю

B& operator=(B& src)


к

B& operator=(B src)


второе задание (с суммой) проходит через этот оператор.

Кто-нибудь может объяснить, почему это происходит?

спасибо

Что я уже пробовал:

Является ли причина такого поведения неявным приведением?

4 Ответов

Рейтинг:
36

tra_la_la_la

Сделайте конструктор

B(A& src)
явный.
Что-то вроде этого
explicit B(A& src)


Optimistic76

Привет tra_la_la_la,

хорошо, если я сделаю явным конструктор, то оба назначения пройдут через B::operator=(A&), но я хотел бы знать, какова логика этого.
Почему считается, что A a каким-то образом отличается от объекта, который возвращает оператор сложения?

Рейтинг:
2

Jochen Arndt

Я не проверял ваш код и то, что он делает, потому что он не реализует операторы присваивания обычным способом. Они должны возвращать не копию, а сам объект (обратите внимание также, что оператор в вашем классе A возвращается ничего).

Так и должно быть:

class A
{
    // ...
    double v() const
    {
        return v_;
    }
    
    A& operator=(const A& src)
    {
        this->v(src.v());
        return *this;
    }

    // This is missing in your code and should be there
    friend A operator+(const A& add1, const A& add2);
};

A operator+(const A& add1, const A& add2)
{
    // EDIT: Or just (because we are friend, we have direct access to the members)
    return A(add1.v_ + add2.v_);
    //A res;
    //res.v(add1.v() + add2.v());
    //return res;
}

class B
{
    // ...
    B& operator=(const B& src)
    {
        this->v(src.v());
        return *this;
    }
     
    B& operator=(const A& src)
    {	
        this->v(src.v());
        return *this;
    }
};
Обратите также внимание, что параметры должны быть const и так же должна быть функция геттера v().


Рейтинг:
2

CPallini

Я предлагаю вам взглянуть на эту страницу: Конструкторы копирования, операторы присваивания, - статьи на языке C++ [^].