好的,这个问题已经发展了一些,我想尝试开始(过度)我正在拍摄的基本目标:
我经常遇到这种情况,我正在寻找更好的方法......
我有一个类,C在命名空间N.C有一个成员,Free.它免费是C管理的东西,并允许C管理新事物.
有几个全局免费功能.在与C相同的名称空间N中也有一些辅助函数,其中一个函数是一个帮助者,它释放由C管理的东西,名为free.
所以我们有类似的东西:
namespace N {
void free(THING * thing);
class C
{
public:
... details omitted...
free()
{
free(m_thing); // <- how best to refer to N::free(THING&)
}
}
} // namespace N
Run Code Online (Sandbox Code Playgroud)
我可以使用N :: free(m_thing).但这对我来说似乎很不幸.有没有办法引用类范围之外的但没有解析绝对命名空间(范围相对一步)?
在我看来,必须命名N :: free是令人讨厌的,因为如果这是一个独立的功能你就不必这么做.如果班级的方法名称恰好不同(例如处置),你也不需要.但是因为我使用了相同的名字,所以如果你放纵我的比喻,我就无法访问它而不必指定绝对路径的数量 - 而不是相对路径.
我讨厌绝对的道路.它们使名称空间中的移动变得非常脆弱,因此代码重构变得更加丑陋.此外,如何在函数体中命名事物的规则变得更加复杂,使用当前的规则集(正如我所理解的那样) - 不那么规律 - 在人们所期望的和作为程序员的人之间产生分裂.
是否有更好的方法来访问与类相同的命名空间中的独立函数,而不必绝对命名自由函数?
编辑:也许我应该用一个不太抽象的例子:
namespace Toolbox {
namespace Windows {
// deallocates the given PIDL
void Free(ITEMIDLIST ** ppidl);
class Pidl
{
public:
// create empty
Pidl() : m_pidl(NULL) { }
// create a copy of a given PIDL
explicit Pidl(const ITEMIDLIST * pidl);
// create a PIDL from an IShellFolder
explicit Pidl(IShellFolder * folder);
...
// dispose of the underlying ITEMIDLIST* so we can be free to manage another...
void Free();
};
Run Code Online (Sandbox Code Playgroud)
所以ITEMIDLIST*来自各个地方,并使用CoTaskMemFree()销毁.我可以将Pidl作为全局名称引入 - 以及作为我的工具箱库一部分的"Windows Shell.h"头中的所有辅助函数.
理想情况下,我会根据它们的相关内容对我的库中的一些工具进行分段 - 在这种情况下,上述所有工具都与Windows中的COM编程有关.我已选择Toolbox作为我的库的基本命名空间,并且目前认为我将使用Toolbox :: Windows用于非常windows-y的函数,类等.
但是C++命名空间和名称解析规则似乎使这非常困难(因此这个问题).创建代码的这种分段是非常不自然的 - 因为koenig查找失败(因为ITEMIDLIST不在我的Toolbox :: Windows命名空间中),而且我没有能力将其移动到那里!我也不应该这样.语言应该足够灵活,IMO,允许扩展库(如我的Toolbox库)扩展其他人的代码而不必将我的扩展注入其命名空间(在Win32和一般广大的情况下)今天存在的大多数代码都是GLOBAL NS--这首先是制作命名空间的全部要点:避免全局NS拥挤/污染/模糊/编程意外).
所以,我回过头来看,有没有更好的方法:扩展现有的代码库,同时不用我的扩展来污染他们的NS,但仍然允许直观和有用的名称解析,如果我的代码在他们的NS中但是我的代码客户端明确地介绍了(即我不想肆无忌惮地注入我的代码,但只是在明确请求时)?
另一个想法:如果我有以下内容,也许满足我上面的criterea会是什么:
using namespace X {
code here...
}
Run Code Online (Sandbox Code Playgroud)
我可以在任何地方放置这样的构造,包括在标题中,我不必担心将X拖入我的客户端的代码中,但是如果我在的话,我将有同样的自由来编写我的源代码.根命名空间.
我没有看到避免在free()这里限定命名空间范围,但应该注意这与"绝对路径"不同.首先,如果你有嵌套的命名空间,你只需要引用最里面的命名空间:
namespace N1 {
namespace N2 {
namespace N3 {
void free(THING * thing);
class C {
public:
free() {
N3::free(m_Thing); // no need to do N1::N2::
}
};
}
}
}
Run Code Online (Sandbox Code Playgroud)
[编辑]回应编辑过的问题.同样,我没有看到任何方法在您描述的确切场景中执行此操作.然而,它似乎不是惯用的C++方法 - 更常见的方法是提供自己的包装类来ITEMIDLIST管理所有分配,RAII风格,并暴露原始句柄(例如通过转换运算符a la ATL,或明确的成员函数,c_str()如果你想要额外的安全性).这将free完全取消您的需要,并且对于您可能想要的任何其他免费功能,因为您控制包装器类型和它所在的命名空间,您可以像往常一样使用ADL.
[编辑#2].这部分问题:
允许直观和有用的名称解析,如果我的代码在他们的NS中但由我的代码的客户端明确地引入(即我不想无缘无故地注入我的代码,但仅在明确请求时)?
这不正是你把它放在命名空间中,而你的客户端写作using namespace ...会实现吗?
| 归档时间: |
|
| 查看次数: |
2237 次 |
| 最近记录: |