Оператор C ++ << распечатать адрес объекта - PullRequest
1 голос
/ 03 апреля 2012

Возможно ли иметь класс с перегруженным оператором ostream <<, (как следующий код) распечатать адрес этого экземпляра? </p>

class MyCls {
      friend ostream& operator << (ostream& o, const MyCls& c) { return o << "MyClass\n";  }
      friend ostream& operator << (ostream& o, const MyCls *c) { return operator<<(o, *c); }
};
MyCls a, b;
std::cout << a << b;

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

(0x12345678) MyClass
(0x23456789) MyClass

Есть обходной путь?

[редактировать]

Сценарий

Я пропустил довольно много подробностей о MyCls, чтобы вопрос казался простым. Класс на самом деле имеет векторы указателей на другие классы. Эти классы также имеют операторы ostream, перегруженные аналогичным образом. Поэтому моя основная цель - показать, какие объекты содержатся в каких контейнерах.

class MyClsB {};
class MyCls {std::vector<MyClsB *> containers; std::string attrA;};

class Printer() {
    void operator() (const T& arg) { os << arg;}
    void operator() (T *arg) { os << *arg; }
    }

int main(int c, char** a) {
    std::vector<MyCls *> v;
    //version 1
    for (int i = 0; i < v.size(); i++) std::cout << v[i] << "\n";
        //version 2
        for_each(v.begin(), v.end(); Printer(std::cout));
        return 0;
}

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

(0x12345678) MyCls: attrA = v1
(0x1234abcd) MyClsB
(0x1234defg) MyClsB
(0x23456789) MyCls: attrA = v2
(0x2345abcd) MyClsB
...

Платформа

  • Win 7x64: VS2010 express
  • Linux: gcc 4.4.5

[Edit 1]: я попробовал метод Бенджамина, и он просто дает мне ошибку сегментации. Добавление отладочной печати показывает, что метод Бенджамина просто заходит в бесконечный цикл.

[Edit 2]: По предложению Джерри мой компилятор жалуется на «недопустимый static_cast типа« const MyCls * »на тип« void * »» (gcc 4.4.5)

[Правка 3]: Удаление указателя-версии оператора << просто напечатайте адрес, но не более того, что нарушило мою основную цель. Я думаю, это потому, что не объявление версии-указателя будет использовать реализацию по умолчанию, которая просто печатает только адрес. </p>

Почему я объявляю указатель-версию, чтобы упростить оператор вызова. Вместо

std::cout << *p2Obj

только

std::cout << p2Obj

Кроме того, у меня есть объект функтора, который используется для объединения с вызовами for_each () мой предыдущий вопрос

Ответы [ 4 ]

3 голосов
/ 03 апреля 2012

Я думаю, что сделал бы эту работу немного иначе, чем я видел в ответах до этого - я бы явно передал адрес в void * перед печатью:

std::ostream &operator<<(std::ostream &os, MyCls const &object) { 
    return os << "(" << static_cast<void const *>(&object) << ") MyClass\n";
}

Мне обычно не нравятся приведения, но в этом случае я думаю, что стоит пояснить, что вы намерены распечатать адрес, чтобы кто-то не принял его за ошибку / несчастный случай.

3 голосов
/ 03 апреля 2012

Конечно

ostream& operator << (ostream& o, const MyCls& c)
{
    return o << "(" << &c << ") MyClass\n";
}
2 голосов
/ 03 апреля 2012

Есть много проблем с вашим примером кода, но это очень легко сделать и нет необходимости в друзьях:

#include <iostream>

class MyCls {
};

std::ostream& operator<<(std::ostream& out, MyCls& instance) {
  return out << "MyCls" << &instance;
}

достаточно.

1 голос
/ 03 апреля 2012

Почему бы просто:

class MyCls {
   friend ostream& operator << (ostream& o, const MyCls& c) 
                  { return o << "MyClass\n" << &c;  }
};

использование:

MyCls a, b;
std::cout << a << b;
...