Archived

This topic is now archived and is closed to further replies.

"friend", classes and access.

This topic is 5112 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a class with private data that I want to be able to access publically from within certain files. Using friend for every function in the file that accesses these variables is tedious. Is there any way to specify public access to private variables in a class for an entire file?

Share this post


Link to post
Share on other sites
Whats wrong with just using a public interface for the private variables?


class example
{
public:
const A& getvalue()const{ return value_; }
void setvalue(const A& val)( value_ = val;}
private:
A value_;
};


Allowing a ''file'' (not sure what you mean by that) complete public access to the private members just defeats the whole point of making them private in the first place.

Share this post


Link to post
Share on other sites
Er, the variables are private because there is meant to be no direct access from users of the library. That''s why no public getter/setter functions. (well, there are similar functions, but higher level)

However the library functions themselves need access. The library is spread over multiple files.

Many of the private functions in the library are not (for various reasons) defined inside the class, but there are very few library files which contain the implementation of these functions.

As for a "file", I''m referring to a *.cpp file, a physical file on disk (and it''s associated #includes where necessary) - the typical scope of a .cpp file.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
You can specify that a class has access to the private members by using ''friend class A;'' somewhere in the class definiton that you want A to have access to.

Share this post


Link to post
Share on other sites
hey ive got the same problem, ap could you give an example? this is what i tried but im still getting the same error.

class Example {
private:
int number;
friend class A;
};

class A
{
public:
void myFunction(Example abc)
{
abc.number=5;
}
};

Share this post


Link to post
Share on other sites
I think friend functions are wonderful and better than using set/get methods.

For example, i have a model object. I want my render object to render it so i pass in the object.

Object3D box;
Render gfx;

gfx.renderModel(box);

class Object3D
{
friend class Render;
private:
float* vertexdata;
float* normals;
//etc
};
class Render
{
void renderModel(Object3D& obj);
};

===============================

void Render::renderModel(Object3D& obj)
{
//i can access all attributes of obj even if they are private
}

In most cases, only the rendering module will need access to vertex data and most other classes should not have acces to it. It makes more sense to make the Render class a friend then to make the variables public and give all classes access to data which they dont require. This is one of the features which i like about C++ which is not found in Java.

Share this post


Link to post
Share on other sites
Er... I''m looking for an ALTERNATE to "friend"... re the title. The class is a friend of class is also being used. It''s global functions that are the problem. (I have to befriend every one and there''s about 60)

They have to be global because they are used with function pointers (and users have to be able to make their own functions that have the same function-pointed type, so I can''t use class-based function pointers.)

Actually, thinking about it, are the function pointers to these types equivalent? (ie. will typecasting one into the other screw up?)

void blah::func();
void func(*blah);





johnnyBravo, your example looks fine to me. Maybe you want to specify that class A exists before example. Try putting this line before Example:

class A;

then define class A after example as u are doing.

I use structs exactly as u are using classes there, and it works fine.





Share this post


Link to post
Share on other sites
namespaces are basically nothing but grouping stuff.

say you have a bunch of functions that calculate stuff you could put them in a namespace called calculaters.
eg
calculaters::sum(3,4)
calculaters:roduct(33,34)

Share this post


Link to post
Share on other sites
hey, that idea of creating a friend Global class that has all the functions in it sounds interesting. not sure how well that''ll work, but a point to ponder

Share this post


Link to post
Share on other sites
quote:
Original post by CraZeE
hey, that idea of creating a friend Global class that has all the functions in it sounds interesting. not sure how well that''ll work, but a point to ponder



It should work. Also you will be able to do this.

Global gb;

gb.
//and all the functions appear thx to code complete

Share this post


Link to post
Share on other sites
If you just want the variable to be accessible inside a particular translation unit, you could use unnamed namespaces, for example


//some .cpp file

namespace
{
unsigned int i;
}

void function()
{
++i;//calls the i variable inside the unnamed namespace

}


the unsigned int i will only be accessible from inside the translation unit in which it is declared. The compiler would turn the above code into something like


//some .cpp file

namespace uniquenumber
{
unsigned int i;
}
using namespace uniquenumber;

void function()
{
++i; //calls uniquenumber::i

}


That could be a possible solution to your problems.

Share this post


Link to post
Share on other sites
It sounds like your design is flawed. Friend pretty much breaks OOP and in most cases there are better ways to do what you want.

--------
"Hey, what about those baggy pants you kids are wearin'' these days? Aren''t they hip and cool and poppin'' fresh?"-Peter Griffin
"Everytime I see an M followed by a dollar sign I just say "oh god" and go to the next post."-Neurokaotix
the D programming language|google|msdn|XLib reference manual

Share this post


Link to post
Share on other sites
Ok, I''ll explain the reason.

The project is a widget-toolkit for games, and the class is "KWidget".

There are ways to align widgets inside other widgets, such as:

ALIGN_NORTH_WEST;
ALIGN_FLOAT;
ALIGN_MATCH;
ALIGN_WEST_NORTH;
ALIGN_SOUTH;
etc..

There are two associated functions per alignment: MinSize and Align. Each one acts upon private layout variables (size, spacing, offset etc..).

The layout variables have to be private without direct getters and setters because changing the size of a widget can affect all the widgets around it. The end user has to call changeMinSize on the widget to change it''s size.

There is an array of alignment types, with function pointers to their associated MinSize and Align functions. There are about 50 different alignment types, making for lots of different functions.

All the functions are in one file.

I believe that the functions should be global for a few reasons:
1) To reduce the size of the widget struct declaration.
2) To make addition/removal/modification of alignment types simpler.
3) Because I have no real desire to stick directly to the letter of the law regarding OO development. I''ve already broken it by using friend. I''m not deviating too drastically though.

