如何在c ++中定义的同一文件中限制函数作用域?

时间:2016-02-04 06:42:44

标签: c++

我有调用私有成员函数的公共成员函数。我想在私有成员函数定义可用的文件中限制私有成员函数的范围。在C中,我在函数名之前使用static来限制它在文件中的范围,我如何在C ++中实现它。

class Base
{
  public:
  void XYZ1(void);
  void XYZ2(void);
  private:
  void fun(void);
};

void Base::XYZ1(void)
{
  fun();
}

void Base::fun(void)
{
  // do something;
}

现在,如果在其他.cpp文件中定义了成员函数XYZ2,则不应该允许它从中调用fun()。基本上将fun()函数限制为文件范围。 在a1.cpp中

void Base::XYZ2(void)
{
  fun();// this should result in some error saying fun() is not defined in its scope.
}

5 个答案:

答案 0 :(得分:6)

  

我想在私有成员函数定义可用的文件中限制私有成员函数的范围。

private成员函数不能被其他类或函数使用,除非它们被授予friend - 由类发布。从这个意义上说,可以调用函数的范围已经是有限的。

话虽如此,该类的任何成员函数或已被授予friend的任何类或函数 - 都可以调用private成员函数。

阻止在定义它的文件之外调用该函数的唯一方法是使其成为.cpp文件中的非成员static函数。或者将它放在.cpp文件中的匿名命名空间中。

答案 1 :(得分:2)

  

现在,如果在其他.cpp文件中定义了成员函数XYZ2,   不应该允许它从中调用fun()。基本上限制了   fun()函数到文件范围。在a1.cpp中

您可以将该函数放在匿名命名空间中(在使用的cpp文件中)。链接将变为内部链接,并且该名称将无法从任何其他文件进行访问。在使函数静态时(在cpp文件中)可以获得相同的效果。

如果您需要访问内部/私有成员,您可以使用嵌套类,该实现是在关联的cpp文件中定义的:

//h
class Nesting
{
    //...
  private:
    struct MyPrivateFunctions;
};

//cpp

struct Nesting::MyPrivateFunctions
{
  static void f1(Nesting& this);
  static void f2(Nesting& this);
  //etc...
};

我已经通过Nesting作为MyPrivateFunctions可以访问其私有成员的参数(因为它是嵌套的,这是允许的。)

请注意,这与其他地方提到的Impl技巧非常相似,但它也允许其他单元中的独立成员函数定义,并且不需要实例化。

答案 2 :(得分:1)

如果您不想向外部显示课程的“隐藏”功能,您也可以使用旧的Impl-技巧。毕竟,私有函数仍然列在头文件中。

// Foo.h
class FooImpl; // forward declearation
class Foo
{
    FooImpl *m_pImpl;
    public:
    Foo(); // Default constructor (and any other) create instance of FooImpl.
    ~Foo();
};

// Foo.cpp
class FooImpl
{
   // members of hidden types, secrets, methods, ... anything you do not want to show to users of class Foo.
};
Foo::Foo() : m_pImpl(new FooImpl()) {}
Foo::~Foo() 
{
     delete m_pImpl; m_pImpl = nullptr;
}

可以看出,使用impl技巧,您不仅可以隐藏函数,还可以隐藏类的数据成员,并且如果成员属于Foo类,则会产生依赖关系。

答案 3 :(得分:1)

大多数人建议您在C ++中使用匿名名称空间。但是,只有在您想做一些事情时才可行,例如声明一个全局变量/函数,该变量/函数应严格在定义它的文件内部使用。

我们不能按照C ++标准在类中使用名称空间,对此,您可能需要看一下下面的讨论:Why can't we declare a namespace within a class?

  

我在函数名称前使用了static来限制其在文件中的作用范围。

这对您有用,但是这里的理解是错误的,因为从不打算将static用作作用域说明符,它是一个存储说明符,并且其生命周期贯穿于整个程序生命周期。您仍然可以通过几种方式从其他文件访问静态变量,但是此处的编译器未提供外部可见的链接器符号,因此其他翻译单元/文件无法访问该

就公共成员函数而言,应允许它们在定义了文件的任何文件中使用此私有函数。这样就不会破坏类成员函数之间的关系。我想您现在将不再将static视为作用域说明符:)

答案 4 :(得分:0)

解决这个问题的方法是使用所谓的“立面”。基本上,您有两个类:第一个类具有您要隐藏的私有方法,而第二个类实现了一个包装器,它只提供您想要访问的方法。第二个类包装了第一个类的实例。这就是整个技巧的运作方式。

https://en.wikipedia.org/wiki/Facade_pattern