Попытка перегрузить оператор cout <<, но он не работает - PullRequest
1 голос
/ 31 января 2012

Я вырвал не относящиеся к делу части из моего класса здесь.Я не знаю, что я делаю неправильно, просто пытаюсь найти << объект. </p>

#include <iostream>

class Snipped
{

    public:
        friend std::ostream& operator<<(std::ostream& os, const Snipped& s);

    protected:
    private:
};

std::ostream& operator<<(std::ostream& os, const Snipped& s)
{
    os << "test";
    return os;
}

int main(int argc, char* argv[])
{
    Snipped* s = new Snipped();

        std::cout << s << std::endl << s;

    delete s;
    return 0;
}

Ожидаемый результат:

test
test

Фактический результат:

0x12ae20
0x12ae20  (random memory location?)

Ответы [ 3 ]

8 голосов
/ 31 января 2012
std::cout << s << std::endl << s;      

Вы звоните << с адресом, вам нужно вызвать его с объектом типа Snipped.
Строка кода выше не будет вызывать вашу перегруженную операторную функцию, потому что параметрыперегруженные функции не совпадают.

Вам нужно позвонить:

std::cout << *s << std::endl << *s;      

Это обеспечивает вызов вашей перегруженной функции оператора <<, поскольку параметры соответствуют ей.

6 голосов
/ 31 января 2012

Попробуйте

std::cout << *s << std::endl; 

Кстати,

std::cout << s << std::endl; 

на самом деле не случайная ячейка памяти.

Это фактическаяадрес памяти в куче, в данном случае.

Вы можете фактически использовать этот адрес для проверки личности объекта.

Это полезно при отладке или в действительностикод.Например, если вы посмотрите на операторы присваивания, вы часто увидите:

class Foo
{
  Foo& operator=( const Foo& foo )
  {
    // use the identity principle 
    if ( &foo==this )
      return *this;  // so I don't waste CPU cycles copying to myself

    // ...really do copy here
    return *this;
  }
};
2 голосов
/ 31 января 2012

Хотя при разыменовании указателя (т. Е. При использовании «* s» вместо «s») есть более крупная рыба, которую нужно жарить! Если нет веской причины для помещения объекта в кучу, вы не должны делать это:

int main()
{
    Snipped s;
    std::cout << s << '\n' << s;
}

Я нашел использование new и более того delete довольно редко в программах, которые я пишу. Помимо простого кода это удобно также часто приводит к более быстрым программам. Если вам действительно нужно выделить что-то в куче, используйте какой-нибудь умный указатель, чтобы убедиться, что объект автоматически освобождается:

int main()
{
    std::unique_ptr<Snipped> s(new Snipped);
    std::cout << *s << '\n' << *s;
}

В качестве дополнительного примечания не используйте std::endl, если только вы действительно не собираетесь очищать поток: я обнаружил, что неправильное использование std::endl является основной причиной огромных проблем с производительностью более одного раза. Конечно, в большинстве случаев это не имеет значения, но в еще большем количестве случаев вас не волнует флеш. Если вам не нравится использовать '\n' или "\n", вы можете использовать собственный манипулятор:

std::ostream& nl(std::ostream& out) { return out << '\n'; }

При этом вы можете использовать nl вместо std::endl и не страдать от постоянного сброса потока.

...