作为一名旧时的 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 传递给调用的方法 来自 MyClass2 的 ShowAdapters 函数是通过制作 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 程序的任何类、函数和对话框项访问该数组。提前致谢。