how to use friend ?

T

toton

Hi,
I have a parser interface , which is
class IParser{
public:
void readHeader(Document& doc)= 0;
void readCC(CC& cc) = 0;
};
Now, there are 3 kinds of parser which extends (implements) IParser,
one for XML, ne for Config, & one for binary.
They need to get the Document & CC class and fill the data, in the
document and CC.

Now document data's (like name, version) are private, and have a get
method. Once the document is set by the IParser implementation, it
should not be changed.
document class is like
class Document{
private:
std::string _name;
std::string _version;
public:
std::string getName() const{
return _name;
}
std::string getVersion() const{
return _version;
}
};
Now, declaring IParser as friend in document class is not helping, as
the actual implementation like class XMLParser, class ConfigParser are
not friend of Document, thus cant access Document private variables.
The classes are decalred like,
class XMLParser :public IParser{
public:
void readHeader(Document& doc){
...
}
void readCC(CC& cc){
...
}
};

How to do this with or without friend? i.e. any class derived from
IParser can access the private variables of document?
any other better way this can be implemented? I had thought to create
the Document class inside readHeader, and initialize parameters
throught ctor, but Document class has a large number of such member
variables, and difficult to initialize all of them through ctor.


thanks in advance for advice ...
abir
 
I

Ivan Vecerina

: Hi,
: I have a parser interface , which is
: class IParser{
: public:
: void readHeader(Document& doc)= 0;
: void readCC(CC& cc) = 0;
: };
: Now, there are 3 kinds of parser which extends (implements) IParser,
: one for XML, ne for Config, & one for binary.
: They need to get the Document & CC class and fill the data, in the
: document and CC.
:
: Now document data's (like name, version) are private, and have a get
: method. Once the document is set by the IParser implementation, it
: should not be changed.
....
: Now, declaring IParser as friend in document class is not helping, as
: the actual implementation like class XMLParser, class ConfigParser are
: not friend of Document, thus cant access Document private variables.
....
: How to do this with or without friend? i.e. any class derived from
: IParser can access the private variables of document?
: any other better way this can be implemented?

If "IParser" was the root of a hierarchy of classes that have special
access to manipulating documents, I would include in IParser protected
methods that allow subclasses to perform on a Document all the
required operations.

But in this case, IParser-s seem more like factory objects, they
act to create document objects which are then accessed using
a specific interface.
Can the parser create document objects by calling a constructor ?
If needed, parser could fill in a DocumentData structure, which
is then passed to the constructor of Document.
[ maybe Document can have DocumentData as a member ]

Alternativley, the Document instance could be calling the
IParser interface to obtain data packets that it will
take care of adding to itself.


Of course, I have no definitive answer given the provided
level of detail.
I hope this helps,
Ivan
 
T

toton

Ivan said:
: Hi,
: I have a parser interface , which is
: class IParser{
: public:
: void readHeader(Document& doc)= 0;
: void readCC(CC& cc) = 0;
: };
: Now, there are 3 kinds of parser which extends (implements) IParser,
: one for XML, ne for Config, & one for binary.
: They need to get the Document & CC class and fill the data, in the
: document and CC.
:
: Now document data's (like name, version) are private, and have a get
: method. Once the document is set by the IParser implementation, it
: should not be changed.
...
: Now, declaring IParser as friend in document class is not helping, as
: the actual implementation like class XMLParser, class ConfigParser are
: not friend of Document, thus cant access Document private variables.
...
: How to do this with or without friend? i.e. any class derived from
: IParser can access the private variables of document?
: any other better way this can be implemented?

If "IParser" was the root of a hierarchy of classes that have special
access to manipulating documents, I would include in IParser protected
methods that allow subclasses to perform on a Document all the
required operations.

But in this case, IParser-s seem more like factory objects, they
act to create document objects which are then accessed using
a specific interface.
Can the parser create document objects by calling a constructor ?
If needed, parser could fill in a DocumentData structure, which
is then passed to the constructor of Document.
[ maybe Document can have DocumentData as a member ]

