#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);
}