C++,保护的抽象虚基类,纯虚函数,私有析构函数

26

今天我发现了这个引语,有人能解释一下吗?

"如果你认为C++不是过于复杂的,那么什么是protected abstract virtual base pure virtual private destructor,你上一次需要它是什么时候呢? —— Tom Cargill"


7
我可以把这个标记为“冗余部门的部门”吗?拜托了? - Ben Voigt
3
我不考虑 protected abstract virtual base pure virtual private destructor and when was the last time you needed one。我认为 1) 我的类是抽象的 2) 析构函数必须是虚函数 3) 但我不需要实现所以它是纯虚函数 4) 我将使用受保护的继承。 - Martin York
1
我对这个引用的历史背景很感兴趣。汤姆·卡吉尔因他的“异常处理:虚假的安全感”文章而臭名昭著。通过谷歌搜索,我发现汤姆·卡吉尔在90年代中期转向了Java。我的猜测是他对C++感到(正确或错误地)幻灭了。这个引用似乎证实了这一点。有人可以证实/否认吗? - paercebal
5个回答

23

我认为这是一个私有纯虚析构函数(我认为这部分很容易理解),它是一个抽象基类的一部分,你通过受保护的虚拟继承使用了它。

 class Base
 {
    private:
        virtual ~Base() = 0;   /* A */
 };

 class Derived : protected virtual Base
 {
    private:
     ~Derived () {.......}    /* B */
 };

从标签B的角度来看,标签A上的这行代码是一个 "protected abstract virtual base pure virtual private destructor"。

这三个部分分别具有它们自己的用途。我不知道有哪种设计模式需要以上三个部分的全部内容,但没有什么阻止它们同时使用。


4
这是编译错误,对吗?因为在虚拟继承中,虚拟基类的析构函数必须由最终派生类的析构函数调用,但~Derived()无法访问~Base()。(注:~Base()纯虚拟的并不意味着它没有实现体。) - Ben Voigt
@BenVoigt:C++确实很奇怪。它可以将方法声明为纯虚函数(= 0),但仍然具有定义并且可调用。这正是像这样的析构函数发生的情况,因为它始终至少获得自动生成的定义。 - Jan Hudec
@BenVoigt 是正确的,这段代码有一个错误,有点证明了 OP 引用的观点..(同时也缺少 ~Base 的显式主体) - Neil Kirk
@NeilKirk:有一个版本可以编译(在“Base”的类体中添加“friend class Derived;”),但是专家们犯这个错误的数量很多(仅在此页面的答案中,我就数了四个错误的代码片段/解释)... - Ben Voigt
我在那段代码中看到了三个问题:
  1. 它不会编译,因为Derived看不到Base的析构函数。
  2. 即使析构函数不是私有的,它也无法链接,因为析构函数没有主体。应该在0后面加上{}。
  3. = 0什么也没做,因为Derived有隐式析构函数,并且不能强制使用此函数来获得显式析构函数。
- Simo Simov
显示剩余2条评论

5

4

不确定原始上下文,但我猜测是有人声称C++比Java等语言更简单。汤姆的观点是,C++拥有足够多的功能,使您可以轻松地创建非常复杂的结构。


3
这些话似乎有道理,但实际上并不是。此外,将两个不同的东西串在一起,试图过度复杂化问题,这表明作者只是想混淆人们,试图证明根本不存在的观点。
我们应该注意到,每种情况都是独特的,您可以根据情况构建类层次结构和析构函数。因为编程语言提供了这样的功能而称其过于复杂是愚蠢的。这就像说私有继承有什么意义。是的,通常你不会用它,但是在某些场合下使用它会很好。
另外,我认为:
- 我的类是抽象的。 - 析构函数必须是虚拟的。 - 但我不需要实现所以它是纯的。 - 我将使用protected继承。

纯虚函数并不意味着类不需要实现,它意味着子类必须提供一个实现(如果选择的话,该类也可以这样做)。 - KayEss

2
基本上,他只是随意把一堆词汇拼凑在一起,而没有意识到它们实际上指的是不同的事物,或者经常是同一件事情。
protected abstract virtual base

相当简单。
class Base { // BASE
    virtual something() = 0; // ABSTRACT
};
class Derived : protected virtual Base { // PROTECTED VIRTUAL
};

纯虚析构函数

这也很简单。

class Base { // BASE
private:
    virtual ~Base() = 0; // pure virtual, private, destructor
};
class Derived : Base {
};

当然,纯虚函数与抽象函数是相同的。

很明显,这是由一个对自己所写内容一无所知的人完全夸大其词。


3
我认为Tom Cargill 对这些词的含义有合理的想法。参见:http://www.amazon.com/C-Programming-Style-Tom-Cargill/dp/0201563657 - janm
1
@janm:他知道这些单词的含义,并不意味着他在将它们串联起来时有任何注意。值得注意的是,每个尝试使该程序工作的人(包括著名的Scott Meyers,在BR41N的回答中引用)都会产生非法代码。它可以工作,但需要一个“友元类”声明。 - Ben Voigt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接