C++报错‘expression must have class type’,求WinHTTP类问题排查
解决"expression must have class type"错误
这个错误的根源是你在第13行写的WinHTTP newHTTP();被C编译器解析成了一个返回WinHTTP类型、无参数的函数声明,而不是创建WinHTTP类的对象——这就是C里著名的「最令人头疼的解析」(Most Vexing Parse)问题。
除此之外,你的WinHTTP类目前只提供了带用户名和密码参数的构造函数,所以即使你修正了语法,还需要处理构造函数的参数问题。下面分两步解决:
1. 修正对象实例化的语法
把函数声明式的写法改成对象初始化的写法:
- 如果你要使用带参数的构造函数,传入用户名和密码:
WinHTTP newHTTP("your_username", "your_password"); - 如果你不需要用户名密码,可以给
WinHTTP类添加一个无参的默认构造函数,这样就能直接创建对象:
在类的public部分添加:
然后主函数里直接写:WinHTTP() = default; // 默认构造函数,或者自己实现空的构造函数体WinHTTP newHTTP; // 注意不要加括号!
2. 修改后的完整代码示例
主函数修正版
#include "stdafx.h" #include <iostream> #include <string> #include <windows.h> #include <WinHttp.h> #include "myHTTP.h" int main() { // 这里改成正确的对象初始化方式,传入构造函数需要的参数 WinHTTP newHTTP("test_user", "test_pass"); HINTERNET myResponse = newHTTP.httpConnect(L"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36", L"api.example.com", // 注意:WinHttpConnect需要服务器主机名,不是带http://的完整URL 0, L"GET"); int x; std::cin >> x; return 0; }
WinHTTP类修正版(添加默认构造函数)
class WinHTTP { private: std::string siteUsername, sitePassword; std::wstring UA, URL; bool bResult = false; DWORD dwSize = sizeof(DWORD); LPSTR pszOutBuffer; DWORD dwDownloaded = 0; HINTERNET hSession = NULL, hConnect = NULL, hRequest = NULL; public: // 添加无参默认构造函数 WinHTTP() = default; // 原有的带参数构造函数 WinHTTP(std::string myuser, std::string mypass) : siteUsername(myuser), sitePassword(mypass){ } HINTERNET httpConnect(std::wstring userAgent, std::wstring myURL, int isHTTPS, std::wstring protocol) { UA = userAgent; URL = myURL; std::wstring acceptTypes = L"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"; int portToUse = isHTTPS == 1 ? 443 : 80; hSession = WinHttpOpen(UA.c_str(), WINHTTP_ACCESS_TYPE_NO_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); if (hSession) { hConnect = WinHttpConnect(hSession, URL.c_str(), portToUse, 0); } else { printf("error: %d",GetLastError()); } hRequest = WinHttpOpenRequest(hConnect, protocol.c_str(), NULL, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0); if (hRequest) { return hRequest; } else { printf("error: %d", GetLastError()); return hRequest; } } };
另外提醒一下:WinHttpConnect的第二个参数应该是服务器主机名(比如L"api.example.com"),而不是带http://的完整URL,你当前传入的L"http://api"可能会导致连接失败,记得修正这个参数。
内容的提问来源于stack exchange,提问作者jimmy
相关产品推荐
相关产品推荐

