2012-07-24 107 views
4

,我有以下我的构造函数的代码块(这只是一个例子,这个问题是不是split,而约抛出一般异常。此外,升压库不能使用。抛出异常的通用理由C++

Transfer::Transfer(const string &dest){ 
    try{ 
    struct stat st; 
    char * token; 
    std::string path(PATH_SEPARATOR) // if it is \ or/this macro will solve it 
    token = strtok((char*)dest.c_str(), PATH_SEPARATOR) // 
    while(token != NULL){ 
     path += token; 
     if(stat(path.c_str(), &st) != 0){ 
      if(mkdir(path.c_str()) != 0){ 
       std:string msg("Error creating the directory\n"); 
       throw exception // here is where this question lies 
      } 
     } 

     token = strtok(NULL, PATH_SEPARATOR); 
     path += PATH_SEPARATOR; 

    } 
    }catch(std::exception &e){ 
     //catch an exception which kills the program 
     // the program shall not continue working. 
    } 

} 

我想是抛出一个异常如果目录不存在,它不能被创建。我想抛出一个通用的异常,我怎么能做到这一点在C++? PS:dest has th Ë格式如下:

dest = /usr/var/temp/current/tree 
+3

'令牌= strtok的((字符*)DEST做到这一点.c_str(),PATH_SEPARATOR)//'ouch – chris 2012-07-24 16:30:01

+0

@chris你有更好的建议吗? – cybertextron 2012-07-24 16:31:17

+0

Boost文件系统有一个'create_directories',它为你免费提供所有这些,并且具有很好的错误语义。 – Flexo 2012-07-24 16:33:17

回答

7

请检查this answer。这就解释了如何使用自己的异常类

class myException: public std::runtime_error 
{ 
    public: 
     myException(std::string const& msg): 
      std::runtime_error(msg) 
     {} 
}; 

void Transfer(){ 
    try{ 
      throw myException("Error creating the directory\n"); 
    }catch(std::exception &e){ 
     cout << "Exception " << e.what() << endl; 
     //catch an exception which kills the program 
     // the program shall not continue working. 
    } 

} 

另外,如果你不想让自己的类,你可以简单地通过

throw std::runtime_error("Error creating the directory\n"); 
+7

通过常量引用来捕获异常是一个很好的经验法则。 – 2012-07-24 16:45:00

+1

你明白了。 '抛出std :: runtime_error(“味精”)'会做到这一点。 – cybertextron 2012-07-24 16:50:46

+1

我想补充一点,在各个地方退出程序的可扩展性不是很好。这当然不应该在将成为图书馆一部分的代码中完成。最好扔掉尽可能少的地方(例如main)。 – 2012-07-24 16:55:03

6

usage of strtok is incorrect - 它需要一个char*,因为它修改字符串,但不允许修改在std::string一个.c_str()的结果。需要使用C风格的演员阵容(这里演奏的像是const_cast)是一个很大的警告。

无论何时发布,您都可以通过使用boost文件系统(likely to appear in TR2)整齐地避开这个问题和路径分隔可移植性。例如:

#include <iostream> 
#include <boost/filesystem.hpp> 

int main() { 
    boost::filesystem::path path ("/tmp/foo/bar/test"); 
    try { 
    boost::filesystem::create_directories(path); 
    } 
    catch (const boost::filesystem::filesystem_error& ex) { 
    std::cout << "Ooops\n"; 
    } 
} 

拆分平台分隔符上的路径,根据需要创建目录,或者在失败时引发异常。