如何在 C++ 中分配类内数组的可修改大小

Posted

技术标签:

【中文标题】如何在 C++ 中分配类内数组的可修改大小【英文标题】:How to assign modifiable size of array inside class in C++ 【发布时间】:2014-02-05 09:54:36 【问题描述】:

我需要将类内定义的数组大小设置为与情况相关的值。为了澄清这一点,以下具有固定数组大小的代码显示没有错误

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);

问题是:

    如何在 CreateTag 函数中定义 idG 向量数组。

Entry.idG[c] 显示错误。

    createTag 函数循环中的'NumberOfPoints' 也等于30。如何在main 函数中分配这个值。 如何制作另一个向量数组 ids 。我可以在同一个结构条目中定义它并在 createTag 中调用它吗?

【问题讨论】:

为什么不使用std::vector 【参考方案1】:

我们在 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() 访问底层指针

【讨论】:

是的,它已经在 CMinimalServer 中的向量上,还没有完全醒来^^ 您的 Entry 结构不应该为每个成员提供向量,以复制 OP 的样本吗?或者完全省略,并将数组替换为std::vector&lt;&gt; 关于连续数组和data的评论就是为了这个目的。拆分数组需要更多的工作来保持大小同步,并且只有在有原因(内存缓存性能、遗留 API)的情况下才应该首选。 这允许在问题中未将其说明为所需功能的尺寸修改 @bobah “我需要将类内定义的数组大小设置为与情况相关的值。” OP的第一行??我认为你错了。【参考方案2】:

如果要在运行时定义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
        
   

【讨论】:

你不应该显示裸指针,因为这是一个坏习惯,至少,使用像 unique_ptr 这样的智能指针。 @galop1n 智能指针不是灵丹妙药;在这种情况下,他应该使用std::vector,而不是指针。但是如果他要使用指针:在这种情况下,它们必须是智能指针。编写的代码会泄漏内存(因此不正确)。【参考方案3】:

ISO 不允许可变长度数组。但是,有一个漏洞。您可以在运行时使用动态内存创建以变量为大小的数组。

例如: 整数 x =4; int *a = new int[x];

不要忘记使用删除!

删除[]一个;

希望对你有帮助!

【讨论】:

【参考方案4】:

如果您想要一个非编译时 const 大小的数组,请使用 std:vector。

【讨论】:

虽然在技术上是正确的,但这是这里所有其他答案中最糟糕的答案! @πάνταῥεῖ 实际上,这是唯一正确的。 @JamesKanze 再次浏览所有这些之后,我必须忽略你是对的。 Downnote 收回...【参考方案5】:

编辑:从裸指针到共享指针,

使用指针进行动态内存分配,

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]... 当可以使用标准时,在这种情况下使用数组是没有意义的: :vector,特别是因为需要动态扩展数组。 好的,让我用 shared_ptr 替换它,最新的 c++11,是的,STL 容器是更好的选择,我同意 这是未定义的行为。您不能只将 shared_ptr 用于数组(这似乎是可能的,但相当复杂)。 就目前而言,您的答案是完全错误的shared_ptr&lt;DWORD&gt;,new DWORD(Number) 绝不可作为 OP 要求的数组!

以上是关于如何在 C++ 中分配类内数组的可修改大小的主要内容,如果未能解决你的问题,请参考以下文章

如何在 TestNG 单元测试类中分配类级别数据

防止在 iOS 中分配类

如何在 C++ 中分配一个二维指针数组

C ++从不同的函数中分配类成员的值

在 Python 中分配类布尔值

如何在 C++ 中分配一个大的动态数组?