在C++中实现类似接口的纯抽象基类的最佳实践
Best practice for implementing an interface-like pure abstract base class in C++?
我想用虚拟析构函数声明一个纯抽象基类。我知道有三种方法可以做到这一点,但我不知道哪种最好,也不知道为什么。
我的目标是以最佳实践C++11风格实现抽象基类接口,并具有最佳运行时性能。特别是,我想提供无操作析构函数的内联/消除。我还想消除与重复的vtables相关的警告,方法是选择一个不生成重复vtables的实现,或者做出明智的决定来抑制警告。
以下是我所知道的实现抽象基类的三种方法:
选项#1
/// A.h:
class A {
public:
virtual ~A() {}
virtual int f() = 0;
};
选项#2
/// A.h:
class A {
public:
virtual ~A();
virtual int f() = 0;
};
/// A.cpp:
A::~A() {}
选项#3
/// A.h:
class A {
public:
virtual ~A() = default;
virtual int f() = 0;
};
这些是我唯一的选择吗?
#1、#2和#3中的哪一个被认为是最佳实践?如果存在权衡(例如运行时性能与编译时性能),请描述它们。
有了选项#1,内联析构函数会内联吗?
我知道选项#1将在每个翻译单元中放入vtable。选项#1在clang中生成-Wweak-vtables
警告,并被gcc[1]中的"模糊链接"类别覆盖。选项#3不会生成clang警告——这是否意味着选项#3不会产生vtable?
选项#3与其他选项有何不同?
其他问题也讨论了关于clang警告的类似问题,但我找不到一个问题来具体说明哪种选择被认为是最佳实践以及为什么。
[1]https://gcc.gnu.org/onlinedocs/gcc/Vague-Linkage.html
最佳实践(至少在我负责的时候):
struct A {
//
// keep move semantics available - rule of 0, 3, or 5
// in this case, 5 because we defined a destructor.
//
A(const A&) = default;
A(A&&) = default;
A& operator=(const A&) = default;
A& operator=(A&&) = default;
virtual ~A() = default;
// non-polymorphic interface in terms of private polymorphic
// implementation
int f()
try
{
// possibly lock a mutex here?
// possibly some setup code, logging, bookkeeping?
return f_impl();
}
catch(const std::exception& e) {
// log the nested exception hierarchy
std::throw_with_nested(std::runtime_error(__func__));
}
private:
virtual int f_impl() = 0;
};
为什么在你看来,为f()设置一个try-catch块很重要einpoklum 16分钟前
@我很高兴你问我。因为如果你在每个方法和每个函数中都这样做,并抛出一个包含函数名(和任何相关参数)的嵌套异常,这意味着当你最终捕捉到异常时,你可以将所有嵌套异常打开到你的日志文件或cerr中,你就会得到一个完美的堆栈跟踪,准确地指向问题。
展开嵌套异常的参考:
http://en.cppreference.com/w/cpp/error/throw_with_nested
这不会影响表演吗?
一点也不。
但在每个功能中添加一个功能尝试块是很痛苦的
要想重现一个你不知道它是如何或为什么发生的问题,也不知道它的背景,这是一个更大的痛苦。相信我。。。
- 如何定义一个纯抽象基类
- 将抽象基类中的所有纯虚函数定义为 varaidaic 模板
- 在C++单元测试上下文中,抽象基类是否应将其他抽象基类作为函数参数
- 有没有一种方法可以使用SFINAE来检测一个类型是否实现了给定的抽象基类
- 自定义异常中的用户定义的空构造函数,具有多个继承和抽象基类
- 如何保存指向抽象基类的指针/引用,但在 c++ 中仍然可以复制
- C++:在共享对象中调用抽象基类构造函数/未定义的符号
- 从抽象基类中获取重载函数
- 如何构建一个 Map,其中键是抽象基类(而不是值)
- 无法调用纯抽象基类超载
- 私下继承C++抽象基类是什么意思
- 如何在抽象基类中实现运算符+
- 如何为抽象基类创建模板实例化?
- 崩溃 __cxxabiv1::__cxa_pure_virtual () - vtable ptr 到抽象基类
- CRTP - 是否可以创建一个抽象基类?
- 嵌套抽象基类的泛型模板
- 抽象基类的派生类未正确覆盖基纯虚拟方法
- 在C 中的数组中存储抽象基类的不同派生类的对象
- "Has a" C++关系,最佳做法是让一个类"implement"多个抽象基类?
- C++ 重新定义抽象基类