IParser is the interface, which all parser will follow. a ParserFactory
class is also there to return the appropriate parser based on the file
extension.
Only any kind of IParser need to manipulate Document class.
and yes, document class is in the root of hierarchy, doesn't get
inherited.
In language like Java, it can be done having them in same package, and
declaring all the Document fields package private.
Alternative, what I thought now, is to accept an IParser object in the
document set method, so that only any kind of IParser can set the
document fields.
another alternative may be declaring the private fields in document as
protected, and in parser implementation, inheriting Document protected
way, but that breaks the UML rule, like Parser becomes a document,
which is bad.
I am looking a generalized way of giving access of the fields to a
class and its childs (which friend doesn't give) ...
 
I

Ivan Vecerina

:
: Ivan Vecerina wrote:
: > : > : Hi,
: > : I have a parser interface , which is
: > : class IParser{
: > : public:
: > : void readHeader(Document& doc)= 0;
: > : void readCC(CC& cc) = 0;
: > : };
: > : Now, there are 3 kinds of parser which extends (implements)
IParser,
: > : one for XML, ne for Config, & one for binary.
: > : They need to get the Document & CC class and fill the data, in the
: > : document and CC.
: > :
: > : Now document data's (like name, version) are private, and have a get
: > : method. Once the document is set by the IParser implementation, it
: > : should not be changed.
: > ...
: > : Now, declaring IParser as friend in document class is not helping,
as
: > : the actual implementation like class XMLParser, class ConfigParser
are
: > : not friend of Document, thus cant access Document private variables.
: > ...
: > : How to do this with or without friend? i.e. any class derived from
: > : IParser can access the private variables of document?
: > : any other better way this can be implemented?
: >
: > If "IParser" was the root of a hierarchy of classes that have special
: > access to manipulating documents, I would include in IParser protected
: > methods that allow subclasses to perform on a Document all the
: > required operations.
: >
: > But in this case, IParser-s seem more like factory objects, they
: > act to create document objects which are then accessed using
: > a specific interface.
: > Can the parser create document objects by calling a constructor ?
: > If needed, parser could fill in a DocumentData structure, which
: > is then passed to the constructor of Document.
: > [ maybe Document can have DocumentData as a member ]
:
: IParser is the interface, which all parser will follow. a ParserFactory
: class is also there to return the appropriate parser based on the file
: extension.
I understood this. I was indicating that IParser seems to act
as a factory for Document objects.

: Only any kind of IParser need to manipulate Document class.
Well, I guess that other classes use it.
Note that if your point is that only IParser "modifies"
a Document, then a better approach might be to expose
only const-references to Document to the rest of the
application.

: and yes, document class is in the root of hierarchy, doesn't get
: inherited.
: In language like Java, it can be done having them in same package, and
: declaring all the Document fields package private.
Putting all classes in the same package, you can assume that all
classes know about each other. The equivalent of this would be
to declare each IParser subclass as 'friend' of Document.

: Alternative, what I thought now, is to accept an IParser object in the
: document set method, so that only any kind of IParser can set the
: document fields.
: another alternative may be declaring the private fields in document as
: protected, and in parser implementation, inheriting Document protected
: way, but that breaks the UML rule, like Parser becomes a document,
: which is bad.
Both approaches are bad.

: I am looking a generalized way of giving access of the fields to a
: class and its childs (which friend doesn't give) ...
This would be achieved with my first suggestion:
having protected methods in the IParser base class that
allow to modify Document.

again:
: > Of course, I have no definitive answer given the provided
: > level of detail.

Ivan ;)
 
T

toton

Ivan said:
:
: Ivan Vecerina wrote:
: > : > : Hi,
: > : I have a parser interface , which is
: > : class IParser{
: > : public:
: > : void readHeader(Document& doc)= 0;
: > : void readCC(CC& cc) = 0;
: > : };
: > : Now, there are 3 kinds of parser which extends (implements)
IParser,
: > : one for XML, ne for Config, & one for binary.
: > : They need to get the Document & CC class and fill the data, in the
: > : document and CC.
: > :
: > : Now document data's (like name, version) are private, and have a get
: > : method. Once the document is set by the IParser implementation, it
: > : should not be changed.
: > ...
: > : Now, declaring IParser as friend in document class is not helping,
as
: > : the actual implementation like class XMLParser, class ConfigParser
are
: > : not friend of Document, thus cant access Document private variables.
: > ...
: > : How to do this with or without friend? i.e. any class derived from
: > : IParser can access the private variables of document?
: > : any other better way this can be implemented?
: >
: > If "IParser" was the root of a hierarchy of classes that have special
: > access to manipulating documents, I would include in IParser protected
: > methods that allow subclasses to perform on a Document all the
: > required operations.
: >
: > But in this case, IParser-s seem more like factory objects, they
: > act to create document objects which are then accessed using
: > a specific interface.
: > Can the parser create document objects by calling a constructor ?
: > If needed, parser could fill in a DocumentData structure, which
: > is then passed to the constructor of Document.
: > [ maybe Document can have DocumentData as a member ]
:
: IParser is the interface, which all parser will follow. a ParserFactory
: class is also there to return the appropriate parser based on the file
: extension.
I understood this. I was indicating that IParser seems to act
as a factory for Document objects.

: Only any kind of IParser need to manipulate Document class.
Well, I guess that other classes use it.
Note that if your point is that only IParser "modifies"
a Document, then a better approach might be to expose
only const-references to Document to the rest of the
application.
Can you give me a little more detail how to exactly do it? I believe
some kind of pattern exists for this, irrespective of language of
implementation, only not finding it ( apparently not present in GOF
book) ...
Again, if you need a little detail,
The actual file contains headers and several CC (kind of data,
basically a set of ints with a start & end mark)
I have IParser interface, which reads a document and puts the header
in the Document class, and reads CC's one by one on a readCC call and
store them in a deque.

The rest of the program gets the Document , and deque of CC's and
process them, but don't modify. The gets the Document & CC's from a
Session class which holds them.

Thus, any IParser implementation can read a file, given the name, can
read the header, create a Document from it and put it in Session.
similarly, upon call to readCC, it can read a CC form the file and put
it in the deque of Session. Also actually Session creates an IParser
implementation based on the file extension.
The remaining program can use the Document & CC deque returned by the
Session. For simplicity I can assume Session is a singleton, which
holds all the processing data.
The remaing things are flexible, how to have association between the
classes etc.
I am searching for some good pattern for this rather than the hacks
which I had thought :) .
: and yes, document class is in the root of hierarchy, doesn't get
: inherited.
: In language like Java, it can be done having them in same package, and
: declaring all the Document fields package private.
Putting all classes in the same package, you can assume that all
classes know about each other. The equivalent of this would be
to declare each IParser subclass as 'friend' of Document.
I dont know how many class will be derived from IParser, thus cant
entry a friend for each in the Document class.
: Alternative, what I thought now, is to accept an IParser object in the
: document set method, so that only any kind of IParser can set the
: document fields.
: another alternative may be declaring the private fields in document as
: protected, and in parser implementation, inheriting Document protected
: way, but that breaks the UML rule, like Parser becomes a document,
: which is bad.
Both approaches are bad.
I know :) , I had said last one is bad to denote it is "extremely bad"
....
 
