Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
319 views
in Technique[技术] by (71.8m points)

c++ - Declare a member-function of a forward-declared class as friend

Is it possible to declare a member function of a forward-declared class as friend? I am trying to do the following:

class BigComplicatedClass;

class Storage {
   int data_;
public:
   int data() { return data_; }
   // OK, but provides too broad access:
   friend class BigComplicatedClass;
   // ERROR "invalid use of incomplete type":
   friend void BigComplicatedClass::ModifyStorage(); 
};

So the goal is to (i) restrict the friend declaration to a single method, and (ii) not to include the definition of the complicated class to reduce compile time.

One approach might be to add a class acting as an intermediary:

// In Storage.h:
class BigComplicatedClass_Helper;
class Storage {
    // (...)
    friend class BigComplicatedClass_Helper;
};

// In BigComplicatedClass.h:
class BigComplicatedClass_Helper {
     static int &AccessData(Storage &storage) { return storage.data_; }
     friend void BigComplicatedClass::ModifyStorage();
};

However, this seems a bit clumsy... so I assume that there must be a better solution!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As @Ben says, it's not possible, but you can give specific access just to that member function through a "passkey". It works a bit like the intermediate helper class, but is imho clearer:

// Storage.h
// forward declare the passkey
class StorageDataKey;

class Storage {
   int data_;
public:
   int data() { return data_; }
   // only functions that can pass the key to this function have access
   // and get the data as a reference
   int& data(StorageDataKey const&){ return data_; }
};

// BigComplicatedClass.cpp
#include "BigComplicatedClass.h"
#include "Storage.h"

// define the passkey
class StorageDataKey{
  StorageDataKey(){} // default ctor private
  StorageDataKey(const StorageDataKey&){} // copy ctor private

  // grant access to one method
  friend void BigComplicatedClass::ModifyStorage();
};

void BigComplicatedClass::ModifyStorage(){
  int& data = storage_.data(StorageDataKey());
  // ...
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...