I just want to make all of the functions in "KWM_Align.h" friends of KWidget.

I''m guessing there''s no solution though. Oh well.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:
It sounds like your design is flawed. Friend pretty much breaks OOP and in most cases there are better ways to do what you want.


exactly. those nerd pussy programmers were just feeling lonely when they decided to make that keyword for c++. hahah fags.

Share this post


Link to post
Share on other sites
I think you should read up on friend functions before saying it breaks OOP. It should not be used in all cases, but in situations where only 1 or a few classes require access to private functions and variables, it makes sense to use friend instead of declaring them public which is worse.

Here is a link:
http://oldlook.experts-exchange.com/Programming/Programming_Languages/Cplusplus/Q_20684762.html

Share this post


Link to post
Share on other sites
Friend is a great tool using sparingly. Many times such as when using an iterator, it makes since to give the iterator access to the private members of the list class. Making those members public is a bad idea, and iterator is its own defined self. Therefore you use friend to create a tight nit well defined interaction between the iterator (to step through the list structure), and the list itself.

Share this post


Link to post
Share on other sites
I''m assuming all your align values are enums or some how otherwise convertible to integers. So instead of friend''ing all 50 or so functions, friend a template function paramterized on the align values. Something like:

class KWidget;
template <int i> void WidgetFunc(const KWidget &);

const int ALIGN_NORTH_WEST = 0;
const int ALIGN_FLOAT = 1;
const int ALIGN_MATCH = 2;
const int ALIGN_WEST_NORTH = 3;

class KWidget {
template <int i> friend void WidgetFunc(const KWidget &);
private:
int stuff;
public:
KWidget() : stuff(-1) {}
};

template <>
void WidgetFunc<ALIGN_NORTH_WEST>(const KWidget & a) {
std::cout << "ALIGN_NORTH_WEST" << std::endl;
std::cout << a.stuff << std::endl;
};

template <>
void WidgetFunc<ALIGN_FLOAT>(const KWidget & a) {
std::cout << "ALIGN_FLOAT" << std::endl;
std::cout << a.stuff << std::endl;
};

int main(void) {
KWidget a;

WidgetFunc<ALIGN_NORTH_WEST>(a);
WidgetFunc<ALIGN_FLOAT>(a);

return 0;
}

The actual functions you use could just call the templated functions, so none of the templated functions need escape into the wild.

Share this post


Link to post
Share on other sites