Pimpl,私有类前向声明​​,范围解析运算符

时间:2016-02-08 06:25:46

标签: c++ forward-declaration pimpl-idiom scope-resolution

考虑使用Pimpl习语的这两个类:

ClassA:Pimpl类前向声明​​和单独行上的变量声明

ClassA.h:

#include <memory>

class ClassA {
public:
    ClassA();
    ~ClassA();
    void SetValue( int value );
    int GetValue() const;

private:

    class ClassA_Impl;
    // ^^^^^^^^^^^^^^ class forward declaration on its own line

    std::unique_ptr<ClassA_Impl> m_pImpl;
    // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ variable declaration on its own line

    //EDIT:
    //Even if we use a raw pointer instead of a smart pointer,
    //i.e. instead of declaring the smart pointer above, if we declare:
    ClassA_Impl *m_pImpl;
    //the situation in the *.cpp files and my questions (below) are the same.


};

ClassA.cpp:

#include "ClassA.h"

class ClassA::ClassA_Impl {
public:
    void SetValue( int value );
    int GetValue() const;
private:
    int value_;   
};

// Private class implementation
void
ClassA::ClassA_Impl::SetValue( int value ) {
    value_ = value;
}

int
ClassA::ClassA_Impl::GetValue() const {
    return value_;
}

// ClassA implementation
ClassA::ClassA() : m_pImpl( new ClassA_Impl() ) {}

ClassA::~ClassA() {}

void
ClassA::SetValue( int value ) {
    m_pImpl->SetValue( value );
}

int
ClassA::GetValue() const {
    return m_pImpl->GetValue();
}

ClassB:一行上的Pimpl类前向声明​​和变量声明

ClassB.h:

#include <memory>

class ClassB {
public:
    ClassB();
    ~ClassB();
    void SetValue( int value );
    int GetValue() const;

    private:
        std::unique_ptr<class ClassB_Impl> m_pImpl;
        //             ^^^^^^^^^^^^^^^^^^ class forward declaration
        //             combined with variable declaration on one line,
        //             in one shot.

        //EDIT:
        //Even if we use a raw pointer instead of a smart pointer,
        //i.e. instead of declaring the smart pointer above, if we declare:
        class ClassB_Impl *m_pImpl;
        //the situation in the *.cpp files and my questions (below) are the same.
};

ClassB.cpp:

#include "ClassB.h"

class ClassB_Impl {
public:
    void SetValue( int value );
    int GetValue() const;
private:
    int value_;
};

// Private class implementation
void
ClassB_Impl::SetValue( int value ) {
    value_ = value;
}

int
ClassB_Impl::GetValue() const {
    return value_;
}

// ClassB implementation
ClassB::ClassB() : m_pImpl( new ClassB_Impl() ) {}

ClassB::~ClassB() {}

void
ClassB::SetValue( int nValue ) {
    m_pImpl->SetValue( nValue );
}

int
ClassB::GetValue() const {
    return m_pImpl->GetValue();
}

问题:

  1. 为什么在ClassB.hp中私有类的实现中,在ClassB.h中的一行上组合前向声明和变量声明需要ClassB_Impl

    即。在ClassA.cpp中,私有类方法定义以

    开头
    void ClassA::ClassA_Impl::foo() {...
    

    但在ClassB.cpp中,私有类方法定义以

    开头
    void ClassB_Impl::foo() {...
    
  2. 每种方法的含义是什么?哪一个更好?

  3. 响应Galik回答的后续问题

    当你在一个语句中组合一个类的前向声明和该类的变量的声明时......

    //one-liner
    class ClassB_Impl *m_pImpl;
    

    ......这叫什么?这种合并声明有名称吗?那么为什么ClassB_Impl不会因为这样的陈述而成为ClassB的内部类?

    将此与...比较

    //two-liner
    class ClassA_Impl;
    ClassA_Impl *m_pImpl;
    

    ...在这种情况下,ClassA_Impl 成为ClassA的内部类。

    为什么单行将ClassB_Impl放入全局名称空间,而双行将ClassA_Impl放入ClassA的命名空间?他们为什么不同?

1 个答案:

答案 0 :(得分:1)

  

为什么要组合前向声明和变量声明   ClassB.h中的一行要求ClassB_Impl为&#34; unscoped&#34;在里面   在ClassB.cpp中实现私有类?

因为在第一个示例中,您将ClassA_Impl声明为ClassA内部类

当您在{em>模板参数中声明ClassB_Impl <{1}}

  

每种方法的含义是什么?哪一个更好?

这是一个意见问题。就个人而言,我认为内部课程是混乱的,而且难以获得很少的奖励。

我首选的方法使用单独的接口类,这有助于减少重新声明界面的次数。

请参阅: Is it possible to write an agile Pimpl in c++?