gpt4 book ai didi

c++ - 从基类调用最终类构造函数

转载 作者:行者123 更新时间:2023-11-28 02:36:53 24 4
gpt4 key购买 nike

我有一个异常类如下:

class ExtensionExceptionType;
class Object;

class Exception
{
public:
explicit Exception () { }

Exception( const std::string &reason ) { PyErr_SetString( _Exc_RuntimeError(), reason.c_str() ); }
Exception( PyObject* exception, const std::string &reason ) { PyErr_SetString( exception, reason.c_str() ); }

Exception( PyObject* exception, Object& reason );

Exception( ExtensionExceptionType& exception, const std::string& reason );
Exception( ExtensionExceptionType& exception, Object& reason );

void clear() { PyErr_Clear(); } // clear the error -- technically but not philosophically const

static Object err_type();
static Object err_value();
static Object err_trace();

static Object err_stats( uint32_t i ); // 0 1 2 for {type, value, trace}

static void wrap( int condition ) {
if( condition == -1 )
throw Exception{};
}
};

// Abstract
class StandardError : public Exception { protected: explicit StandardError() {} };

class LookupError : public StandardError { protected: explicit LookupError() {} };
class ArithmeticError : public StandardError { protected: explicit ArithmeticError() {} };
class EnvironmentError : public StandardError { protected: explicit EnvironmentError() {} };

// Concrete (π)

// e.g.
// class TypeError: public StandardError
// {
// public:
// TypeError (const std::string& reason)
// : StandardError()
// {
// PyErr_SetString( Py::_Exc_TypeError(),reason.c_str() );
// }
// };

#define CONCRETE( CLASS, BASE ) \
class CLASS: public BASE \
{ \
public: \
CLASS (const std::string& reason) \
{ \
std::cout << "(Exception.hxx) " #CLASS " from PyCXX (" << reason.c_str() << ") \n"; \
PyErr_SetString( _Exc_##CLASS(), reason.c_str() ); \
} \
};

// it appears that these classes are only for manually RAISING Python errors
// i.e. Raising an exception in the Python runtime
// because if I type something in to the Python console, I can make (e.g.) a KeyError occur, but these classes don't get hit.

CONCRETE( TypeError, StandardError )
CONCRETE( IndexError, LookupError )
CONCRETE( AttributeError, StandardError )
CONCRETE( NameError, StandardError )
CONCRETE( RuntimeError, StandardError )
CONCRETE( NotImplementedError, StandardError )
CONCRETE( SystemError, StandardError )
CONCRETE( KeyError, LookupError )
CONCRETE( ValueError, StandardError )
CONCRETE( OverflowError, ArithmeticError )
CONCRETE( ZeroDivisionError, ArithmeticError )
CONCRETE( FloatingPointError, ArithmeticError )
CONCRETE( MemoryError, StandardError )
CONCRETE( SystemExit, StandardError )

我刚刚添加:

    static void wrap( int condition ) {
if( condition == -1 )
throw Exception{};
}

...因为在其他地方有很多...

if( SomePythonFunc(...) == -1 ) throw Exception{};

...已整理成:

Exception.wrap( SomePythonFunc(...) ); // much nicer, I think

但是,也有以下情况:

if( SomePythonFunc(...) == -1 ) throw TypeError{ "foo" };

...而且我看不出如何执行等效的包装。

即写:

TypeError.wrap( SomePythonFunc(...), "foo" );

由于 TypeError : Exception,并且 Exception::wrap 是公开的,我可以为 wrap 创建一个可选的第二个参数:

    static void wrap( int condition, string err="default-err" ) {
if( condition == -1 )
throw FinalClassConstructor{ err }; // <-- how to do this?
}

...但是我该如何为刚刚命中::wrap 的最终类调用构造函数?

最佳答案

您尝试做的事情违背了多项 SOLID 原则。您还使您的基类与其后代紧密耦合(!)。你绝对不想要那个。它应该不知道谁继承了。

要正确执行此操作,请覆盖子类中的 Wrap 函数,这些子类基本上是在这些子类中进行处理。在您的代码中,您将使用 StandardError.Wrap(...

但老实说,我只会在代码中保留异常。

(WHATEVER CONDITION -> Throw exception) 在代码中非常好,并且比使用静态方法的另一个异常中的异常更具可读性。

当您不应该再重构它时就是这种情况。

关于c++ - 从基类调用最终类构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27143297/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com