需要术语或名称

时间:2015-06-11 00:20:50

标签: c++

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

2 个答案:

答案 0 :(得分:2)

听起来就像是pimpl的成语。它也有其他名称,例如cheshire cat。

如,

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。您可以看到它只存储数据成员和其他实现细节。

答案 1 :(得分:1)

我认为您在此处解释了很多问题:The Pimpl Idiom in practice

但是,好吧,因为你明确要求另一个答案:

  

"这种方法的名称是什么?"

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

模式通常如下所示:

<强> A.H:

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();
}
  

&#34;福利是什么?&#34;

包括A.h在内的任何代码都只会引用公共界面,并且由于AImpl的内部实施所做的更改,不需要重新编译。 为实现模块化和实现隐私,这是一项重大改进。