473,402 Members | 2,055 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,402 software developers and data experts.

Strange friend ordering

My current project involves reading a particular data format.

It would be convenient to be able to do something like:

class DataClass {
friend bool FileRunner::read_data (const vector<string>&);
...
};

class OtherDataClass {
friend bool FileRunner::read_data (const vector<string>&);
...
};

class FileRunner {
DataClass m_data;
OtherDataClass m_data2;
bool read_data (const vector<string>&);
...
};

However that gives the error:
error: member 'bool FileReader::read(std::string)' declared as friend
before type 'FileRunner' defined

Why I don't want to simply make FileRunner a friend class: FileRunner
is the workhorse class of the program; I want to make sure that all
post-initialization access goes through the appropriate accessors, and
I want to be sure that certain parts aren't changed after
initialization.

Why I don't split off the reading parts into a separate class and make
that whole class a friend: The reading parts need access to some of
the running functions.

Why I don't do all the initialization in the DataClass's constructor:
The initialization process needs to be able to call other functions in
FileRunner, and isn't isolatable to a single point.

I'm planning on rewriting it to be a single external function (friend
to all needed classes) with an added FileRunner& argument, but because
it references fields within FileRunner heavily, that would be very
tedious. Any alternatives?

(I did not design the file format.)

Feb 23 '07 #1
6 1717
ra***********@gmail.com wrote:
My current project involves reading a particular data format.

It would be convenient to be able to do something like:

class DataClass {
friend bool FileRunner::read_data (const vector<string>&);
If the compiler doesn't know what 'FileRunner' is, it cannot allow
you to declare a member of an unknown class as a friend.
...
};

class OtherDataClass {
friend bool FileRunner::read_data (const vector<string>&);
...
};

class FileRunner {
DataClass m_data;
OtherDataClass m_data2;
bool read_data (const vector<string>&);
...
};

However that gives the error:
error: member 'bool FileReader::read(std::string)' declared as friend
before type 'FileRunner' defined
Right.
Why I don't want to simply make FileRunner a friend class: FileRunner
is the workhorse class of the program; I want to make sure that all
post-initialization access goes through the appropriate accessors, and
I want to be sure that certain parts aren't changed after
initialization.
That's unclear, sorry. Whose accessors are we talking about here?
Why I don't split off the reading parts into a separate class and make
that whole class a friend: The reading parts need access to some of
the running functions.
OK.
Why I don't do all the initialization in the DataClass's constructor:
The initialization process needs to be able to call other functions in
FileRunner, and isn't isolatable to a single point.
Unclear again. If you pass your 'FileRunner' to the c-tor of DataClass,
what's exactly not isolatable?
I'm planning on rewriting it to be a single external function (friend
to all needed classes) with an added FileRunner& argument, but because
it references fields within FileRunner heavily, that would be very
tedious. Any alternatives?
Tedious? Why do you need friendship here at all? Have you thought of
creating a special [possibly base] class in each DataClass and allow it
access to DataClass internals? It's kind of backwards, maybe, but it
works around the forward-declarations...

class DataClass {
public:
class DataClassAccessor; // should have access to all of DataClass.
...
};

class FileRunner {
...
};

