请有人向我指出一些理解和使用嵌套类的好资源?我已经有一些材料,比如IBM知识中心 - 嵌套类之类的内容。
但我仍然很难理解它们的目的。请有人帮助我吗?
嵌套类很棒,可以隐藏实现细节。
列表:
class List
{
public:
List(): head(nullptr), tail(nullptr) {}
private:
class Node
{
public:
int data;
Node* next;
Node* prev;
};
private:
Node* head;
Node* tail;
};
这里我不想将 Node 公开,因为其他人可能会决定使用该类,这将阻碍我更新我的类,因为任何公开的部分都是公共 API 的一部分,必须永久维护。通过使类私有,我不仅隐藏了实现细节,还在说这是我的,我可以随时更改它,所以你不能使用它。
看看 std::list
或 std::map
,它们都包含隐藏的类(或者它们是否包含呢?)。重点是它们可能会或可能不会,但是因为实现是私有和隐藏的,STL 的构建者能够更新代码而不影响您使用代码,或留下许多旧代码在 STL 中,因为他们需要与决定使用 list
中隐藏的 Node 类的某些傻瓜保持向后兼容性。
Node
。 - Billy ONeal SomeSpecificCollection
,该类将聚合类 Element
的对象。然后,您可以:
SomeSpecificCollection
和 Element
- 不好,因为名称“ Element”足够通用,可能会导致可能的名称冲突 someSpecificCollection
并声明类 someSpecificCollection :: Collection
和 someSpecificCollection :: Element
。没有名称冲突的风险,但是否可以更冗长? SomeSpecificCollection
和 SomeSpecificCollectionElement
- 具有轻微的缺点,但可能是可以接受的。 SomeSpecificCollection
和类 Element
声明为其嵌套类。然后:
SomeSpecificCollection
时,您仅引用 Element
,并且在其他地方引用 SomeSpecificCollection :: Element
- 看起来与3.大致相同,但更清晰 SomeSpecificCollection
也是一个类。class Product {
public:
enum ProductType {
FANCY, AWESOME, USEFUL
};
enum ProductBoxType {
BOX, BAG, CRATE
};
Product(ProductType t, ProductBoxType b, String name);
// the rest of the class: fields, methods
};
那么,我们可以称之为:
Product p(Product::FANCY, Product::BOX);
Product::
的代码完成建议时,往往会列出所有可能的枚举值(BOX、FANCY、CRATE),在这里很容易犯错(虽然C++0x的强类型枚举有点解决了这个问题,但是不要在意)。class Product {
public:
struct ProductType {
enum Enum { FANCY, AWESOME, USEFUL };
};
struct ProductBoxType {
enum Enum { BOX, BAG, CRATE };
};
Product(ProductType::Enum t, ProductBoxType::Enum b, String name);
// the rest of the class: fields, methods
};
Product p(Product::ProductType::FANCY, Product::ProductBoxType::BOX);
Product::ProductType::
,将只建议所需范围内的枚举。这也减少了犯错误的风险。class X {
public:
X();
virtual ~X();
void publicInterface();
void publicInterface2();
private:
struct Impl;
std::unique_ptr<Impl> impl;
}
X.cpp:
#include "X.h"
#include <windows.h>
struct X::Impl {
HWND hWnd; // this field is a part of the class, but no need to include windows.h in header
// all private fields, methods go here
void privateMethod(HWND wnd);
void privateMethod();
};
X::X() : impl(new Impl()) {
// ...
}
// and the rest of definitions go here
如果完整的类定义需要来自某些外部库的类型定义,而该库具有庞大或丑陋的头文件(例如WinAPI),那么这将特别有用。如果使用PIMPL,则可以仅在.cpp
中封装任何WinAPI特定功能,并永远不要在.h
中包含它。
auto_ptr
,但从技术上讲,这是未定义行为。与 C++0x 中一些模板(例如 unique_ptr
)不同的是,已明确指出模板参数可以是不完整类型,并且必须完整确定该类型的位置(例如使用 ~unique_ptr
)。@Billy ONeal - CB Baileyunique_ptr
的模板参数T
可以是不完整类型。” - CB Baileyenum class
了,我应该更新一下。 - Kos我不常使用嵌套类,但有时会用到它们。特别是当我定义某种数据类型,然后想要定义一个适用于该数据类型的STL函数对象时。
例如,考虑一个通用的Field
类,它具有ID号码、类型代码和字段名称。如果我想按照ID号或名称搜索这些Field
对象组成的vector
容器,我可能会构造一个函数对象来实现:
class Field
{
public:
unsigned id_;
string name_;
unsigned type_;
class match : public std::unary_function<bool, Field>
{
public:
match(const string& name) : name_(name), has_name_(true) {};
match(unsigned id) : id_(id), has_id_(true) {};
bool operator()(const Field& rhs) const
{
bool ret = true;
if( ret && has_id_ ) ret = id_ == rhs.id_;
if( ret && has_name_ ) ret = name_ == rhs.name_;
return ret;
};
private:
unsigned id_;
bool has_id_;
string name_;
bool has_name_;
};
};
需要搜索这些 Field
的代码可以使用在 Field
类中定义的 match
:
vector<Field>::const_iterator it = find_if(fields.begin(), fields.end(), Field::match("FieldName"));
friend
。还包括同一类的成员函数,例如静态工厂方法。 - SasQ可以使用嵌套类实现建造者模式。特别是在C++中,我个人认为它的语义更加清晰。例如:
class Product{
public:
class Builder;
}
class Product::Builder {
// Builder Implementation
}
不是:
class Product {}
class ProductBuilder {}
typedef
实现与嵌套类相同的功能。class
声明中声明了两个概念上独立的对象等。