2

我希望一些孩子(继承类)看不到父类中的某些工作功能。我知道将这些设为私有意味着孩子们无法使用这些功能,但问题是他们会看到它们。我试图避免在自动完成中出现一堆“垃圾”的问题。

考虑到上述情况,我想出了一个主意。代码如下。问题是我不完全确定 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

4 回答 4

3

你得到secretFunc()的本质上与你得到的相反privateFunc()。那是:

  • privateFunc()可见但不可访问(只有其他Parent方法可以调用它)。
  • secretFunc()不可见,但可访问。

详细地说,一个定义为 like 的自由函数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++ 方式。

于 2012-11-22T16:38:36.723 回答
1

secretFunc是一个独立的函数,任何看到它或其声明的人都可以调用它。它与类方法的不同之处在于它无法访问调用它的类实例的成员。

于 2012-11-22T16:18:09.510 回答
1

对于您关于从自动完成中隐藏私有成员函数的问题,这取决于您的 IDE,但如果您使用的是 Visual Studio,它看起来是不可能的如果您使用的是 Qt Creator,它看起来也是不可能的。我不确定 Eclipse,但我怀疑它也不可能。当我说“不可能”时,我的意思是如果不更改您的代码就不可能。pimpl习惯用法可用于隐藏私有成员以及外部依赖项。当然,您private pimpl仍然可以通过自动完成看到,但它是一个不完整的指针类型,所以它对用户没有多大用处,它只是一个成员。

对于您关于 的问题secretFunc,如果您制作secretFunc static,那么只有 Parent.cpp 才能看到和使用它。就目前而言,任何其他源文件都可以说extern void secretFunc();然后开始使用secretFunc.

如果你给它static修饰符(static void secretFunc()),那么它只能被它所在的源文件看到。链接器不会将它暴露给其他翻译单元。

于 2012-11-22T16:20:07.363 回答
0

您可以拥有私有虚函数,并且可以在派生类中覆盖(但不能调用)它们。正如他们所说,这种语言功能在狭窄的圈子中广为人知。人们在生产代码中使用它。

因此,对 IDE 隐藏私有成员似乎会适得其反。

在 VS 中,您可以使用一些预处理器技巧从 IntelliSense 隐藏任何成员:

#ifndef __INTELLISENSE__    
void ThisShouldNotBeSeen() {}
#endif

但这会将它隐藏在任何地方的 IntelliSense 中,而不仅仅是在派生类中。这在开发父类本身时很不方便,因为您会得到很多虚假的 IntelliSense 错误和红色下划线。将此宏添加到您发布的头文件中可能很有用。

我不确定其他 IDE。

于 2012-11-22T17:26:35.203 回答