Как скопировать структуру в c / c ++? - PullRequest
0 голосов
/ 07 сентября 2010
DECLARE_PTR(VIDEOINFOHEADER, pvi, pmt->AllocFormatBuffer(sizeof(VIDEOINFOHEADER)));
ZeroMemory(pvi, sizeof(VIDEOINFOHEADER));

//initialize Vih
VIDEOINFOHEADER Vih;
Vih.aaa = xxx;
Vih.bbb = yyy;
...
//now how to copy the value of Vih to pvi?

Кто-нибудь знает?

Ответы [ 3 ]

2 голосов
/ 07 сентября 2010

Вы должны быть в состоянии сделать простое назначение:

*pvi = Vih;

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

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

Возможно, вам также следует использовать new для выделения pvi, иотсюда и конструктор;почти наверняка вы не должны использовать ZeroMemory() для удаления вновь выделенной переменной.Ваш языковой тег 'C ++ `;код подсказывает (не очень хорошо написано) мышление на C - не мышление на C ++.

Если вы дизайнер классов, вам необходимо рассмотреть некоторые основы проектирования классов.


Какие классы могут быть скопированы с помощью присваивания?

Два набора классов могут быть скопированы с помощью присваивания без страха.

  1. Классы, содержащие простые не указательные элементы данных - POD или 'классы простых старых данных.Эти классы могут использовать оператор присваивания, созданный компилятором.Как только у вас появятся указатели, вы должны начать беспокоиться.Однако, если в классе есть (не POD) члены, которые имеют действительный оператор присваивания, вы все равно можете использовать оператор присваивания по умолчанию, созданный компилятором.

  2. Классы с правильносозданный оператор присваивания.Здесь разработчик класса решает все вопросы, связанные с созданием копии данных, дублированием выделенной памяти или использованием счетчиков ссылок и методов копирования при записи (CoW) для минимизации работы.Такие классы также имеют правильно созданный конструктор копирования - и почти всегда деструктор.Классы предназначены для упрощения выполнения присваивания и передачи значений в функции и т. Д.

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

0 голосов
/ 07 сентября 2010

В C ++ вы можете просто присвоить одну структуру другой:

*pvi = Vih;

В C вы бы использовали memcpy

memcpy(pvi,&Vih,sizeof(VIDEOINFOHEADER));

В вашем конкретном случае, почему вы инициализируетепромежуточный объект Vih?

После того, как вы объявили и присвоили указатель pvi, вы можете просто пойти

pvi->aaa = xxx;
pvi->bbb = yyy; 
...

и так далее, чтобы инициализировать videoinfoheader.Если этот синтаксис -> обременителен, вы можете создать временную ссылку на указанные данные:

DECLARE_PTR(VIDEOINFOHEADER, pvi, pmt->AllocFormatBuffer(sizeof(VIDEOINFOHEADER)));
ZeroMemory(pvi, sizeof(VIDEOINFOHEADER));

//initialize pvi, using a temporary reference that allows the convenient . notation
VIDEOINFOHEADER& Vih = *pvi;
Vih.aaa = xxx;
Vih.bbb = yyy;
...
// pvi is now initialized as pvi and Vih are both referencing the same memory, just
// using different syntaxes.
0 голосов
/ 07 сентября 2010

Вы используете Windows API из C ++. Это возможно, но вы должны понимать тонкие риски, с которыми вы столкнетесь.

Многие Windows API используют простые структуры, и это не исключение. Структура VIDEOINFOHEADER - это просто последовательность простых членов. Вам не нужен сложный синтаксис. Следующий код понятнее:

  VIDEOINFOHEADER *pvi = pmt->AllocFormatBuffer(sizeof(VIDEOINFOHEADER));
  // Equivalent to
  // DECLARE_PTR(VIDEOINFOHEADER, pvi, pmt->AllocFormatBuffer(sizeof(VIDEOINFOHEADER)));
  ZeroMemory(pvi, sizeof(VIDEOINFOHEADER));

  pvi->rcSource.left = 5; // etcetera. You can directly assign to pvi->
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...