Как исправить 'Cannot конвертировать' Tmp 'в' float 'при инициализации - PullRequest
0 голосов
/ 20 июня 2019

В настоящее время я изучаю перегрузку операторов и хочу перегрузить как operator<< (чтобы отобразить все элементы свойства tab моего класса), так и operator[] (чтобы получить и установить отдельные элементы этого массива).

Я пытался снять перегрузку operator<<, но это ничего не изменило.

#include <iostream>
#include <string>
using namespace std;

class Tmp{
private:
    float *tab;
    int size,elemCount = 0;
public:
    Tmp(int size,float element = 0.0f){
        this -> size = size;
        tab = new float[size];
        for(int i = 0;i < size;i ++){
            tab[i] = element;
            elemCount++;
        }
        this -> tab = tab;
    }


    const float& operator[] (const int count) const;
    friend ostream& operator << (ostream& os, const Tmp* obj);


    ~Tmp(){
        delete[] tab;
    }
};

ostream& operator << (ostream& os, const Tmp* obj){
        os << "Wartości tablicy:" << endl;
        for(int i=0;i<obj->size;i++){
            os<<obj->tab[i]<<endl;
        }
        return os;
}

const float& Tmp::operator[] (const int count) const {
    return tab[count];
}

int main() {
    cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
    Tmp *a = new Tmp(2);
    cout<<a<<endl;

    float b = a[0]; //error here
    //cout<<b<<endl;

    return 0;
}

Ожидаемым выводом будет присвоение переменной первого значения массива табуляции b, но вместо этого я получаю ошибку «не могу преобразовать Tmp» в «float» при инициализации ».

1 Ответ

1 голос
/ 21 июня 2019

В заявлении

float b = a[0];

a - это указатель Tmp*, поэтому a[0] совпадает с *(a+0). Вы вообще не вызываете перегруженный operator[], вы просто вызываете арифметику и разыменование указателя, поэтому вы действительно присваиваете объект Tmp для переменной float, отсюда и ошибка.

Вам нужно разыменовать указатель перед вызовом оператора:

float b = (*a)[0];

Или вы можете вызвать оператор напрямую, как и любой другой метод класса:

float b = a->operator[](0);

Лучшее решение - просто вообще не использовать указатель, тем более что вы все равно протекаете объект Tmp (вы не вызываете delete a;):

Tmp a(2);
float b = a[0];

Кроме того, перегруженный operator<< должен принимать объект Tmp по ссылке, а не по указателю.

Попробуйте это:

#include <iostream>
#include <string>
using namespace std;

class Tmp{
private:
    float *tab;
    int size, elemCount = 0;
public:
    Tmp(int size, float element = 0.0f){
        this->size = size;
        tab = new float[size];
        for(int i = 0; i < size; ++i){
            tab[i] = element;
            ++elemCount;
        }
    }

    ~Tmp(){
        delete[] tab;
    }

    const float& operator[] (const int count) const;
    friend ostream& operator << (ostream& os, const Tmp& obj);
};

ostream& operator << (ostream& os, const Tmp& obj){
    os << "Wartości tablicy:" << endl;
    for(int i = 0; i < obj.size; ++i){
        os << obj.tab[i] << endl;
    }
    return os;
}

const float& Tmp::operator[] (const int count) const {
    return tab[count];
}

int main() {
    cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
    Tmp a(2);
    cout << a << endl;

    float b = a[0];
    //cout << b << endl;

    return 0;
}

Также обратите внимание, что ваш класс Tmp не соответствует правилу 3/5/0 , так как в нем отсутствует конструктор копирования и оператор назначения копирования, чтобы обеспечить содержание вашего tab массивы правильно копируются между Tmp объектами.

Лучшее решение - использовать std::vector вместо new[] и позволить компилятору управлять памятью:

#include <iostream>
#include <string>
#include <vector>
using namespace std;

class Tmp{
private:
    vector<float> tab;
public:
    Tmp(int size, float element = 0.0f)
        : tab(size, element)
    {
    }

    const float& operator[] (const int count) const;
    friend ostream& operator << (ostream& os, const Tmp& obj);
};

ostream& operator << (ostream& os, const Tmp& obj){
    os << "Wartości tablicy:" << endl;
    for(size_t i = 0; i < obj.tab.size(); ++i){
        os << obj.tab[i] << endl;
    }
    return os;
}

const float& Tmp::operator[] (const int count) const {
    return tab[count];
}

int main() {
    cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
    Tmp a(2);
    cout << a << endl;

    float b = a[0];
    //cout << b << endl;

    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...