Найти список переменных-членов класса и их типы? - PullRequest
7 голосов
/ 17 июня 2011

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

class A
{
 public:
  SomeOtherClass* s;
  int i;
  int j;
  A() {}
  A(const A& soc): s(soc.s->Clone()), i(soc.i), j(soc.j) {}
};

Я всегда должен помнить, чтоесли я добавлю еще одну переменную int k в класс, мне также придется добавить ее в список инициализации k(soc.k), а иногда и в деструктор.Мне приходилось добавлять / удалять переменные-члены так много раз, и очень неприятно забывать о копировании в списке инициализации и обнаружении упущения намного позже при отладке.

Поэтому я хотел бы знать, есть ли синтаксис / логика, с помощью которой я могу узнать список переменных-членов класса и их типов, так что я могу, возможно, перебрать их и решить, какая из них нужнабыть скопированы в копию ctor и какие из них нужно глубоко копировать?

Я не понимаю, почему создатели C ++ не могли включить такую ​​возможность, поскольку, за исключением виртуальных членов, ячейки памяти переменных были бы смежными, и их типы также известны.Даже если бы они были внешними или виртуальными, тип и размер были бы известны во время выполнения.Так не должно ли это быть возможно?

Ответы [ 5 ]

12 голосов
/ 17 июня 2011

В C ++ нет отражения, поэтому для этого вам понадобится внешняя библиотека. Создатели C ++ не реализовали эту функцию, поскольку она подразумевает снижение производительности, а производительность является одной из основных целей C ++.

3 голосов
/ 17 июня 2011

Я всегда должен помнить, что если я добавлю еще одну переменную int k в класс, мне также придется добавить ее в список инициализации k (soc.k), а иногда и в деструктор.

Да, вы делаете.

Мне приходилось так много раз добавлять / удалять переменные-члены, и очень досадно забывать о копировании в списке инициализации и поискеупущение намного позже при отладке.

Да, это так.

Поэтому я хотел бы знать, есть ли синтаксис / логика, с помощью которой я могу узнать список переменных-членов класса иих типы, так что я могу, возможно, перебрать их и решить, какие из них должны быть скопированы в ctor копирования, а какие из них должны быть глубоко скопированы?

Нет, нет.

Я не понимаю, почему создатели C ++ не могли включить такую ​​возможность, поскольку, за исключением виртуальных членов,ячейки памяти переменных были бы смежными, и их типы также известны.Даже если бы они были внешними или виртуальными, тип и размер были бы известны во время выполнения.Так разве это не должно быть возможно?

Да, в идеале.

C ++ на самом деле не "такой язык", но - aнемного боли.

2 голосов
/ 17 июня 2011

пожалуйста, проконсультируйтесь http://yosefk.com/c++fqa/defective.html#defect-6

за точку зрения по теме.

и, как ответ, в принципе, вы не можете этого сделать.

1 голос
/ 17 июня 2011

Да, это не отвечает на ваш вопрос, но для решения вашей проблемы то, что я сделал в своем коде, - это использование структуры для хранения элементов, которые можно автоматически копировать, чтобы мне не приходилось беспокоиться о них.

class A
{
 public:
  SomeOtherClass* s;

  class Members
  {
    int i;
    int j;
  };

  Members m;

  A() {}
  A(const A& soc): s(soc.s->Clone()), m(soc.m) {}

  void f() {
    m.j;//use j
  }
};

Но обычно я предпочитаю использовать указатели deep_copy, чтобы мне даже не понадобился этот трюк (указатель также копируется автоматически, когда я могу).

Я писал об этом некоторое время назад: https://stackoverflow.com/questions/469696/what-is-your-most-useful-c-c-utility/1609496#1609496.

Я не уверен, что это решит вашу проблему с деструктором (возможно, указатель deep_copy).

Если вам интересно, я также предлагаю проверить сообщения, которые говорили о членстве здесь, в stackoverflow, который в основном использовал такой же трюк для других средств, если я правильно помню.

0 голосов
/ 17 июня 2011

Как уже отмечалось, в C ++ нет отражения. Одна простая вещь, которую вы могли бы сделать, это проверить размер класса. Это может, по крайней мере, заставить вас взглянуть на правильное местоположение, сгенерировав сообщение об ошибке, если вы забудете обновить размер после добавления члена.

Пример:

template<size_t Real, size_t Expected> struct check_size;
template<size_t Size> struct check_size<Size, Size> {};
// ...
A(const A& soc): s(soc.s->Clone()), i(soc.i), j(soc.j) {check_size<sizeof(A), 24> size_checker;}
...