class DataClass::DataClassAccessor {
friend bool FileRunner::read_data(...
...
};

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Feb 23 '07 #2
On Feb 23, 1:52 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
ralphmerri...@gmail.com wrote:
My current project involves reading a particular data format.
It would be convenient to be able to do something like:
class DataClass {
friend bool FileRunner::read_data (const vector<string>&);

If the compiler doesn't know what 'FileRunner' is, it cannot allow
you to declare a member of an unknown class as a friend.
Actually, I also had the line "class FileRunner;" above the
declaration.

However that gives the error:
error: member 'bool FileReader::read(std::string)' declared as friend
before type 'FileRunner' defined

Right.
Why I don't want to simply make FileRunner a friend class: FileRunner
is the workhorse class of the program; I want to make sure that all
post-initialization access goes through the appropriate accessors, and
I want to be sure that certain parts aren't changed after
initialization.

That's unclear, sorry. Whose accessors are we talking about here?
I did not explictly list them, but accessors for DataClass and
OtherDataClass.
Why I don't split off the reading parts into a separate class and make
that whole class a friend: The reading parts need access to some of
the running functions.

OK.
Why I don't do all the initialization in the DataClass's constructor:
The initialization process needs to be able to call other functions in
FileRunner, and isn't isolatable to a single point.

Unclear again. If you pass your 'FileRunner' to the c-tor of DataClass,
what's exactly not isolatable?

I'm planning on rewriting it to be a single external function (friend
to all needed classes) with an added FileRunner& argument, but because
it references fields within FileRunner heavily, that would be very
tedious. Any alternatives?

Tedious? Why do you need friendship here at all? Have you thought of
Tedious in that I'd have to explicitly say 'file_runner_arg.whatever'
instead of 'whatever' thoroughout the code.

I'd have to get into the exact details of the original format (which
isn't even well specified) and my implementation to explain why I need
all the friendship. Barring that, just take my word that the code
doesn't break up well.
creating a special [possibly base] class in each DataClass and allow it
access to DataClass internals? It's kind of backwards, maybe, but it
works around the forward-declarations...
How would that work?

Feb 23 '07 #3
On Feb 23, 1:52 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
ralphmerri...@gmail.com wrote:
Why I don't want to simply make FileRunner a friend class: FileRunner
is the workhorse class of the program; I want to make sure that all
post-initialization access goes through the appropriate accessors, and
I want to be sure that certain parts aren't changed after
initialization.

That's unclear, sorry. Whose accessors are we talking about here?
Misread this initially. Accessors for DataClass & OtherDataClass.

Feb 23 '07 #4
ra***********@gmail.com wrote:
>[..] Why do you need friendship here at all? Have you thought
of

Tedious in that I'd have to explicitly say 'file_runner_arg.whatever'
instead of 'whatever' thoroughout the code.

I'd have to get into the exact details of the original format (which
isn't even well specified) and my implementation to explain why I need
all the friendship. Barring that, just take my word that the code
doesn't break up well.
>creating a special [possibly base] class in each DataClass and allow
it access to DataClass internals? It's kind of backwards, maybe,
but it works around the forward-declarations...

How would that work?
Well, I don't know how it would work for you. I gave you an example,
hoping that you can at least attempt to incorporate it into your code
to see _if_ it works. After all, you have a way around the circular
reference.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Feb 24 '07 #5
In article <11**********************@h3g2000cwc.googlegroups. com>,
ra***********@gmail.com says...
My current project involves reading a particular data format.

It would be convenient to be able to do something like:

class DataClass {
friend bool FileRunner::read_data (const vector<string>&);
...
};

class OtherDataClass {
friend bool FileRunner::read_data (const vector<string>&);
...
};

class FileRunner {
DataClass m_data;
OtherDataClass m_data2;
bool read_data (const vector<string>&);
...
};
You haven't said enough to say whether it's a good idea, but what you
have right now is _almost_ equivalent to something like this:

class base {
protected:
virtual bool read_data(const vector<string&)=0;
};

class DataClass : virtual base {
// code that uses read_data
};

class OtherDataClass : virtual base {
// code that uses read_data
};

class FileRunner : DataClass, OtherDataClass {
protected:
bool read_data(const vector<string&s) {
// whatever
}
};

Since read_data is declared in base, it's usable from both DataClass and
OtherDataClass (except in their ctors). Since FileRunner inherits from
DataClass and OtherDataClass, it implicitly contains an embedded object
of each type and has access to the public/protected functions of both.
OTOH, this is an example of the "deadly diamond" inheritance pattern,
which isn't particularly popular.

OTOH, you've implied that you want to use read_data from the ctor of
DataClass and/or OtherDataClass. That's not possible with code like
above -- to allow that, you'd have to move the definition of read_data
to base, instead of just declaring it there.

Side note: the inheritance above is (intentionally) _private_, so the
usual concerns about inheritance such as LSP don't apply.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Feb 24 '07 #6

ra***********@gmail.com wrote:
>
It would be convenient to be able to do something like:

class DataClass {
friend bool FileRunner::read_data (const vector<string>&);
...
};

class OtherDataClass {
friend bool FileRunner::read_data (const vector<string>&);
...
};

class FileRunner {
DataClass m_data;
OtherDataClass m_data2;
bool read_data (const vector<string>&);
...
};
I'm planning on rewriting it to be a single external function (friend
to all needed classes) with an added FileRunner& argument, but because
it references fields within FileRunner heavily, that would be very
tedious. Any alternatives?
I agree, "declared friend only" is wrong point in C++. We need to be able to
declare (for any class A) any other name as "friend", and not declared names
also.

If later any X will try to access to protected section of class A compiler
will check friend declarations of A to realize has the X access or no.

Or we need to be able to do forward class member declaration (i think it is
worse)

class Base;
void Base::test()const;
If you need access make internal class for access (search the group for
"Tfriend")

class DataClass
{
int i;

public:
class Tfriend
{
DataClass &p;

public:
int& i(){return p.i;}
const int& i()const {return p.i;}

Tfriend(const DataClass& ap):p(const_cast<DataClass&>ap){}
};

};

class FileRunner
{
DataClass m_data;
OtherDataClass m_data2;

bool read_data (const vector<string>&)
{
DataClass::Tfriend fr(m_data);
fr.i();
}
};
--
Maksim A. Polyanin
http://grizlyk1.narod.ru/cpp_new

"In thi world of fairy tales rolls are liked olso"
/Gnume/
Feb 26 '07 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: cwdjr | last post by:
Real One has a page to copy on their site that detects if the browser of a viewer of a page has Real One installed. The page is located at...
2
by: Jason Heyes | last post by:
The following program does not compile. Apparantly "t" is inaccessible. #include <iostream> using namespace std; template <class T> class Foo { T t; public: Foo(T t_) : t(t_) { }
12
by: Bryan Parkoff | last post by:
CMain Class is the base class that is initialized in main function. CA Class is the base class that is initialized in CMain::CMain(). CMain Class is always public while CA Class is always...
2
by: Gerard Stafleu | last post by:
I have a project with the following module: Module mdlDeclarations Public Enum getMethod gmFirst gmLast End Enum End Module and the following class:
5
by: Edwinah63 | last post by:
Hi everyone, i was wondering if anyone else had observed this and if there is any workaround i have a screen (an mdi child form) with the buttons &Add, &Edit, &Save and E&xit, the idea being...
6
by: Peter Oliphant | last post by:
I just discovered that the ImageList class can't be inherited. Why? What could go wrong? I can invision a case where someone would like to add, say, an ID field to an ImageList, possible so that...
4
by: Dovla | last post by:
Hi, I have the following problem. I have a project that uses the Treeview control. The code supports drag-drop functionality for moving nodes between different levels and for changing their...
9
by: M. Posseth | last post by:
i have 3 forms Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim frm As New Form2 frm.Show(Me) End Sub...
5
by: A.Gallus | last post by:
This is my problem: I have two classes A and B: class A { void methodA(); } class B
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.