【问题标题】:Terminology or name required需要术语或名称
【发布时间】:2015-06-11 00:20:49
【问题描述】:

在许多 C++ 源代码中,我看到在设计一个可能是子类的类时,有一个前向声明或对另一个类似名称的类的引用,并在原始类名的末尾附加了 privatePrivate .例如,在 Qt 中有一个名为 QGraphicsItem 的类,并且在头文件的开头有一个 QGraphicsItemPrivate 的前向声明。我尝试查看设计模式名称并搜索谷歌试图查看是否可以找到这种设计技术或方法的名称,但它没有产生任何结果。这种方法的名称是什么?什么是/是什么好处?

【问题讨论】:

  • “感谢您提供链接或参考一些文章以供进一步阅读。” 到目前为止,它被欺骗了。你也可以这样,而不是自己写一个答案?
  • @πάνταῥεῖ 我所需要的只是进一步研究它的名称。我试图向机器人(又名谷歌)描述一种编程语言技术的努力毫无意义。如果您认为有什么好知道但很难找到,请继续写一个答案。
  • @Barracuda -- 一个代码示例会很棒。
  • @Soren 我不这么认为。问题在于找到设计技术的技术术语。描述中提供的类名属于一个名为 Qt 的开源免费软件,该软件可在 Internet 上轻松获得。

标签: c++


【解决方案1】:

听起来像 pimpl 成语。它也有其他名字,例如,柴郡猫。

例如,

class FooPrivate;
class Foo
{
public:
    Foo();
    ~Foo();
    int GetInt();
private:
    FooPrivate* implPtr;
};

在实现文件中,

class FooPrivate
{
    public:
    int x = 0;
};

Foo::Foo() : implPtr(new FooPrivate()) {}

Foo::~Foo() { delete implPtr; }

int Foo::GetInt()
{
    return implPtr->x;
}

用于隐藏 Foo 的实现细节。所有数据成员和私有方法都存储在 Private 中。这意味着实现的更改不需要使用 Foo 重新编译每个 cpp 文件。

在 Qt 源代码中,它位于 qgraphicsitem_p.h。你可以看到它只存储数据成员和其他实现细节。

【讨论】:

    【解决方案2】:

    我认为您的很多问题都在这里得到了解释:The Pimpl Idiom in practice

    但是,既然您明确要求另一个答案:

    “这种方法叫什么名字?”

    它被广泛称为Pimpl idiom,还有其他(可能更严重的)等效术语正在使用,例如不透明指针)。

    模式通常如下所示:

    啊:

    class AImpl;
    
    class A {
    public:
        A();
        ~A();
        void foo();
        void bar();
    private:
        AImpl* pimpl;
    };
    

    A.cpp:

    // Changing the following code won't have impact for need to recompile 
    // external dependants
    // *******************************************************************
    // * Closed black box                                                *
    // *******************************************************************
         struct AImpl {
            void foo();
            void bar();
         };
    
    // *******************************************************************
    // * lengthy implementation likely to change internally goes         *
    // * here                                                            *
    // *******************************************************************
         void AImpl::foo() {
         }
         void AImpl::bar() {
         }
    // * /Closed black box                                               *
    // *******************************************************************
    
    // The public interface implementation just delegates to the
    // internal one:
    A::A() : pimpl(new AImpl()) { 
    }
    
    A::~A() { 
        delete pimpl;
    }
    
    void A::foo() {
        pimpl->foo();
    }
    
    void A::bar() {
        pimpl->bar();
    }
    

    “什么是好处?”

    包括A.h在内的任何代码都只是引用公共接口,由于AImpl的内部实现发生了变化,不需要重新编译。
    这是一个很大的改进,可以实现模块化和实现隐私。

    【讨论】:

    • 很抱歉,但必须在此处指出,因为无法在编辑中修复单个字符。在类A构造函数实现中,pinpl必须改为pimpl
    猜你喜欢
    • 2015-07-26
    • 1970-01-01
    • 2016-02-15
    • 1970-01-01
    • 1970-01-01
    • 2011-12-26
    • 2017-04-07
    • 1970-01-01
    • 2014-11-13
    相关资源
    最近更新 更多