I

Ivan Vecerina

: > : Only any kind of IParser need to manipulate Document class.
: > Well, I guess that other classes use it.
: > Note that if your point is that only IParser "modifies"
: > a Document, then a better approach might be to expose
: > only const-references to Document to the rest of the
: > application.
: Can you give me a little more detail how to exactly do it? I believe
: some kind of pattern exists for this, irrespective of language of
: implementation, only not finding it ( apparently not present in GOF
: book) ...
Well, one illustration could be:
class MyDocHandler
{
public:
//...

Document const& loadDocument( string const& fileName )
{
auto_ptr<IParser> parser = createParserForFile( fileName );
parser.load( curDoc_ );
return curDoc_;
}

private:
Document curDoc_;
};
Only DocHandler has access to the document in non-const form.
The rest of the application would be unable to modify
the document instance, having only a const-reference to it.

The other option I had mentioned was that IParser would create
data in a DocumentData struct. A document is then created to
store "DocumentData" and encapsulate its manipulation.

But in my related applications, it is usually the Document
class that calls the Parser to obtain items/contents that
it will store within itself.

: Again, if you need a little detail,
Actually, the better design depends more on the overview
of the system (I should have said "information" rather than detail).


Yet, I hope the above may help a bit.
Cheers -Ivan
 
