下面是一些编译良好并运行良好的C++示例代码:
class A
{
public:
A() {/* empty */}
private:
friend void IncrementValue(A &);
int value;
};
void IncrementValue(A & a)
{
a.value++;
}
int main(int, char **)
{
A a;
IncrementValue(a);
return 0;
}
然而,我想要做的是将IncrementValue()声明为静态的,这样它就不会被其他编译单元看到或调用:
static void IncrementValue(A & a)
{
a.value++;
}
然而,这样做会给我一个编译错误:
temp.cpp: In function ‘void IncrementValue(A&)’:
temp.cpp:12: error: ‘void IncrementValue(A&)’ was declared ‘extern’ and later ‘static’
temp.cpp:8: error: previous declaration of ‘void IncrementValue(A&)’
..。并且将友元声明更改为match也没有帮助:
friend static void IncrementValue(A &);
..。因为它给出了这个错误:
temp.cpp:8: error: storage class specifiers invalid in friend function declarations
我的问题是,在C++中有没有办法让一个(非方法)朋友函数声明为静态的?
发布于 2016-12-03 00:49:22
虽然Praetorian的answer在技术上是正确的,因为它回答了您明确提出的问题,但我认为这不是一个有用的答案,因为他提出的建议既不合理,也不能满足您所声明的希望定义只能在friend类的翻译单元中调用的方法的目标。
他的解决方案有两个问题。首先,由于引用翻译模块中没有定义静态声明的友元函数这一错误,任何其它翻译单元都将无法编译,该翻译单元的头部包含以静态函数声明为首的类定义。其次,引用翻译单元可以通过定义静态声明的函数本身来消除编译错误,并且该定义将能够访问该函数被声明为朋友的类的所有私有数据。这表明朋友函数应该始终保留它们的默认公共链接,因为这可以防止由于公共链接函数的多个定义成为编译错误而导致的潜在封装漏洞。
我相信@engf在他对你的问题的评论中是正确的,你需要一个在同一个翻译单元中定义的朋友类,作为你希望它能够访问的类。例如。
// A.h
class A
{
public:
A() : _value(0) {}
private:
int _value;
friend struct A_Accessor;
};
// A.cpp
struct A_Accessor
{
static void IncrementValue(A& a)
{
++a._value;
}
};
TEST(StaticInit, IncrementA)
{
A a;
A_Accessor::IncrementValue(a);
}
这将以一种方式定义IncrementValue,允许它访问A的私有数据,但不能从A的转换模块外部引用。
https://stackoverflow.com/questions/19845478
复制相似问题