1. STDMETHOD
STDMETHOD,定义了一个返回HRESULT类型的虚方法
举例说明:
写一个如下的函数
STDMETHOD(fun)(int i)
其展开以后变成:
virtual HRESULT __stdcall fun(int i);
这样就定义了一个虚函数fun。
当然,这个虚函数只能放在接口定义中,所以STDMETHOD宏是用于定义接口用,放在头文件中用。
2. volatile关键字
特性:
易变性
编译器对volatile修饰的变量,当要读取这个变量时,任何情况下都会从内存中读取,而不会从寄存器缓存中读取(因为每次都从内存中读取体现出变量的“易变”),防止不同线程寄存器和内存读到不同的值
不可优化性
编译器不会对volatile修饰的变量进行任何优化
顺序性
程序的乱序优化:保证一段代码的输出结果的前提下,将各条代码的实际执行顺序进行优化调整
volatile变量与volatile变量间代码的顺序,编译器不会进行乱序优化,但是volatile变量与非volatile变量代码的顺序,编译器不保证顺序,可能会进行乱序优化
参考:https://www.cnblogs.com/Joezzz/p/10271920.html
总结:
多线程编程,并发访问/修改的全局变量,通常都会建议加上Volatile关键词修饰,来防止C/C++编译器进行不必要的优化。
3. ATL_NO_VTABLE
在用ATL编写COM组件时,在类前面都有一个宏ATL_NO_VTABLE,这个宏的定义如下: #define __declspec(novtable) ATL_NO_VTABLE;
因为ATL是通过多重继承来实现COM组件的;
继承层次中的每个类都有自己的虚函数表,所以在继承层次很深的情况下,虚函数表会变 得非常宏大,如果用ATL_NO_VTABLE宏来阻止生成虚函数表,就会有限的减少组件的长度。
事实上ATL中预先实现的接口类基本上都使用了这个宏。只要有继承树结构的最下层的几个类 CComObject、CComAggObject、CCompolyObject、CComContainedobject
能够正确生成 VTABLE就可以了。也正因为这个原因,这几个类都没有使用ATL_NO_VTABLE.
4. L"字符串"
VC支持ascii和unicode两种字符类型,用_T可以保证从ascii编码类型转换到unicode编码类型的时候,程序不需要修改。
字符串前面加L表示该字符串是Unicode字符串;L"我的字符串"
表示将ANSI字符串转换成unicode的字符串,就是每个字符占用两个字节。
strlen("asd") = 3;
strlen(L"asd") = 6;
5. _T(“字符串”)
_T宏可以把一个引号引起来的字符串,根据你的环境设置,使得编译器会根据编译目标环境选择合适的(Unicode还是ANSI)字符处理方式
如果你定义了UNICODE,那么_T宏会把字符串前面加一个L。这时 _T(“ABCD”) 相当于 L"ABCD" ,这是宽字符串。
如果没有定义,那么_T宏不会在字符串前面加那个L,_T(“ABCD”) 就等价于 “ABCD”
6. GetmodulefileNameX
GetmodulefileName()
函数返回当前进程已加载可执行或DLL文件的完整路径名(以’\0’终止),该模块必须由当前进程地址空间加载。如果想要获取另一个已加载模块的文件路径,可以使用GetmodulefileNameEx()
函数。
DWORD WINAPI GetmodulefileName(
_In_opt_ HMODULE hModule, //应用程序或DLL实例句柄,NULL则为获取当前程序可执行文件路径名
_Out_ LPTSTR lpFilename, //接收路径的字符串缓冲区
_In_ DWORD nSize //接收路径的字符缓冲区的大小
);
确切的说,GetmodulefileName
的定义是一个宏,在UNICODE版本下,GetmodulefileName
等同于GetmodulefileNameW
,在ANSI版本下等同于GetmodulefileNameA
GetmodulefileNameA
和GetmodulefileNameW
的区别在于它们的字符串参数的“字符宽度”,这两个函数的原型如下:
DWORD WINAPI GetmodulefileNameA(
HMODULE hModule,
LPSTR lpFilename,
DWORD nSize );
ANSI版本,第二个参数是LPSTR,也就是char*。
DWORD WINAPI GetmodulefileNameW(
HMODULE hModule,
LPWSTR lpFilename,
DWORD nSize );
//UNICODE版本,第二个参数是LPWSTR,也就是wchar_t*。
7. ShellExecuteW
功能是运行一个外部程序(或者是打开一个已注册的文件、打开一个目录、打印一个文件等等);
它可以打开电脑内的任何文件,也可以打开URL
ShellExecute(
hWnd: HWND, //指定父窗口句柄
Operation: PChar,//指定动作, 如: open、runas、print、edit、explore、find[2]
FileName: PChar,//指定要打开的文件或程序
Parameters: PChar,//给要打开的程序指定参数
Directory: PChar,//缺省目录
ShowCmd: Integer//打开选项
):
hWnd:
用于指定父窗口的句柄。当函数调用过程中出现错误时,它将作为Windows消息窗口的父窗口。
lpOperation:
用于指定要进行的操作,当参数为NULL时,默认操作"open"。
“open”,表示执行由lpFile参数指定的程序,或者打开由lpFile参数指定的文件或文件夹。
"explort",表示打开由lpFile参数指定的文件夹。
"print",表示打印由lpFile参数指定的文件。
lpParameters:
若lpFile参数是一个可执行文件,则此参数指定命令行参数,否则此参数应设为NULL。
lpDirectory:
用于指定默认目录。
nShowCmd:
用于指定程序窗口初始显示方式。 有如下参数
#define SW_HIDE 0 /*隐藏窗体,并激活另一个窗体*/
#define SW_SHOWnorMAL 1 /*与SW_RESTORE相同*/
#define SW_SHOWMINIMIZED 2 /*激活并以最小化的形式显示窗体*/
#define SW_SHOWMAXIMIZED 3 /*激活并以最大化的形式显示窗体*/
#define SW_MAXIMIZE 3 /*最大化指定的窗体*/
#define SW_SHOWNOACTIVATE 4 /*以上次的状态显示指定的窗体,但不激活它*/
#define SW_SHOW 5 /*激活窗体,并将其显示在当前的大小和位置上*/
#define SW_MINIMIZE 6 /*最小化指定的窗体,并激活另一个窗体*/
#define SW_SHOWMINNOACTIVE 7 /*以最小化形式显示指定的窗体,但不激活它*/
#define SW_SHOWNA 8 /*以当前的状态显示指定的窗体,但不激活它*/
#define SW_RESTORE 9 /*以原本的大小和位置,激活并显示指定的窗体*/
#define SW_SHOWDEFAULT 10 /*设置显示的状态由STARTUPINFO结构体指定*/
8. GetBuffer()和releaseBuffer()
GetBuffer()主要作用是将字符串的缓冲区长度锁定;
releaseBuffer()则是解除锁定,使得CString对象在以后的代码中继续可以实现长度自适应增长的功能。
9. STDAPI
在WINNT.h文件中STDAPI宏定义如下:
#define STDAPI EXTERN_C HRESULT STDAPICALLTYPE
其中,
#define STDAPICALLTYPE __stdcall
综合解释为:
STDAPI只是一个宏定义,而该宏定义由两个宏定义(EXTERN_C和STDAPICALLTYPE)和HRESULT组成。
经过预编译,有如下结果:extern "c" HRESULT __stdcall
extern “c” 会指示编译器这部分代码按C语言的进行编译
HRESULT 函数返回值类型,如果函数正常执行,则返回S_OK
__stdcall 是一种函数调用约定关键字
10. CreateEvent
HANDLECreateEvent(
LPSecurity_ATTRIBUTESlpEventAttributes,// 安全属性
BOOLbManualReset,// 复位方式
BOOLbInitialState,// 初始状态
LPCTSTRlpName // 对象名称
);
参数:
lpEventAttributes:一般为NULL
bManualReset:创建的Event是自动复位还是人工复位。如果true,人工复位,一旦该Event被设置为有信号,则它一直会等到ResetEvent()
被调用时才会恢复为无信号。如果false,自动复位,一旦该Event被设置为有信号,则当有一个wait到它的Thread时, 该Event就会自动复位,变成无信号
bInitialState:初始状态,true,有信号,false无信号
lpName:事件对象的名称。您在OpenEvent函数中可能使用
返回值:
该函数创建一个Event同步对象,如果CreateEvent调用成功的话,会返回新生成的对象的句柄,否则返回NULL。
11. time()
//头文件 <time.h>
time_t time(time_t *t);
如果t是空指针,直接返回当前时间。如果t不是空指针,返回当前时间的同时,将返回值赋予t指向的内存空间。
返回自纪元 Epoch(1970-01-01 00:00:00 UTC)起经过的时间,以秒为单位
#include <stdio.h>
#include <time.h>
int main ()
{
time_t seconds;
seconds = time(NULL);
printf("自 1970-01-01 起的小时数 = %ld\n", seconds/3600);
return(0);
}
输出:
12. FindFirstChangeNotificationA
HANDLE FindFirstChangeNotification(
LPCTSTR lpPathName, // 指定要监视的目录
BOOL bWatchSubtree, // 指定是否监视lpPathName 目录下的所有子目录
DWORD dwNotifyFilter // 指定过滤条件
);
13. 函数声明后面加throw()
问题描述:
C++里面为什么有时候在函数声明的时候在后面加throw()关键字?
解释:
C++函数后面加关键字throw(something)限制,是对这个函数的异常安全作出限制;这是一种异常规范,只会出现在声明函数时,表示这个函数可能抛出任何类型的异常。
void fun() throw(); //表示fun函数不允许抛出任何异常,即fun函数是异常安全的。
void fun() throw(...); //表示fun函数可以抛出任何形式的异常。
void fun() throw(exceptionType); // 表示fun函数只能抛出exceptionType类型的异常。
14. CALLBACK
CALLBACK,即回调函数,是一个通过函数指针调用的函数。
如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。
回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
回调函数是由开发者按照一定的原形进行定义的函数(每个回调函数都必须遵循这个原则来设计)
注意
① 回调函数必须有关键词 CALLBACK;
② 回调函数本身必须是全局函数或者静态函数,不可定义为某个特定的类的成员函数
原文地址:https://www.jb51.cc/wenti/3280974.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。