考虑使用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.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();
}
问题:
为什么在ClassB.hp中私有类的实现中,在ClassB.h中的一行上组合前向声明和变量声明需要 即。在ClassA.cpp中,私有类方法定义以 但在ClassB.cpp中,私有类方法定义以ClassB_Impl
“void ClassA::ClassA_Impl::foo() {...
void ClassB_Impl::foo() {...
每种方法的含义是什么?哪一个更好?
(响应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
的命名空间?他们为什么不同?
答案 0 :(得分:1)
为什么要组合前向声明和变量声明 ClassB.h中的一行要求ClassB_Impl为&#34; unscoped&#34;在里面 在ClassB.cpp中实现私有类?
因为在第一个示例中,您将ClassA_Impl
声明为ClassA
的内部类。
当您在{em>模板参数中声明ClassB_Impl
<{1}}
每种方法的含义是什么?哪一个更好?
这是一个意见问题。就个人而言,我认为内部课程是混乱的,而且难以获得很少的奖励。
我首选的方法使用单独的接口类,这有助于减少重新声明界面的次数。