我写的小程序,请大家评判
/*
文件名: AutoRun.cpp
介绍: 定义类AutoRun中功能函数
版本: v1.0
*/
#include <iostream>
#include <cassert>
#include "AutoRun.h "
#include "windows.h "
using std::endl;
using std::cout;
const unsigned int MAX_SIZE=1024;
//构造函数
AutoRun::AutoRun()
{
m_hKey=NULL;
lpSubKey= "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run ";
}
bool AutoRun::Open()
{
assert(m_hKey==NULL);
//打开注册表
try
{
LONG ret=RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
lpSubKey,
0,
KEY_ALL_ACCESS,
&m_hKey//返回句柄!函数不能用const修饰
);
if(ret!=ERROR_SUCCESS)
{
throw ret;
}
}
catch (LONG &e)
{
cout < < "注册表打开失败 " < < endl;
return false;
}
return true;
}
//查询键
bool AutoRun::Query()const
{
//参数有效性检查...
assert(m_hKey!=NULL);
//通过检查!
TCHAR lpKeyName[MAX_SIZE]; // buffer for subkey name
TCHAR lpValueName[MAX_SIZE];
DWORD dwKeySize; // size of name string
DWORD dwValueSize;
DWORD dwSubKeys; // number of subkeys
DWORD dwValues; // number of values for key
LONG ret;
//获得 键数 和 值数 ,用来列举
try
{
ret=RegQueryInfoKey(
m_hKey, // key handle
NULL,
NULL,
0, // reserved
&dwSubKeys, // number of subkeys
NULL,
NULL,
&dwValues, // number of values for this key
NULL,
NULL,
NULL,
NULL);
if(ret!=ERROR_SUCCESS)
{
throw ret;
}
cout < < "Number of subkeys: " < < dwSubKeys < < endl;
}
catch (LONG &e)
{
return false;
}
//列举键
for (DWORD i=0;i <dwSubKeys;i++)
{
try
{
ret=RegEnumKeyEx(
m_hKey,
i,
lpKeyName,
&dwKeySize,
NULL,
NULL,
NULL,
NULL);
if(ret!=ERROR_SUCCESS)
{
throw ret;
}
}
catch (LONG &e)
{
return false;
}
lpKeyName[dwKeySize]= '\0 ';
//输出结果
cout < < "Key: " < < lpKeyName < < endl;
}
//列举值
cout < < "Number of values: " < < dwValues < < endl;
for(i=0;i <dwValues;i++)
{
try
{
ret=RegEnumValue(
m_hKey,
i,
lpValueName,
&dwValueSize,
NULL,
NULL,
NULL,
NULL);
if(ret!=ERROR_SUCCESS)
{
throw ret;
}
}
catch(LONG &e)
{
return false;
}
lpValueName[dwValueSize]= '\0 ';
//输出结果
cout < < "Value: " < < lpValueName < < endl;
}
return true;
}
//添加键
bool AutoRun::Add(LPCTSTR lpFileName,LPCTSTR lpPath)const
{
//参数有效性检查...
assert(lpFileName!=NULL && lpPath!=NULL && m_hKey!=NULL);
//通过检查!
TCHAR buff[MAX_SIZE];
strcpy(buff,lpPath);
DWORD dwSize=sizeof(buff);
//写入注册表
try
{
LONG ret=RegSetValueEx(
m_hKey,
lpFileName,
NULL,
REG_SZ,
(LPBYTE)buff,
dwSize
);
if (ret!=ERROR_SUCCESS)
{
throw ret;
}
}
catch (LONG &e)
{
return false;
}
return true;
}
//删除键
bool AutoRun::Del(LPCTSTR lpFileName)const
{
//参数有效性检查...
assert(lpFileName != NULL && m_hKey!=NULL);
//通过检查!
try
{
LONG ret=RegDeleteValue(m_hKey,lpFileName);
if (ret!=ERROR_SUCCESS)
{
throw ret;
}
}
catch(LONG &e)
{
return false;
}
return true;
}
bool AutoRun::Close()const
{
assert(m_hKey!=NULL);
//关闭注册表
try{
LONG ret=RegCloseKey(m_hKey);
if(ret!=ERROR_SUCCESS)
{
throw ret;
}
}
catch(LONG &e)
{
cout < < "关闭注册表失败!尝试再次关闭 " < < endl;
RegCloseKey(m_hKey);
return false;
}
return true;
}
//析构函数
AutoRun::~AutoRun()
{
m_hKey=NULL;
}
[解决办法]
随便说点什么,仅供参考
1. 就我对try-catch的理解,当一个函数(或者模块,类)无法处理某一个类错误(或者异常)时,他可以将这类错误作为一个exception抛出来,交给调用者(或者上层)来处理,这样函数本身可以保证设计的完整性。在lz的程序中,比如AutoRun::Open(),设计上可以
void AutoRun::Open() throws SomeException or
bool AutoRun::Open();
而lz对于try-catch的使用,有点多此一举
2.对于bool AutoRun::Query()const的设计,不应该像lz那样遍历然后输出到console,而应该将结果返回(或提供某种机制返回,比如迭代器)。AutoRun::Query只处理数据,不处理数据如何显示。这样可以提高AutoRun的可复用性。
[解决办法]
fflush(stdin)说得确实有道理,学习。:)
让偶来再帮他详细解释一下吧。:P
大多数情况下throw/catch不该在一起,原因是:异常的抛出端要是完全知道该怎么办的话,那干粹用常规方式处理掉就OK了。
关于cout,一个工具类不应该跟某个具体的输出流绑定在一起,这样,显然会影响它的可用性。比如,如果另一个人(或许也是你自己)想利用你的代码,但他不希望输出到命令行窗口,而是希望输出到文件怎么办?或者他根本不想编命令行窗口程序,而是想把这个类用在一个图形界面的程序中,通过对话框什么的做输出又怎么办?