我在头文件MyClass
中有一个类interface.h
声明,在foo
中有一些静态函数(bar
和file1.cpp
以及更多)。静态函数仅在file1.cpp
内使用,但它们需要修改MyClass`的私有/受保护成员。
// in "interface.h"
class MyClass {
// maybe declare as friend?
// friend static void foo(MyClass &ref);
private:
double someval;
}
// in "file1.cpp"
static void foo(MyClass &ref) {
ref.someval = 41.0;
}
static void bar(MyClass &ref) {
ref.someval = 0.42;
}
// function that uses foo/bar
void doSomething(MyClass &ref) {
foo(ref);
}
创意1 :以某种方式宣称他们是MyClass
的朋友?
为什么它不好:它们是静态的并且位于不同的编译单元中。除此之外,它会将它们暴露给MyClass
的用户,他们不需要了解任何有关它们的信息。
创意2 :没有想法2。
答案 0 :(得分:3)
链接类型:是否可以将友元函数声明为静态?
就我个人而言,我发现整个friend
的东西有点破坏封装,但你问了一个有效的问题,答案是你可以用帮助器实现你想要的东西上课:
<强> file1.h 强>
class MyClass {
private:
double someval;
friend class MyClassHelper;
};
<强> file1.cpp 强>
#include "file1.h"
struct MyClassHelper {
static void mutateMyClass(MyClass& ref) {
ref.someval=42;
}
};
// in "file1.cpp"
static void foo(MyClass &ref) {
MyClassHelper::mutateMyClass(ref);
}
你真的确定要这样做吗?你确定你不想在MyClass本身中封装MyClass的mutators吗?
答案 1 :(得分:0)
听起来很奇怪(看起来很棒),你实际上可以读到&amp;写一个类/结构的私有成员。
它不漂亮,当然不鼓励,但可行。
template<typename T>
struct invisible
{
static typename T::type value;
};
template<typename T>
typename T::type invisible<T>::value;
template<typename T, typename T::type P>
class construct_invisible
{
construct_invisible(){ invisible<T>::value = P; }
static const construct_invisible instance;
};
template<typename T, typename T::type P>
const construct_invisible<T, P> construct_invisible<T, P>::instance;
struct MyClass_someval{ typedef double MyClass::*type; };
template class construct_invisible<MyClass_someval, &MyClass::someval>;
static void foo(MyClass &ref) {
ref.*invisible<MyClass_someval>::value = 41.0;
}
当我第一次看到它时,我也想:HOLY S ***!
答案 2 :(得分:0)
// in "interface.h"
class MyClass {
// maybe declare as friend?
// friend static void foo(MyClass &ref);
public:
friend class SetSomevalClass; // make the classes friends
private:
double someval;
};
class SetSomevalClass // functor class(or function class)
{
public:
double operator()(MyClass n, double data) // this could have been void
{
n.someval = data; //set somevalue to data
return n.someval; //return somevalue
// return is solely used to show result in foo() and bar()
}
};
// in "file1.cpp"
static void foo(MyClass &ref)
{
SetSomevalClass s; //create functor object
//s(ref, 40);
//this would be the end of the foo function(uncommented) if we did not want to show the result
std::cout << "foo()" << s(ref, 40) << std::endl;
//simply to show result
}
static void bar(MyClass &ref)
{
SetSomevalClass s;
//s(ref,2);
//this would be the end of the foo function(uncommented) if we did not want to show the result
std::cout << "bar()" << s(ref, 2) << std::endl;
}
// function that uses foo/bar
void doSomething(MyClass &ref) //calls both foo() and bar()
{
foo(ref);
bar(ref);
}
int main()
{
MyClass s;
doSomething(s);
}// end main