我的班级使用PImpl习语,看起来像这样:
// In LongDescriptiveClassName.hpp
class LongDescriptiveClassName
{
public:
// Stuff...
private:
struct LongDescriptiveClassNameData;
LongDescriptiveClassNameData &Data;
};
在.cpp文件中,我声明/定义私有结构:
// In LongDescriptiveClassName.cpp
struct LongDescriptiveClassName::LongDescriptiveClassNameData
{
void PrivateMethod1();
void PrivateMethod2();
// and so on...
};
void LongDescriptiveClassName::LongDescriptiveClassNameData::PrivateMethod1()
{
// Stuff...
}
void LongDescriptiveClassName::LongDescriptiveClassNameData::PrivateMethod2()
{
// Stuff...
}
这对我来说很难读。 有没有办法可以缩写导致私有方法的名称?
我的理解是我不能在.cpp文件中typedef
因为PImpl结构是私有的。使用#define
会不会是一种恶魔?
#define ShortName LongDescriptiveClassName::LongDescriptiveClassNameData
struct ShortName
{
// ...
};
void ShortName::PrivateMethod1()
// ...
此.cpp文件是唯一需要缩写它的源文件,然后仅用于方法定义。你推荐什么?
答案 0 :(得分:3)
类名已经是命名空间了,所以没有理由给impl这么长的名字:
class LongDescriptiveClassName
{
public:
// Stuff...
private:
struct Impl;
// shared_ptr is also an option if that's
// the semantics you want.
std::unique_ptr<Impl> Data;
};
// and off in the implementation, we have...
struct LongDescriptiveClassName::Impl
{
void PrivateMethod1();
void PrivateMethod2();
// and so on...
};
void LongDescriptiveClassName::Impl::PrivateMethod1()
{
// Stuff...
}
它运作得很好。
顺便说一下,你的代码不是pimpl习语的例子。 “pimpl”中的“p”表示“指针”,这很重要。引用意味着该对象不拥有其实现。
这不一定是错的;有时候有充分的理由在类中包装引用,但它不是pimpl习语。
答案 1 :(得分:0)
我不完全确定您的问题,但似乎正确使用using
关键字应该会有很大帮助。不是
using ShortName = LongDescriptiveClassName::LongDescriptiveClassNameData
你在找什么?
请注意,这只是LongDescriptiveClassNameData
的工作类型而不是数据。
答案 2 :(得分:0)
虽然@ Pseudonym的解决方案绝对正常,但我更喜欢使用带有初始大写的名称仅用于类型,所以我想我只是这样做:
class LongDescriptiveClassName {
private:
struct Data;
Data &data;
};
答案 3 :(得分:0)
我喜欢称之为Impl
或Detail
(尽管后者常见于namespace detail
)。