我有调用私有成员函数的公共成员函数。我想在私有成员函数定义可用的文件中限制私有成员函数的范围。在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.
}
答案 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)
解决这个问题的方法是使用所谓的“立面”。基本上,您有两个类:第一个类具有您要隐藏的私有方法,而第二个类实现了一个包装器,它只提供您想要访问的方法。第二个类包装了第一个类的实例。这就是整个技巧的运作方式。