Мне нужно сделать размер массива, определенный внутри класса, как зависящее от ситуации значение. Чтобы пояснить суть, следующий код с фиксированным размером массива не показывает ошибки
class CMinimalServer : public GBDataAccess
{
public:
DWORD IdG[30];
VARIANT Value[30];
WORD Quality[30];
FILETIME Timestamp[30], ft;
HRESULT Error[30];
Но мне нужно сделать размер массива, который в этом случае равен 30, в качестве надежного значения. Под этим я хочу сказать, что предположим, что в другой части кода у меня есть
if (a==b)
Number = 10;
else
Number = 30;
Размер массива должен быть соответственно 10 и 30.
Но следующий код показывает ошибку
class CMinimalServer : public GBDataAccess
{
public:
DWORD IdG[Number ];
VARIANT Value[Number ];
WORD Quality[Number ];
FILETIME Timestamp[Number ], ft;
HRESULT Error[Number ];
Я пытался
#define Number 16
наверху, а приведенный выше код не показал ошибки, но проблема в том, что я не могу изменить переменную в другой части кода
////Некоторые проблемы в решении
Я изменил код в соответствии с предложением: мне нужно делать функции внутри класса (createTag).
// Class definition
class CMinimalServer : public GBDataAccess
{
public:
struct Entry
{
DWORD IdG;
VARIANT Value;
WORD Quality;
FILETIME Timestamp;
HRESULT Error;
};
private:
FILETIME ft;
void createTag()
{
DWORD ids[NumberOfPoints],i;
VARIANT val;
val.vt = VT_BOOL;
unsigned c=0;
for (i = 0; i<NumberOfPoints; i++)
{
wchar_t opcid[NumberOfPoints];
wsprintfW(opcid, L"Item%02i", i+1);
val.boolVal = VARIANT_FALSE;
srv.GBCreateItem(&ids[i], i, opcid, OPC_READABLE|OPC_WRITEABLE, 0, &val);
Entry.IdG[c] = ids[i];
Value[c].vt= VT_BOOL;
c++;
}
.....
}
//Main function
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
CMinimalServer() = default;
CMinimalServer(int number) : tab_(number){};
std::vector<Entry> tab_ = std::vector<Entry>(30);
}
Проблемы:
Ошибка Entry.idG [c].
У нас есть вектор в C++
#include <vector>
class CMinimalServer : public GBDataAccess {
public:
struct Entry {
DWORD IdG;
VARIANT Value;
WORD Quality;
FILETIME Timestamp;
HRESULT Error;
};
CMinimalServer() = default;
CMinimalServer( int number ) : tab_(number) {};
private:
FILETIME ft;
std::vector<Entry> tab_ = std::vector<Entry>(30);
};
Разумеется, вы можете использовать вектор для каждого отдельного значения, если они вам нужны, и доступ к базовому указателю с помощью variable.data()
Entry
не должно быть векторов для каждого члена для репликации образца OP? Или вообще не указывать, и заменить массивы на std::vector<>
.
Если number
должен быть определен во время выполнения, то решение этой проблемы заключается в определении вашего класса, как:
class CMinimalServer : public GBDataAccess
{
public:
DWORD* IdG;
VARIANT* Value;
WORD* Quality;
FILETIME* Timestamp;
FILETIME ft;
HRESULT* Error;
CMinimalServer(int number)
{
IdG = new DWORD[number];
Value = new VARIANT[number];
... etc
}
~CMinimalServer()
{
delete[] IdG;
delete[] Value;
... etc
}
}
std::vector
, а не указатели. Но если он собирается использовать указатели: в этом случае они должны быть умными указателями. Код, как написано, утечки памяти (и, следовательно, является неправильным).
ISO не допускает массив переменной длины. Однако есть лазейка. Вы можете создать массив с переменной как ее размер во время выполнения с использованием динамической памяти.
Например: int x = 4; int * a = new int [x];
Не забудьте использовать delete!
delete [] a;
Надеюсь, это поможет!
Если вам нужен массив независимых значений const compimeime, используйте std: vector.
Отредактировано: от голых указателей до общих указателей,
Динамическое выделение памяти с помощью указателей сделает это,
class CMinimalServer : public GBDataAccess
{
public:
shared_ptr<DWORD> IdG;
shared_ptr<VARIANT> Value;
shared_ptr<WORD> Quality;
shared_ptr<FILETIME> Timestamp, ft;
shared_ptr<HRESULT>* Error;
Затем внутри конструктора присвойте им память (определите размер массива), как это
CMinimalServer::CMinimalServer()
{
IdG = new DWORD(Number);
Value = new VARIANT(Number);
Quality = new WORD(Number);
Timestamp = new FILETIME(Number);
}
unique_ptr
.
new DWORD(Number)
Это совершенно неправильно, если вы хотите выделить массив, используйте new DWORD[Number]
... И нет смысла использовать массивы в этом контексте, когда возможно использовать std :: vector, особенно поскольку существует необходимость динамически расширять массивы.
std::vector
?