我希望有些孩子(继承类)看不到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.
答案 0 :(得分:3)
使用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 ++方法。
答案 1 :(得分:1)
secretFunc
是一个独立的函数,任何看到它或声明的人都可以调用它。它与类方法的不同之处在于它无法访问调用它的类实例的成员。
答案 2 :(得分:1)
关于隐藏私有成员函数与自动完成的问题,它取决于您的IDE,但if you're using Visual Studio it looks like it isn't possible。 If you're using Qt Creator, it also looks like it isn't possible。我不确定Eclipse,但我怀疑它不可能。当我说“不可能”时,我的意思是在不改变你的代码的情况下是不可能的。 pimpl idiom可用于隐藏私有成员以及外部依赖项。当然,你的private pimpl
仍然可以通过自动完成看到,但它将是一个不完整的指针类型,因此它对用户没什么用处,而且它只是一个成员。
关于secretFunc
的问题,如果您secretFunc
static
,那么只有Parent.cpp才能查看和使用它。目前,任何其他源文件都可以说extern void secretFunc();
,然后开始使用secretFunc
。
如果你给它static
修饰符(static void secretFunc()
),那么它只能被源文件看到。链接器不会将它暴露给其他翻译单元。
答案 3 :(得分:0)
您可以拥有私有虚函数,并且可以在派生类中覆盖(但不调用)它们。正如他们所说,这种语言特征在狭义的圈子中广为人知。人们在生产代码中使用它。
因此,似乎隐藏IDE中的私人成员会适得其反。
在VS中,您可以使用一些预处理器技巧隐藏IntelliSense中的任何成员:
#ifndef __INTELLISENSE__
void ThisShouldNotBeSeen() {}
#endif
但这会将它从智能感知中隐藏,而不仅仅是在派生类中。这在开发父类本身时很不方便,因为您会收到大量虚假的IntelliSense错误和红色下划线。将此宏添加到您发布的头文件中可能很有用。
我不确定其他IDE。