对子级隐藏函数
Hiding functions from children
我希望一些子级(继承类)不要看到Parent类中的某些工作函数。我知道,将这些功能私有化意味着孩子们不能使用这些功能,但问题是他们会看到它们。我正在努力避免在自动完成中出现一堆"垃圾"的问题。
考虑到以上情况,我想出了一个主意。下面的代码。问题是,我不完全确定secretFunc的性质。这是一个全局函数还是在某种程度上属于Parent类?它没有在标头中声明,只是在cpp中定义。这个想法是,我可以在Parent中有一些这样的工作函数,然后这些函数将从Child类中隐藏。这是一种更精英的方式吗?即使有,我仍然想了解secretFunc的本质。
#ifndef PARENT_H
#define PARENT_H
class Parent
{
public:
Parent();
~Parent();
private:
void privateFunc();
protected:
void protectedFunc();
public:
void publicFunc();
};
#endif
#include "Parent.h"
//What is the nature of this function???
void secretFunc()
{
}
UnitTest::UnitTest()
{
}
UnitTest::~UnitTest()
{
}
void UnitTest::privateFunc()
{
}
void UnitTest::protectedFunc()
{
}
void UnitTest::publicFunc()
{
}
#ifndef CHILD_H
#define CHILD_H
#include "Parent.h"
class Child : public Parent
{
public:
Child();
~Child();
};
#endif
#include "Child.h"
UnitTest::Child()
{
}
UnitTest::~Child()
{
}
//Auto complete can see private Parent functions!
//Of course, child can't use them, but it can see them.
//I wish to hide these private functions from child.
//Auto complete can see and can also use protected Parent funcitons.
//As should be...
//Auto complete can see and can also use public Parent funcitons.
//As should be...
//secetFunc should be invisible.
使用secretFunc()
得到的基本上与使用privateFunc()
得到的相反。即:
privateFunc()
可见但不可访问(只有其他Parent
方法才能调用它)secretFunc()
不可见,但可以访问
详细说明,像secretFunc()
这样定义的自由函数在全局命名空间中,即使头文件中没有可用的声明。因此,任何其他与Parent.cpp
链接的文件中的代码都可以通过编写自己的声明来调用secretFunc()
,只要声明是正确的。
也就是说,Child.cpp
可能包含
void secretFunc();
在顶部,这使函数可见,然后Child.cpp
中的任何东西都可以调用secretFunc()
。
如果您所要做的只是使函数对自动完成不可见,那么这可能不是一个问题。但你可以同时实现隐形和不可接近。您需要做的是从全局命名空间中删除secretFunc
。您可以通过将它封装在一个匿名命名空间中来实现这一点。
所以在Parent.cpp
中,您写道:
namespace {
void secretFunc() {
// ...
}
}
这使得函数对于Parent.cpp
文件之外的任何东西都是不可见和不可访问的。如果Child.cpp
进行自己的声明(如上所述),链接器将产生错误,因为它将无法在全局命名空间中找到具有secretFunc
名称的函数。
注意,这与私有方法的不同之处在于:
- 可访问性仅限于
Parent.cpp
文件中的内容,而不是Parent
类 - 因为它不是
Parent
的类成员,所以它对Parent
对象没有特殊访问权限(也没有this
指针)
最后一件事。使用static
关键字而不是将函数封装在匿名命名空间中具有相同的效果,但这是一种C-ism。使用匿名名称空间是惯用的C++方法
secretFunc
是一个独立的函数,任何看到它或它的声明的人都可以调用它。它与类方法的不同之处在于,它不能访问调用它的类实例的成员
对于您关于隐藏私有成员函数以防止自动完成的问题,这取决于您的IDE,但如果您使用的是Visual Studio,这似乎是不可能的。如果你正在使用Qt Creator,它看起来也是不可能的。我不确定Eclipse,但我怀疑它也不可能。当我说"不可能"时,我的意思是不更改代码就不可能。皮条习惯用法可以用来隐藏私有成员以及外部依赖关系。当然,您的private pimpl
在自动完成时仍然可见,但它将是一个不完整的指针类型,因此它对用户没有多大用处,而且它只是一个成员。
对于您关于secretFunc
的问题,如果您将secretFunc
设为static
,那么只有Parent.cpp才能看到并使用它。按照目前的情况,任何其他源文件都可以说extern void secretFunc();
,然后开始使用secretFunc
。
如果你给它static
修饰符(static void secretFunc()
),那么它只能被它的源文件看到。链接器不会将它暴露给其他翻译单元。
您可以拥有私有虚拟函数,并且可以在派生类中重写(但不能调用)它们。正如他们所说,这种语言特征在狭隘的圈子里广为人知。人们正在生产代码中使用它。
因此,向IDE隐藏私人成员似乎会适得其反。
在VS中,您可以使用一个小的预处理器技巧来向IntelliSense隐藏任何成员:
#ifndef __INTELLISENSE__
void ThisShouldNotBeSeen() {}
#endif
但这将在任何地方对IntelliSense隐藏它,而不仅仅是在派生类中。这在开发父类本身时很不方便,因为您会得到很多虚假的IntelliSense错误和红色下划线。将此宏添加到您发布的头文件中可能会很有用。
我不确定其他IDE。
- 参数包构造函数在类模板中隐藏用户定义的转换
- 名称隐藏对静态函数继承的实例使用
- 从多个模板化基类派生时出现"隐藏重载的虚函数"警告
- 函数隐藏和重载之间的区别
- c++ 内联友元函数是否会导致命名空间之间的名称隐藏?
- 使用函数参数隐藏成员函数
- 函数的隐藏/锚定参数?
- 调用虚函数的逻辑不清楚(或者是方法隐藏?
- 隐藏私有过载的虚拟函数?
- static_assert:派生"must"中的某个函数隐藏了Base的类函数
- 在继承的类构造函数中使用隐藏成员
- C 如何使用隐藏的默认构造函数初始化成员
- 函数隐藏和使用C 中的函数
- 基的私有虚函数由派生的私有虚函数隐藏
- 为什么基类函数没有被同名的派生类函数隐藏
- C++朋友函数被类函数隐藏
- 为什么继承的函数隐藏在这个代码的基类中
- 基类模板成员函数隐藏在派生类中,尽管参数列表不同
- 为什么在使用初始值设定项列表时,非显式构造函数被显式构造函数隐藏
- 为什么派生类重载函数隐藏基类函数