在C++中,在什么情况下向前声明一个类是有意义的?

pjngdqdw  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(92)

我最近遇到了以下模式:

class A {
public:
    virtual void update() = 0;
    class B;
};

class A::B : public A {
public:
    virtual void update() {}
};

这里,B暴露在外部以被覆盖。
我的问题是,为什么将派生类定义为从基类继承的前向声明,而不仅仅是创建一个单独的类并重写update函数?
这似乎引入了不必要的耦合。

wpcxdonn

wpcxdonn1#

在类中声明或向前声明类并不能使其成为成员,它创建了类似于命名空间的东西。它通常是私有声明的,所以它的使用是在声明它的类内部进行的。派生创建紧耦合。

  • 在类中使用类的常见示例 *

一个常见的此类用途是在pimpl idiom的实现中。
通常它只是一个正向声明,然后定义在一个单独的cpp文件中,从而隐藏了实现。
隐瞒实施情况的理由各不相同;

  • 密码保密
  • 编译程序防火墙
  • 减少部分重建/编译时间

这似乎引入了不必要的耦合。类中用于派生用途的类
您的示例可能会使此复杂化,但问题在于细节,任何工厂或类名中的Intent的更多上下文可能会为您的代码示例提供更具体的见解。结果是编译器可以检查pimpl中是否实现了新的纯虚函数。
对于这个问题;
我的问题是,为什么将派生类定义为从基类继承的前向声明,而不仅仅是创建一个单独的类并重写update函数?
可能没有太多的意义,它将是高度特定的情况,缺乏更多的细节,上面的一般用例是一个很好的起点。

zfciruhq

zfciruhq2#

如果前提是将B嵌套在A中(对于嵌套类,有一些特殊的规则,例如名称查找和访问可能是相关的,参见下面的示例),那么你确实需要forward声明,因为你不能从不完整的类型继承:

class C {
    public:
        class B : public C {

        };
};

causes the compiler error

<source>:3:26: error: invalid use of incomplete type 'class C'
    3 |         class B : public C {
      |                          ^
<source>:1:7: note: definition of 'class C' is not complete until the closing brace
    1 | class C {
      |       ^

这是一个允许派生类访问封闭类的成员的例子,即使它是private

class C {
    private: 
       int x;
    public:
        class B;
};

class C::B : public C {
    void foo() { x = 42; }
};

(不过,我发现嵌套类的规则如此不直观和出乎意料,所以我通常会避免它们。
这似乎引入了不必要的耦合。
在你的例子中,这似乎是不必要的。虽然设计可能是由你从你的例子中遗漏的部分驱动的。

相关问题