将静态函数声明为友元函数?

时间:2015-04-01 12:55:44

标签: c++

我在头文件MyClass中有一个类interface.h声明,在foo中有一些静态函数(barfile1.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。

链接类型:Is it possible to declare a friend function as static?

3 个答案:

答案 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