[英]Is this a good way of using inheritance?
这是使用继承的好方法吗?
#include <iostream>
namespace Test::A {
class A {
char const * const this_message;
public:
constexpr A(char const * const message) noexcept
: this_message(message) {
}
constexpr char const * message() const noexcept {
return this_message;
}
};
struct B : public A {
constexpr B(char const * const message) noexcept
: A(message) {
}
};
}
int main() {
std::cout << sizeof(Test::A::A) << '\n';
std::cout << sizeof(Test::A::B) << '\n';
std::cout << Test::A::B("Test 1").message() << '\n';
try {
char const * const Test4 = "Test 4";
// Uncomment / comment to toggle between
//throw Test::A::B("Test 1");
throw Test::A::B(Test4);
} catch (Test::A::A const a) {
// I'm passing 'a' by copy because the size of 'a'
// will always be either 4 or 8 bytes / it's faster this way.
constexpr auto message = Test::A::B("Test 3").message();
std::cout << a.message() << " " << message << '\n';
}
return 0;
}
我有2个问题:
A)这是使用继承和...的好方法吗?
B)该程序正确,结构正确且没有不确定的行为吗?
我想创建自己的简单两级异常层次结构(仅一个基类和一些派生类),而我试图找到一种无需任何虚拟方法的实现方式。
以下代码可以正常工作,即使在派生类上没有要析构的东西,它也似乎以正确的顺序调用了析构函数。 但是,我对此工作的内部原理有些疑惑。
我知道如果我希望通过其基指针删除派生类,则需要一个虚拟析构函数,但是我没有考虑支持这种多态性。
我知道,通过从B
调用message
方法,我只是从A
调用该方法,而该方法又只返回成员变量this_message
,该变量可以在A
或B
初始化。
将对象传递给catch调用时, B
对象是否通过切片过程变成了A
? 但原因是b只是初始化成员A
/具有相同的状态, A
,它们都工作地进行到底。
想法是通过传递包含行号,文件位置等的静态char数组,在宏中初始化A
类及其派生类。
您正在使用标准库std :: cout,因此绝对应该从std :: exception派生异常。
您的类的名称应适当命名,例如SomethingException。
使用指针初始化类似乎是错误的,即使它指向.const节中的内容。 您已经在要展开的堆栈中初始化了指针。 该指针将在您的类实例中的副本之前消失,因为它被抛出了。 该地址将有效,因为该地址是.const但它闻起来会导致将来的维护人员挠头。
所以:A-不是很好的继承形式。 B-行为被定义为有臭味;-)
我知道如果我希望通过其基指针删除派生类,则需要一个虚拟析构函数,但是我没有考虑支持这种多态性。
如果您是唯一一个从事项目工作的程序员,那么这种折衷方案可能是切实可行的,但是您需要与加入该项目的每个人进行沟通和强制执行这些折衷方案,因此您很难扩展或重用该项目。您编写的代码。
将对象传递给catch调用时,B对象是否通过切片过程变成了A? 但是因为B只是初始化A的成员/与A具有相同的状态,所以最后都可以解决。
是的,通过切片。 是的,它挂在一起。
想法是通过传递包含行号,文件位置等的静态char数组,在宏中初始化A类及其派生类。
那是另一个问题/陷阱:人们习惯于在内部std::string
捕获文本的std::exception
,因此必须警告其他程序员不要执行诸如Test::A::B(my_message_in_a_string.c_str());
和Test::A::B(my_ostringstream.str())
,这使得将有用的消息放入异常类变得非常困难。
A)这是使用继承和...的好方法吗?
它为您提供了按基(无论是按引用还是切片)或派生类型进行捕获的选项,因此继承可添加有用的功能。
B)该程序正确,结构正确且没有不确定的行为吗?
确实如此,但是由于缺乏虚拟功能和使用切片,它在维护时非常脆弱并且很难扩展。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.