T

toton

Ivan said:
: > : Only any kind of IParser need to manipulate Document class.
: > Well, I guess that other classes use it.
: > Note that if your point is that only IParser "modifies"
: > a Document, then a better approach might be to expose
: > only const-references to Document to the rest of the
: > application.
: Can you give me a little more detail how to exactly do it? I believe
: some kind of pattern exists for this, irrespective of language of
: implementation, only not finding it ( apparently not present in GOF
: book) ...
Well, one illustration could be:
class MyDocHandler
{
public:
//...

Document const& loadDocument( string const& fileName )
{
auto_ptr<IParser> parser = createParserForFile( fileName );
parser.load( curDoc_ );
return curDoc_;
}

private:
Document curDoc_;
};
Only DocHandler has access to the document in non-const form.
The rest of the application would be unable to modify
the document instance, having only a const-reference to it.
I even can't access getters for the Document class !!!!!!!!!.
What to do with this class?
 
I

Ivan Vecerina

: Ivan Vecerina wrote:
: > Document const& loadDocument( string const& fileName )
[...]
: I even can't access getters for the Document class !!!!!!!!!.
: What to do with this class?
You probably need to read about 'const' usage in C++.
In C++, the interface of a class can have a 'const' subset:
the operations that will not modify the contents of an instance.
A member function that does not modify the instance it is
called on is identified by appending 'const' to its signature:

class Document
{
public:
//.....

// const members: can be called on a const or non-const instance
std::string const& getTitle() const { return title_; }
Point getViewSize() const;

// non-const members: can only be called on a non-const instance
void loadContents( DocumentData const& sourceBuffer );

private:
std::string title_;
//.....
};

Point Document::getViewSize() const
{ .... }


const is one of the features I miss the most when working
with non-C++ code, it's worth taking advantage of.

Ivan
 
T

toton

Ivan said:
: Ivan Vecerina wrote:
: > Document const& loadDocument( string const& fileName )
[...]
: I even can't access getters for the Document class !!!!!!!!!.
: What to do with this class?
You probably need to read about 'const' usage in C++.
In C++, the interface of a class can have a 'const' subset:
the operations that will not modify the contents of an instance.
A member function that does not modify the instance it is
called on is identified by appending 'const' to its signature:

class Document
{
public:
//.....

// const members: can be called on a const or non-const instance
std::string const& getTitle() const { return title_; }
Point getViewSize() const;
I had just forgot to type const exactly for the getter which I had
called. :)
// non-const members: can only be called on a non-const instance
void loadContents( DocumentData const& sourceBuffer );

private:
std::string title_;
//.....
};

Point Document::getViewSize() const
{ .... }


const is one of the features I miss the most when working
with non-C++ code, it's worth taking advantage of.
Me too...
Thanks ...
 

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,776
Messages
2,569,603
Members
45,189
Latest member
CryptoTaxSoftware

Latest Threads

Top