Я просматривал исходный код, пытаясь узнать больше о C ++, и наткнулся на некоторый код, который выглядел запутанным. Я не смог понять его использование, поиграв с ним.
Может кто-нибудь объяснить, что делает оператор float * () и как он используется?
Вектор класса
{
общественности:
float x, y, z;
Vector() : x(0), y(0), z(0){
}
Vector( float x, float y, float z ) : x(x), y(y), z(z){
}
operator float*(){
return &x;
}
operator const float *(){
return &x;
}
Я искал StackOverflow, и похоже, что это оператор преобразования, но я все еще не уверен, что он на самом деле делает и почему это полезно.
С уважением,
operator type_name
объявляет неявное преобразование оператор. Другими словами, эта функция вызывается, когда вы пытаетесь (неявно) преобразовать объект вашего типа в float*
— например, в задании:
Vector x(1, 2, 3);
float* f = x;
assert(*f == 1);
Излишне говорить, что это конкретное преобразование довольно ужасно, потому что его эффект довольно неинтуитивен и легко приводит к невозможности найти ошибки. Неявные преобразования, как правило, должны обрабатываться с осторожностью, поскольку они скрывают потенциально запутанную семантику. Но они могут быть отлично использованы с типами, которые должны использоваться взаимозаменяемо и где преобразование не повредит.
Например, рассмотрим случай, когда вы пишете свой собственный integer
а также complex
классы. Конверсия из integer
в complex
безвреден, так как каждое целое число является действительным комплексом (но не наоборот). Таким образом, имея неявное преобразование integer
→ complex
безопасно.
Как уже было сказано, это оператор преобразования, который преобразует объект типа Vector
к объекту типа float *
, Этот оператор преобразования может быть вызван неявно, потому что у него нет спецификатора функции explicit
,
Я думаю, что идея введения этого оператора состояла в том, чтобы получить доступ к элементам данных x, y, z в виде массива с плавающей точкой. В этом случае вы можете применить некоторые стандартные алгоритмы к объекту класса, преобразовав его в массив с плавающей точкой.
Учтите, что вторая перегруженная оператор-функция должна иметь квалификатор const.
Рассмотрим следующий код
#include <iostream>
#include <algorithm>class Vector
{
public:
float x,y,z;Vector() : x(0), y(0), z(0){
}
Vector( float x, float y, float z ) : x(x), y(y), z(z){
}
operator float*(){
return &x;
}
operator const float *() const {
return &x;
}
};
int main()
{
Vector v( 1, 3, 2 );
auto max = std::max_element( v + 0, v + 3 );
std::cout << *max << std::endl;
return 0;
}
Выход 3.
Учтите, что в соответствии со стандартом C ++
13 Нестатические члены данных (не объединяющего) класса с одинаковым доступом
управления (п. 11) распределяются так, чтобы более поздние члены имеют выше
адреса внутри объекта класса
Таким образом, порядок данных членов класса определен.
Это оператор преобразования, позволяющий использовать класс с API, которые хотят float*
. У вас есть две разные версии, потому что одна преобразует класс в const float*
а другой неconst
, Хотя оператор неконстантного преобразования нарушает инкапсуляцию вашего класса.
Полезность: Ну, это может быть очень удобно, когда, как я уже говорил, вы хотите работать с библиотекой, которая ожидает определенный тип. Это также может быть полезно при естественном преобразовании между двумя типами.