从 C++ (MFC) 中的不同类访问数组

问题描述 投票:0回答:0

作为一名旧时的 VB6.0 程序员,我正在使用 VisualStudio 学习 VC++ (MFC),我编写了一个小示例,如下所示。我创建了一个类来填充 myAdapters 数组,如下所示:

    class CAdapter
    {
    public:
        int m_IPv4;
        string m_AdapterName;
        CAdapter* myAdapters;
        int adapterCount;
    
        CAdapter() {
            myAdapters = nullptr;
            adapterCount = 0;
        }
    
        ~CAdapter() {
            delete[] myAdapters;
        }
    
        void addAdapter(CAdapter adapter) {
            CAdapter* newArray = new CAdapter[adapterCount + 1];
    
            for (int i = 0; i < adapterCount; i++) {
                newArray[i] = myAdapters[i];
            }
    
            newArray[adapterCount] = adapter;
            adapterCount++;
    
            delete[] myAdapters;
            myAdapters = newArray;
        }
    
        CAdapter* getAdapters() {
            return myAdapters;
        }
    
        int getAdapterCount() const {
            return adapterCount;
        }
    
        void GetAdapters() {
            CAdapter adapter1;
            adapter1.m_IPv4 = 192168001;
            adapter1.m_AdapterName = "John";
            addAdapter(adapter1);
    
            CAdapter adapter2;
            adapter2.m_IPv4 = 192168002;
            adapter2.m_AdapterName = "Jane";
            addAdapter(adapter2);
    
            CAdapter* adapterArray = getAdapters();
    
            for (int i = 0; i < adapterCount; i++)
            {
                printf("Element %d in main: %d %s\n", i, adapterArray[i].m_IPv4, adapterArray[i].m_AdapterName);
            }
        }
    };

但是,我需要随时从任何函数或类访问 myAdapters 元素。所以我让某个 AI 修改代码,从一个类调用 GetAdapters 函数,从另一个类调用 ShowAdapters 函数,结果是:

允许从一个类调用 GetAdapters() 函数,并且 ShowAdapters() 函数被另一个类调用,你可以 使 myAdapters 数组和 adapterCount 变量成为公共成员 CAdapter 类的。这将允许其他类访问和 修改这些变量。

这里是一个示例,说明如何修改 CAdapter 类来制作 myAdapters 数组和 adapterCount 变量公共成员

    class CAdapter {
    public:
        // constructor
        CAdapter() {}
    
        // public member variables
        CAdapterInfo* myAdapters;
        int adapterCount;
    
        // public member functions
        void GetAdapters() {
            // ...
        }
    
        void ShowAdapters() {
            // ...
        }
    };

通过此修改,您现在可以创建 CAdapter 的实例 一个类中的类,调用它的GetAdapters()函数来填充 myAdapters 数组,然后将实例传递给另一个可以 调用它的ShowAdapters()函数来显示 myAdapters 数组。这是您如何执行此操作的示例:

    class MyClass1 {
    public:
        void doSomething() {
            // create an instance of the CAdapter class
            CAdapter adapters;
    
            // call the GetAdapters() function to populate the myAdapters array
            adapters.GetAdapters();
    
            // pass the adapters instance to another class that can call its ShowAdapters() function
            MyClass2 class2;
            class2.showAdapters(adapters);
        }
    };
    
    class MyClass2 {
    public:
        void showAdapters(CAdapter& adapters) {
            // call the ShowAdapters() function to display the contents of the myAdapters array
            adapters.ShowAdapters();
        }
    };

本质上,提议的代码是正确的并且可以工作。但是,GPT 先生不明白的是,每当要从 ComboBox 元素的 OnCbnSelchangeCombo1 等事件调用 showAdapters 函数时,我无法将适配器实例传递给 MyClass2,因为在这样的函数中我没有访问由 MyClass1 创建的 adapters 实例。

我告诉 AI,它的回应极大地改变了示例代码:

一种避免将适配器实例从 MyClass1 传递给调用的方法 来自 MyClass2ShowAdapters 函数是通过制作 myAdapters array CAdapter 类的静态成员。这样,myAdapters 数组可以直接从任何包含 CAdapter 头文件。这是一个如何做到这一点的例子:

CAdapter.h:

#pragma once

#include <string>

class CAdapter {
public:
    static void GetAdapters();
    static void ShowAdapters();

private:
    static int adapterCount;
    static CAdapter* myAdapters;
    
    std::string m_AdapterName;
    std::string m_IPv4;
};

CAdapter.cpp:

#include "CAdapter.h"
#include <iostream>
#include <windows.h>
#include <iphlpapi.h>

#pragma comment(lib, "iphlpapi.lib")

int CAdapter::adapterCount = 0;
CAdapter* CAdapter::myAdapters = nullptr;

void CAdapter::GetAdapters() {
    DWORD dwSize = 0;
    DWORD dwRetVal = 0;

    // Make an initial call to GetAdaptersAddresses to get the size needed.
    GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, nullptr, &dwSize);

    // Allocate memory from sizing information.
    myAdapters = new CAdapter[dwSize];

    // Get adapter information.
    PIP_ADAPTER_ADDRESSES pAddresses = reinterpret_cast<PIP_ADAPTER_ADDRESSES>(new BYTE[dwSize]);
    dwRetVal = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &dwSize);
    if (dwRetVal == NO_ERROR) {
        // Iterate through all adapters and add them to the array.
        PIP_ADAPTER_ADDRESSES pCurrAddresses = pAddresses;
        while (pCurrAddresses) {
            if (pCurrAddresses->PhysicalAddressLength != 0) {
                // Add adapter to the array.
                myAdapters[adapterCount].m_AdapterName = pCurrAddresses->AdapterName;
                myAdapters[adapterCount].m_IPv4 = pCurrAddresses->IpAddressFirst->IpAddress.String;
                adapterCount++;
            }
            pCurrAddresses = pCurrAddresses->Next;
        }
    }

    delete[] reinterpret_cast<BYTE*>(pAddresses);
}

void CAdapter::ShowAdapters() {
    for (int i = 0; i < adapterCount; i++) {
        printf("Adapter Name: %s\n", myAdapters[i].m_AdapterName.c_str());
        printf("IPv4 Address: %s\n", myAdapters[i].m_IPv4.c_str());
        printf("\n");
    }
}

无缘无故,AI 重写了整个代码以使用GetAdaptersAddresses API 函数。这是对话中的一个(值得注意的)推论,我从未提及任何 API,也没有将它们包含在示例代码中。我正在使用 GetAdaptersInfo,它几乎相同,所以它非常准确。

由于我是 C++ 的新手,这段代码引入了许多重大更改,需要很长时间才能适应我的 MFC 应用程序,而且我不相信这是最好的方法或者它是否有效(所有以前的代码都没有对 MFC 稍作调整即可工作)。为什么在 C++ 中没有简单的方法来声明和访问“全局”数组,就像我过去使用 Visual Basic 时那样,只需在全局范围内声明数组,使其可供所有窗体、对话框和模块访问?有没有更简单的方法来做到这一点?本质上,我希望 myAdapters 数组由来自 CAdapters 类的函数填充,然后以某种方式从 MFC 程序的任何类、函数和对话框项访问该数组。提前致谢。

c++ visual-studio mfc
© www.soinside.com 2019 - 2024. All rights reserved.