隐藏儿童的功能

时间:2012-11-22 16:11:09

标签: c++

我希望有些孩子(继承类)看不到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.

4 个答案:

答案 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 possibleIf 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。