如何在C ++中向Dirrerent类中的函数抛出错误?

时间:2016-01-26 19:37:31

标签: c++

我不确定"是否会将错误抛给其他班级"描述我的问题是正确的。

示例如下。有两个类:

  • A是一个用作directory的类,就像系统中的目录一样。它有两个私有值,称为filedirectory。它有一个名为mkdir的公共函数,它将创建一个目录。如果dirnamemkdir的内容已存在),它将抛出错误。
  • B是一个用作command的类,它还有一个名为mkdir函数的函数。 mkdir中的B接受两个参数:指向Adirname的指针。

如何在A中抛出错误然后在B中捕获错误? 我搜索了一些网站,但他们只有投入功能的说明。 谢谢!

更新1:

首先,我尝试在isExist中编写一个名为A的bool函数,并在B之前mkdir中使用它。如果isExist = true, throw errors(..);

我在这里尝试做的是将A视为一个对象,如果可能的话,本身应该抛出错误。

代码:

class A{

private:
    file f;
    directory d;
public:
    void mkdir(const string& dirname);
}

class B {
private:
       shared_ptr<A> p;
public:
       void mkdir(shared_ptr<A>, const string&);
}

更新2:

Ty回答你的答案,我现在更清楚了。这里提供了@ molbdnilo提供的一些有用的评论,以防万一像我这样的人也对异常感到困惑。

  

我会尝试更清楚:如果B :: mkdir调用A :: mkdir,它可以捕获A :: mkdir抛出的异常。如果其他东西叫A :: mkdir,B :: mkdir根本不会注意到任何东西。异常与类完全无关,它们只涉及函数的执行。无论函数是否是类的成员,异常都是相同的。

此外,@ el.pescado也列出了一个很好的答案。

3 个答案:

答案 0 :(得分:3)

如果我理解你想做什么,你可以在一个类的成员函数中捕获异常,然后将其传递给另一个类的成员函数。我下面的例子使用自由函数而不是成员函数,但原理是相同的:

#include <iostream>
#include <stdexcept>

using namespace std;

void HandleException(exception& exc) {
    cout << "Exception: \"" << exc.what() << "\" has been handled." << endl;
}

void DoSomethingRisky(double x) {
    if (x == 0)
        throw std::runtime_error("x must be non-zero");
    else
        cout << x << endl;
}

int main() {

    try {DoSomethingRisky(0);}
    catch (exception& exc) {
        HandleException(exc);
    }

    return 0;
}

编辑:下面是一个使用原始问题示例样式中的成员函数的示例:

#include <iostream>
#include <stdexcept>

using namespace std;

struct A {
    void HandleException(exception& exc) {
        cout << "Exception \"" << exc.what() << "\" has been handled." << endl;
    }
};

struct B {

    B(A* a): a_ptr(a) {}

    void DoSomethingRisky(double x) {
        try {
            if (x == 0)
                throw runtime_error("x must be non-zero");
            else
                cout << x << endl;
        }
        catch (exception& exc) {
            a_ptr->HandleException(exc);
        }
    }

    A* a_ptr;

};

int main() {

    A a;
    B b(&a);
    b.DoSomethingRisky(0);

    return 0;
}

答案 1 :(得分:2)

如果B继承自A,而A是一个从不打算单独实例化的抽象类,则可以在子类中定义实现,但调用“true”方法在超类中通过模糊实现并仍然处理超类中的错误,如此(未经测试超出编译):

#include <exception>

using namespace std;

class A {
public:
  void myfunc();

protected:
  virtual void myfunc_impl() = 0;
};

class B : public A {

protected:
  void myfunc_impl() override {
    // do stuff
    throw std::exception();
  }
};

void A::myfunc() {
  try {
    myfunc_impl();
  } catch(std::exception &e) {
    // handle exception
  }
}

这称为 non virtual interface idiom (信用:@ xtofl以澄清名称!)

答案 2 :(得分:2)

  

我搜索了一些网站,但他们只有投入的说明   功能

那是因为从方法(a.k.a.成员函数)抛出异常与从常规函数抛出异常没什么不同:

// some system headers...
#include <sys/stat.h>
#include <sys/errno.h>
#include <stdio.h>

void A::mkdir(const string &dirname)
{
    int code = ::mkdir(dirname.c_str(), 0755); // calling system mkdir() function
    if (code != 0) {
        // creating directory failed

        char *message = strerror(errno); // get system errror message
        throw std::runtime_error(message); // throw exception as usual
    }
}

void B::mkdir(shared_ptr<A> a, const string &dirname)
{
    try { // call A::mkdir, any axecptions thrown there will propagate here
        a->mkdir(dirname);
    }
    catch (std::exception &e) { // catch exception as usual
        std::cout << "Creating directory failed: " << e.what() << std::endl;
    }
}