我正在使用Garmin GPS设备,并尝试通过USB提取与纬度,经度等有关的信息。我在SDK中工作,并且我已经把这个信息拉出来了,所以现在我正在努力将这些代码滚动到我正在使用的系统中。
此代码放在一个类中:CGarminUSBEngine继承自CASCIIEngine
我使用代码
从设备中提取此信息ReadFile (gHandle,
TheNewBuffer,
MAX_BUFFER_SIZE,
&theBytesReturned,
NULL);
我的问题是CGarminUSBEngine继承的CASCIIEngine具有该功能
BOOL ReadFile(void)
当我尝试用5个参数调用ReadFile()从我的USB设备读取时,我收到编译错误,说“'CASCIIEngine :: Readfile':函数不带5个参数”
我还没弄明白如何显式调用这个ReadFile()函数的WINAPI版本,或者甚至为什么需要它。在我看来编译器应该知道ReadFile是重载的,我试图调用WINAPI版本,而不是CASCIIEngine版本。
主要是我想知道如何明确调用WINAPI版本,其次我想知道为什么这是必要的。也许它很简单,我只是想念,这将是令人沮丧的。我赞美任何帮助。
答案 0 :(得分:7)
您收到错误是因为编译器正在解析对CASCIIEngine::Readfile()
的调用,而不是Windows API †提供的全局ReadFile()
函数。
显然,参数的数量不匹配,因此编译器会抱怨。
要告诉编译器引用全局ReadFile()
函数,请使用::
范围解析运算符。
::ReadFile (gHandle, TheNewBuffer, MAX_BUFFER_SIZE, &theBytesReturned, NULL);
// ^^---- Note `::`
†确定哪个功能得到解决的确切规则在C ++标准中有详细说明。您的情况的相关条款如下:
3.4.1非限定名称查找[basic.lookup.unqual]
1。在3.4.1中列出的所有情况下,搜索范围为a 按各自类别列出的顺序进行声明; 一旦找到名称的声明,名称查找就会结束。 如果没有找到声明,该程序就会形成错误。
...
8. 在类的成员函数(9.3)的定义中使用的名称 函数
X
之后的declarator-id
应声明为一个 有以下几种方式:
- 在用于使用它的块中或封闭之前 块(6.3)或
- 应该是类
X
的成员或者是基类的成员X
(10.2)或- 如果
X
是类Y
(9.7)的嵌套类,则应为Y
,或者应该是Y
基类的成员(此查找适用 反过来到Y
的封闭类,从最里面开始 封闭类)或- 如果
的定义X
是本地类(9.8)或是本地的嵌套类 class,在包含该块的块中定义类X
之前 类X
或- 如果
X
是命名空间N
的成员,或者是a的嵌套类 作为N
成员的类,或者是本地类或嵌套类 在N
成员之前的一个函数的本地类中 成员函数定义,在命名空间N
中或在N
之一中 封闭名称空间。...
9.3.1非静态成员函数[class.mfct.nonstatic]
2. 当
id-expression
(5.1)不属于班级成员时 访问语法(5.2.5)并且不用于形成指向成员的指针(5.3.1) 用于类X
或类的非静态成员函数体中 在mem-initializer
中用于类X
的构造函数, if 名称查找(3.4.1)将id-expression
中的名称解析为a 类X
的非静态非类型成员或X
的基类,id-expression
转换为类成员访问表达式 (5.2.5)使用(*this)
(9.3.2)作为左侧的后缀表达式.
运算符。成员名称然后引用成员 调用函数的对象...
根据3.4.1 / 1和3.4.1 / 8,ReadFile()
类中CASCIIEngine
的声明首先(第二个要点)在ReadFile()
之前找到全局命名空间(最后一个项目符号点),因此名称查找解析为成员函数。
这意味着您班上对ReadFile()
的电话实际上已经解决了这个问题:
(*this).ReadFile(gHandle, TheNewBuffer, MAX_BUFFER_SIZE,
&theBytesReturned, NULL); // Per 9.3.1/2
因此,全局函数甚至没有考虑重载解析,因为它不是成员函数。
当您以上面使用的方式使用::
范围解析运算符时,它将成为引用全局命名空间中的名称的限定名称,因此上述规则不适用。