Перегрузка оператора = и постоянная ссылка

#c #operator-overloading #constants

#c #перегрузка оператора #константы

Вопрос:

Я пытаюсь создать класс для цветов на C ,
это не домашнее задание, просто я все еще борюсь со ссылками и const .

—Color.h

 class Color{
private:
    double r;
    double g;
    double b;
    double a;
public:
    //constructor, getters and setters...
    Coloramp; operator =(Coloramp; other_color); //(1)
}
  

—Color.cpp

 Coloramp; operator=(Coloramp; other_color){
     this->r = other_color.get_r(); //line 41
     this->b = other_color.get_b();
     //and so on...
     return *this;
}
  

таким образом, это работает нормально, но я слышал, что нужно ввести const, чтобы избежать того, что по ошибке объект будет изменен операцией присваивания, поэтому нужно объявить другой объект как const . Вот так:

 Coloramp; operator =(Color constamp; other_color); //(2)
  

но это дает мне эти ошибки:

 /Users/../color.cpp:41: error: passing 'const Color' as 'this' argument of 'float Color::get_r()' discards qualifiers
  

итак, вот мой вопрос…

что здесь происходит? во-вторых, что произойдет, если я не объявлю other_color как const ? каковы возможные ошибки?

PS .: небольшой бонусный вопрос:
я хочу передать свою переменную в opengl glColor4v(colorx.return_rgba()), возвращающий массив [r,g,b,a] класса Color. Это:

 float* Color::return_rgba(){
    float  rgba[4] = {this->r, this->g, this->b, this->a};
    return rgba;
}
  

не сработает, потому что rgba больше не будет находиться в области видимости после возврата, поэтому он будет удален, и мой указатель будет указывать на неинициализированные адреса, черт возьми…

Комментарии:

1. Я отредактировал вопрос в строке 41, где я поместил комментарий

2. Кстати, вам действительно не нужно перегружать operator= . Это необходимо только в том случае, если вы хотите, чтобы поведение отличалось от назначения по умолчанию.

Ответ №1:

передача ‘const Color’ в качестве ‘этого’ аргумента ‘float Color::get_r()’ отбрасывает квалификаторы

Это означает, что вы должны пойти дальше. get_r вероятно, объявлено как

 float get_r()
  

и чтобы заставить его работать (const-корректно), вы должны сделать это

 float get_r() const
  

во-вторых, что произойдет, если я не объявлю other_color как const ?

Вы не сможете назначить const Color s, квалифицированные из. Обычно вы хотите иметь возможность использовать const объекты, среди прочего, в качестве источника присваивания. Более того, это делает намерение не изменять исходный код понятным для читателя кода.

Я хочу передать свою переменную в opengl glColor4v(colorx.return_rgba()), возвращающий массив [r,g,b,a] класса Color.

Возвращает специальное «транспортное средство», которое будет содержать массив и автоматически преобразовываться в float* . Что-то вроде

 struct ColorQuadruplet
{
  float data_[4];
  // add initialization and such here
  operator float*() { return data_; }
};

ColorQuadruplet Color::get_rgba() const
{
  ColorQuadruplet ret;
  // fill ret
  return ret;
}
  

Комментарии:

1. вы быстры, и я думаю, что вы ответили на вопрос. Это означает, что я должен установить все методы, которые я намерен использовать в постоянной ссылке, как константу ..?

2. ДА. Более того, вам нужны все методы, которые не предназначены для изменения объекта как const .

3. @Pella86 : Да, эта концепция известна как постоянная корректность .

4. отлично! Спасибо! еще один вопрос, если я не использую const … никогда, какие проблемы у меня могут возникнуть?

5. @Pella86: У этого вопроса есть две стороны. (1) Если вы никогда не использовали const ни в одном из источников, которые вы предоставляете своему компилятору, результирующая программа будет вести себя точно так же. Некоторые люди говорят: «Если вы не хотите что-то изменять, вы просто не изменяете это», им не нужен const . Тем не менее, я думаю, что есть возможность использовать систему типов C для полезных целей… поэтому я бы использовал const . (2) Вы не можете избежать использования объектов const в некоторых контекстах … например. std::set предоставляет его содержимое как const объекты.

Ответ №2:

Здесь у вас есть два варианта. Один из них предназначен для operator= прямого доступа к элементам исходного объекта:

 Color amp;operator=(Color const amp;other) { 
    r = other.r;
    g = other.g;
    b = other.b;
    a = other.a;
}
  

Другой (который вы, вероятно, захотите сделать в любом случае, если вы настаиваете на том, чтобы иметь средства доступа для цветовых компонентов вообще) — это настроить параметры доступа, которые вы написали:

 double get_r() const { return r; }
               ^^^^^
  

const Вот часть, которую я добавил, которой у вас, по-видимому, нет.

Редактировать: что касается передачи значений в glColor, я бы рассмотрел небольшой интерфейс, подобный этому:

 gl_color(Color const amp;c) { 
    glColor4d(c.r, c.g, c.b, c.a);
}