Не могу перегрузить оператор << для своего класса - PullRequest
0 голосов
/ 02 января 2019

Я пытаюсь уменьшить избыточность кода, используя перегрузку оператора вывода в поток вместо функций печати. ​​

//***.h
class MainWind : public QWidget
{
    Q_OBJECT

public:
    explicit MainWind(QWidget *parent = nullptr);
    ~MainWind();
    MainWind *operator<<(const QString &str);
private:
    Ui::MainWind *ui;
};

//***.cpp
MainWind *MainWind::operator<<(const QString &str)
{
    ui->serverConsole->insertPlainText(str);
    return this;
}

В этот момент все успешно компилируется.

Но когда япопробуйте использовать:

//other.cpp
MainWind *mainWind  = new MainWind;
mainWind << QString("str");

Я получил эту ошибку:

ServerSocket.cpp: 39: ошибка: недопустимые операнды для двоичного выражения ('MainWind *' и 'QString')qstring.h: 1410: функция-кандидат недопустима: нет известного преобразования из> 'MainWind *' в 'QDataStream &' для 1-го аргумента

...

И кандидатов многодля этой позиции)

Или

//other.cpp
MainWind *mainWind  = new MainWind;
mainWind <<"str";

Я получил эту ошибку:

ServerSocket.cpp: 39: ошибка: недопустимые операнды для двоичного выражения('MainWind *' и 'const char [4]') ServerSocket.cpp: 39: ошибка: недопустимые операнды типов 'MainWind *' и 'const char [4]' в двоичный оператор '<<' CurrentSession :: inst () .mainWind () << "str"; </p>

                                                  ^

В чем может быть проблема?

ДОПОЛНЕНИЕ К ЭТОМУ ЦВESTION:

Попытка использовать:

//*.h
friend MainWind *operator<<(MainWind *out,QString &str);

//***.cpp
MainWind * operator<<(MainWind *out, QString &str)
{
    out->ui->serverConsole->insertPlainText(str);
    return out;
}

Компиляция предыдущего кода успешна.

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

Но при использовании этого:

//other.cpp
MainWind *mW = new MainWind;
mW << "str";

Компиляция перейдет к ошибке:

ServerSocket.cpp: 37: ошибка: недействительнаоперанды типов 'MainWind *' и 'const char [4]' to binary 'operator <<' mW << "str"; </p>

                ^

Ответы [ 3 ]

0 голосов
/ 02 января 2019

Вам нужно использовать *mainWind << QString("str");.LHS должен быть объектом, а не указателем.

При этом я настоятельно рекомендую изменить функцию operator<<, чтобы она возвращала ссылку на объект, а не указатель.

MainWind& operator<<(const QString &str);

и реализация до

MainWind& MainWind::operator<<(const QString &str)
{
    ui->serverConsole->insertPlainText(str);
    return *this;
}

Это позволит вам связать оператора в цепочку.

*mainWind << QString("str") << QString("Second string");
0 голосов
/ 02 января 2019
//other.cpp
MainWind *mainWind  = new MainWind;
mainWind <<"str";

Причина в том, что mainWind << "str" ищет operator<<(), который принимает два аргумента, первый из которых - MainWind *.

Принимая во внимание, что вы определили MainWind::operator<<(), который вызывается с первым аргументом MainWind &. Нет прямого преобразования из MainWind * в MainWind & (или в MainWind). Отсюда и сообщение об ошибке.

Один из способов получить код для компиляции - изменить mainWind <<"str" на *mainWind << "str". * разыменовывает указатель и выдает ссылку, чего и ожидает ваш operator<<().

Подвох в том, что

*mainWind << "str" << "another str";

не скомпилируется, поскольку эквивалентно

(*mainWind).operator<<("str") << "another str";

, где (*mainWind).operator<<("str") возвращает MainWind *. Это вызывает ту же проблему (снова) при попытке потоковой передачи "another str".

Реальное исправление заключается в изменении operator<<(), чтобы он возвращал ссылку

//  within the class definition of MainWind

MainWind &operator<<(const QString &str);

// definition of the operator<<()

MainWind &MainWind::operator<<(const QString &str)
{
    ui->serverConsole->insertPlainText(str);
    return *this;
}

и измените код вызова на

//other.cpp version 2

MainWind *mainWind  = new MainWind;
*mainWind <<"str";

// this will work too

*mainWind << "str" << "another str";  

//   note reliance on cleaning up mainWind to avoid a memory leak

delete mainWind;   

Нет другого исправления, позволяющего использовать mainWind << "str", поскольку перегрузка не-члена operator<<() разрешена только для классов или перечислимых типов, но не для указателей.

0 голосов
/ 02 января 2019

Вы перегружены << на MainWnd не MainWnd*.

*mainWind << QString("str");

Также вы хотите QString const&

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