friends

  • Thread starter Kasper Middelboe Petersen
  • Start date
K

Kasper Middelboe Petersen

Hi,

I have:

class Process {
virtual void run();
...
};

class Processes : public Process {
...
private:
std::list<Process*> plist;
};

// helper function
void Run(Processes& p) {
p.run();
}

Now my wish is to only allow the member function run() to be invoked
from the helper function and nowhere else. This should be doable by
adding "friend void Run(Processes& p);" to the Processes class. The
run function in Processes basically is to go trough its plist running
the run function on each Process.

How do I make this possible without having run in Process declared as
public?


Thanks,
Kasper
 
K

Kai-Uwe Bux

Kasper said:
Hi,

I have:

class Process {
virtual void run();
...
};

class Processes : public Process {
...
private:
std::list<Process*> plist;
};

// helper function
void Run(Processes& p) {
p.run();
}

Now my wish is to only allow the member function run() to be invoked
from the helper function and nowhere else. This should be doable by
adding "friend void Run(Processes& p);" to the Processes class. The
run function in Processes basically is to go trough its plist running
the run function on each Process.

How do I make this possible without having run in Process declared as
public?

Interesting idea: regard a list of processes as a process itself. So, maybe,
it would be appropriate to ditch the helper function. Something like that:

class Process {
protected: // maybe, this should be public
virtual void run ();
...
};

class ProcessSequence : protected Process {
private:
typedef std::list< Process* > process_list;
process_list all_processes;
protected: // maybe, this should be public
virtual void run () {
for ( process_list::iterator iter = all_processes.begin();
iter != all_processes.end(); ++iter ) {
iter->run();
}
}
};

Warning: the above is untouched by any compiler, so it probably contains
typos. But it should get across the idea.


One thing makes me wonder, though: why is run() not public? Do you not want
your processes to run? At some point, someone has to call it.


Best

Kai-Uwe Bux
 
K

Kasper Middelboe Petersen

Interesting idea: regard a list of processes as a process itself. So, maybe,
it would be appropriate to ditch the helper function. Something like that:

class Process {
protected: // maybe, this should be public
  virtual void run ();
  ...

};

class ProcessSequence : protected Process {
private:
  typedef std::list< Process* > process_list;
  process_list all_processes;
protected: // maybe, this should be public
  virtual void run () {
    for ( process_list::iterator iter = all_processes.begin();
          iter != all_processes.end(); ++iter ) {
      iter->run();
    }
  }

};

Warning: the above is untouched by any compiler, so it probably contains
typos. But it should get across the idea.

Won't the "iter->run();" fail unless run in Process is declared as
public?
My similar code did, which prompted the post after not being able to
figure out how to friend it.

One thing makes me wonder, though: why is run() not public? Do you not want
your processes to run? At some point, someone has to call it.

I'm creating a CSP library. My Processes can either be run in sequence
or in parallel. Part of my goal of this library is to mentain focus on
compositional semantics. I've struggled quite a bit with making an
interface I like and have ended up with:

Run( InParallel
( new MyProcess(...) )
( new MyProcess(...) )
( InSequence
( new MyProcess(...) )
( new MyProcess(...) )
( new MyProcess(...) )
)
);

I want to enforce using this way, and only this way, to start the CSP
network. This could be accomplished by not allowing any access to
run() (or any of the other functions that I'm also forced to have as
public at the momement) from other functions than the Run helper
function.


/Kasper
 
K

Kai-Uwe Bux

Kasper said:
Won't the "iter->run();" fail unless run in Process is declared as
public?
My similar code did, which prompted the post after not being able to
figure out how to friend it.

Interesting. It appears that a friend declaration is required even though
ProcessList inherits from Process. The call (*iter)->run() does not qualify
as a call to the accessible member function of the base class. However,
something like this->Process::run() compiles.

Anyway, here is where to put the friend:

#include <list>

class Process {
protected:
virtual void run () {};
friend class ProcessSequence;
};

class ProcessSequence : public Process {
private:
typedef std::list< Process* > process_list;
process_list all_processes;
protected:
virtual void run () {
for ( process_list::iterator iter = all_processes.begin();
iter != all_processes.end(); ++iter ) {
(*iter)->run();
}
}
};

int main ( void ) {}

I'm creating a CSP library. My Processes can either be run in sequence
or in parallel. Part of my goal of this library is to mentain focus on
compositional semantics. I've struggled quite a bit with making an
interface I like and have ended up with:

Run( InParallel
( new MyProcess(...) )
( new MyProcess(...) )
( InSequence
( new MyProcess(...) )
( new MyProcess(...) )
( new MyProcess(...) )
)
);

I want to enforce using this way, and only this way, to start the CSP
network. This could be accomplished by not allowing any access to
run() (or any of the other functions that I'm also forced to have as
public at the momement) from other functions than the Run helper
function.

Ah, I see.


Best

Kai-Uwe Bux
 
K

Kasper Middelboe Petersen

Won't the "iter->run();" fail unless run in Process is declared as
Interesting. It appears that a friend declaration is required even though
ProcessList inherits from Process. The call (*iter)->run() does not qualify
as a call to the accessible member function of the base class. However,
something like this->Process::run() compiles.

Makes sense it doesn't work - keep in mind its two different objects.
They should have access to each others private parts just because they
have the same type.

  friend class ProcessSequence;
Exactly what I was looking for. It works perfectly now - thanks! :)
 
K

Kasper Middelboe Petersen

Makes sense it doesn't work - keep in mind its two different objects.
They should have access to each others private parts just because they
have the same type.

Typo - Meant to write: They should *not* have access
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,078
Latest member
MakersCBDBlood

Latest Threads

Top