I have an assignment where we're supposed to overload operators using parent/ child classes and I want to convert a parent object into a child object. So like boat + plane = seaplane.
An implementation example:
seaPlane plane::operator+=(boat rhs)
{
seaPlane temp;
temp.displacement = rhs.displacement;
// etc...
*this = temp;
return *this;
}
I'm getting two errors here: it says the boat data members are inaccessible and that "no suitable user-defined conversion... exists".
It may also be useful to know that I'm storing the objects in a heterogeneous collection.
Unfortunately, I do not have the reputation required to comment on Jonathan Smit's answer.
I agree that the access level of the data members of boat is a problem, but since the implementation of += (or + if you follow other advice) is in the class plane, you need to have
class boat{
friend class plane;
// class definition as before
};
Sorry to make this an answer in its own right, I feel it would have better served as a comment.
For your first error, here are things you should try doing. Check the access of your member variables in your boat class. Are they all private or protected? If so, then you can declare inside the node class that the seaPlane class is a friend class. This should give you access.
Something like this.
class boat{
friend class plane;
//some code
}
Otherwise, you can make the member variables public to allow access. The best option is based on your implementation and what you want.
Lastly, as the comments on your question point out, it is more apt to just overload +.
Related
I have searched through some SO articles but haven't found anything (yet) that quite addresses my question. Apologies if this answer does already exist somewhere.
A bit of background first...
I want to represent a device with "sections" of functionality, where the functionality has a hierarchical tree-like structure. Rather than have a load of flattened functions like
DeviceReferenceCheck(),
DeviceRefereceSet(),
DevicePhaseSetX(),
DevicePhaseDefaultsSet...()
I'd instead like to leverage nested classes so I could get
dev.reference.check()
dev.reference.set()
dev.phase.setx()
dev.phase.defaults.set...()
To do this I'm trying to use nested classes to get the obj.func.subfunction.subsub....() structure. The nested classes need a reference to the outermost class because they need to use read/write functions provided there.
In my attempts, the first thing I don't understand very well is as follows... I had tried this myself but then stopped using it because of a compiler warning.
class GPIBDevice_Agilent53132A : public GPIBDevice
{
private:
class RefOsc {
public:
// ... snip ...
RefOsc(GPIBDevice_Agilent53132A &parent);
// ... snip ...
} ro;
public:
// ... snip ...
GPIBDevice_Agilent53132A();
// ... snip ...
};
GPIBDevice_Agilent53132A::GPIBDevice_Agilent53132A() : GPIBDevice(), ro(*this)
{
}
Compiler says: gpibdevice_agilent53132a.cpp(5): warning C4355: 'this' : used in base member initializer list.
Aha, I think to myself... clever compiler... using this in the initialiser list is probably not a good idea because the class hasn't been fully constructed yet.
Question 1:
Is what I've said above correct? Is using this, in the enclosing class' initialiser list, to give the nested class a reference to the enclosing class, a bad idea? My thoughts are "yes" but would like some clarification because in other SO threads I have seen this method being used (Nested Class member function can't access function of enclosing class. Why?).
My approach to get around this was to have a member pointer to nested and then when actually in the constructor (so now safe to use this as class has been constructed) made a new inner class where I could pass in the reference to *this without warnings. Is this the standard way of doing it?
Continuing on....
The reason for the private nested class is btw that I don't want the user to be able to instantiate that class him/herself. Now, I did have it public to begin with... tried to use a private constructor in the nested class, but then the compiler told me it couldn't construct the class. So presumably the enclosing class can see nested class private data members?
Question 2:
Why can't the enclosing class see the nested classes private data members/functions?
My work around for this is to have the nested class declare the enclosing class as a friend. Is this really necessary?
Thanks for you help guys!
Summary
Thanks to Jan for his explanation of the curiously recurring template pattern. It's an interesting method to know about.
I've ended up accepting my own answer because I feel it answers the questions directly. The CRTP method is good but doesn't directly answer questions 1 & 2, but does provide a good alternative.
Question 1:
It would seem that this is possible. Thank you to mkirci and R. Martinho Fernandes for confirming my suspicions on why the compiler generated the warning and whether it was "safe" to ignore it.
In summary... not the best idea to use this in the initialiser list of the constructor because the class has not yet been constructed. As the guys point out, this can cause UB if the pointer is used. I've decided to use my work around which is use a pointer to the inner class, and then create it once inside the outer-class constructor... this way outer class is already created and can pass a reference to itself to the inner class safely.
Question 2:
From the C++ standard, I have found (after a lot of digging) in section 11.7:
A nested class is a member and as such has the same access rights as any other member. The members of an enclosing class have no special access to members of a nested class; the usual access rules (Clause 11) shall be obeyed.
The standard gave the following example:
class E {
int x;
class B { };
class I {
B b; // OK: E::I can access E::B
int y;
void f(E* p, int i) {
p->x = i; // OK: E::I can access E::x
}
};
int g(I* p) {
return p->y; // error: I::y is private
}
};
So, this is (annoyingly) why my outer class cannot call the inner class' private constructor. My solution has been to make the outer class a friend of the inner class. I.e in the above example add friend E; into the inner class decl.
I'm trying to learn C++, Thanks to this article I find many similarity between C++ and Python and Javascript: http://www.cse.msu.edu/~cse231/python2Cpp.html
But I can't understand C++ Classes at all, they looks like Javascript prototypes, but not that easy.
For example:
//CLxLogMessage defined in header
class myLOG: public CLxLogMessage{
public:
virtual const char * GetFormat (){
return "Wavefront Object";
}
void Error (const std::string &msg){
CLxLogMessage::Error (msg.c_str ());
}
void Info (const std::string &msg){
CLxLogMessage::Info (msg.c_str ());
}
private:
std::string authoringTool;
};
Question: What is this Public/Private stuff at all!?
Edit: To be honest, I more enjoy C++ than Python, because I can learn truth meaning of everything, not simple automated commands, for example I preferred to use "int X" rather than "X" alone.
Thanks
myLOG is the name of the class. It inherits (look it up2) from CLxLogMessage and has the functions GetFormat (which is virtual and can be overridden by subclasses and called through base class pointers, look it up2), Error, and Info. It has the data member authoringTool which is a string.
The public and private stuff is access specifiers. Something in the private section can only be used by the class's member functions, and stuff in the public section can be used by anybody. There is another type of section called protected which means that only a class and its subclasses can access it, but nobody else1.
If you start adding stuff to a class without setting an access level first, it defaults to private.
You can have as many public, private, and protected sections as you want, in any order.
You need these different protection levels because you don't want other people messing with your data when you don't know about it. For example, if you had a class representing fractions, you wouldn't want someone to change the denominator to a 0 right under your nose. They'd have to go through a setter function which would check that the new value was valid before setting the denominator to it. That's just a trivial example though. The fact that Python does not have these is a shortcoming in the language's design.
All your questions would be answered if you had read a C++ book. There is no easy way out with C++. If you try to take one, you'll end up being a horrible C++ programmer.
1 You can let somebody else access private and protected members by declaring them as friends (look it up2).
2 Sorry for saying "look it up" so much, but it's too much information for me to put here. You'll have to find a good resource for these kinds of things.
Even though there's no way to give a comprehensive answer or anything near that, maybe think about it like this: classes are types. Consider this:
int n;
Here "int" is the name of a type, and "x" is a variable of type "int". There are basic types in C++, like "int", "char", "double". Now we can also make new, compound types from old types:
struct Foo
{
int n;
char c;
double d;
};
This defines a new type called "Foo", and Foo x; makes a new variable of that type. Now we can add some magic to the type "Foo":
class Foo
{
int n;
double d;
public:
Foo() : n(20), d(0.5) { } // "constructor"
};
The keywords struct and class almost mean the same thing, so we still have a compound type that has two member variables, n and d. However, this type also has a member function, and this one gets called every time you create a new Foo object. So when you say, Foo x;, then this variable's member value x.n will be set to 20 and x.d will be set to 0.5.
So that's that in a nutshell: Classes are types with built-in magic. And you are the magician.
The private and public is to do with data encapsulation, it means you can change the implementation of the class without affecting how it is used. I suggest reading up on some of the theory of object orientation.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
When should you use 'friend' in C++?
I have come to a stumbling block because of lack of documentation on friend classes. Most books just explain it briefly, e.g an excerpt from C++: the Complete Reference:
Friend Classes are seldom used. They are supported to allow certain special case situations to be handled.
And frankly, I have never seen a friend class in any good code made by an experienced C++ programmer. So , here is my list of problems.
Do Inherited Classes have the same friends as there base classes? e.g, if I declare class foo as a friend of class base, will class der (derived from base) also have foo as a friend?
What are the special case situations when a friend class should be used?
I am making a winapi wrapper in which I want to make class WinHandle a friend of class Widget (to access some protected members). Is it recommended? Or should I just access them using the traditional Get/Set functions?
Friend is used for granting selective access, just like the protected access specifier. It's also hard to come up with proper use case where use of protected is really useful.
In general, friend classes are useful in designs where there is intentional strong coupling: you need to have a special relationship between two classes. More specifically, one class needs access to another classes's internals and you don't want to grant access to everyone by using the public access specifier.
The rule of thumb: If public is too weak and private is too strong, you need some form of selected access: either protected or friend (the package access specifier in Java serves the same kind of role).
Example design
For instance, I once wrote a simple stopwatch class where I wanted to have the native stopwatch resolution to be hidden, yet to let the user query the elapsed time with a single method and the units to be specified as some sort of variable (to be selected by user preferences, say). Rather than, have say elapsedTimeInSeconds(), elapsedTimeInMinutes(), etc. methods, I wanted to have something like elapsedTime(Unit::seconds). To achive both of these goals, I can't make the native resolution public nor private, so I came up with the following design.
Implementation overview
class StopWatch;
// Enumeration-style class. Copy constructor and assignment operator lets
// client grab copies of the prototype instances returned by static methods.
class Unit
{
friend class StopWatch;
double myFactor;
Unit ( double factor ) : myFactor(factor) {}
static const Unit native () { return Unit(1.0); }
public:
// native resolution happens to be 1 millisecond for this implementation.
static const Unit millisecond () { return native(); }
// compute everything else mostly independently of the native resolution.
static const Unit second () { return Unit(1000.0 / millisecond().myFactor); }
static const Unit minute () { return Unit(60.0 / second().myFactor); }
};
class StopWatch
{
NativeTimeType myStart;
// compute delta using `NativeNow()` and cast to
// double representing multiple of native units.
double elapsed () const;
public:
StopWatch () : myStart(NativeNow()) {}
void reset () { myStart = NativeNow(); }
double elapsed ( const Unit& unit ) const { return elapsed()*unit.myFactor; }
};
As you can see, this design achieves both goals:
native resolution is never exposed
desired time unit can be stored, etc.
Discussion
I really like this design because the original implementation stored the multiple of native time units and performed a division to compute the elapsed time. After someone complained the division was too slow, I changed the Unit class to cache the dividend, making the elapsed() method (a little) faster.
In general, you should strive for strong cohesion and weak coupling. This is why friend is so little used, it is recommended to reduce coupling between classes. However, there are situations where strong coupling gives better encapsulation. In those cases, you probably need a friend.
Do Inherited Classes have the same friends as there base classes? e.g if i declare class foo as a friend of class base, will class der (derived from base) also have foo as a friend?
The rule with friend keyword is:
Friendship attribute is not inherited.
So No friend of base class will not be friend of Derived class.
What are the special case situations when a friend class should be used?
Frankly, (IMHO) using friend classes is mostly done to achieve some things for rather ease of usage. If a software is designed taking in to consideration all the requirememtens then there would practically no need of friend classes. Important to note perfect designs hardly exist and if they do they are very difficult to acheive.
An example case which needs friend class:
Sometimes there may be a need for a tester class(which is not part of the release software) to have access to internals of classes to examine and log certain specific results/diagnostics. It makes sense to use friend class in such a scenario for ease of usage and preventing overhead of design.
I am making a winapi wrapper in which I want to make class WinHandle a friend of class Widget (to access some protected members). Is it recommended? Or should I just access them using the traditional Get/Set functions?
I would stick to the traditional setter/getter. I rather avoid using friend where I can get working through usual OOP construct. Perhaps, I am rather paranoid about using friend because if my classes change/expand in future I perceive the non inheritance attribute of friend causing me problems.
EDIT:
The comments from #Martin, and the excellent answer from #André Caron, provide a whole new perspective about usage of friendship, that I had not encountered before & hence not accounted for in the answer above. I am going to leave this answer as is, because it helped me learn a new perspective & hopefully it will help learn folks with a similar outlook.
friend usually accounts for where you would normally use one single class, but you have to use more because they have different life-times or instance counts, for example. friendship is not transferred or inherited or transitive.
Get/Set is quite terrible, although better than it could be. friend allows you to limit the damage to just one class. Usually you will make an intermediary class which is friended.
class MyHandleIntermediary;
class MyHandle {
friend class MyHandleIntermediary;
private:
HANDLE GetHandle() const;
};
class MyWidget;
class MyHandleIntermediary {
friend class MyWidget;
static HANDLE GetHandle(const MyWidget& ref) {
return ref.GetHandle();
}
};
class MyWidget {
// Can only access GetHandle() and public
};
This allows you to change the accessibility of friendship on a per-member level and ensures that the extra accessibility is documented in a single place.
One of the cases where I applied the "friend classes", is where one class is composed or referenced by other (objects) classes, and the composing objects, require access to the internals of the main class.
enum MyDBTableButtonBarButtonKind {
GoFirst,
GoPrior,
GoNext,
GoLast
}
class MyDBTableButtonBarButtonWidget;
class MyDBTableButtonBarWidget {
friend class MyDBTableButtonBarButtonWidget;
// friend access method:
protected:
void GoFirst();
void GoPrior();
void GoNext();
void GoLast();
void DoAction(MyDBTableButtonBarButtonKind Kind);
};
class MyDBTableButtonBarButtonWidget {
private:
MyDBTableButtonBarWidget* Toolbar;
public:
MyDBTableButtonBarButtonWidget(MyDBTableButtonBarWidget* AButtonBar) {
this ButtonBar = AButtonBar;
}
MyDBTableButtonBarButtonKind Kind;
public:
virtual void Click() { Buttonbar->DoAction(this Kind); };
};
void MyDBTableButtonBarWidget::DoAction(MyDBTableButtonBarButtonKind Kind)
{
switch (Kind)
{
case MyDBTableButtonBarButtonKind::GoFirst:
this.GoFirst();
break;
case MyDBTableButtonBarButtonKind::GoLast:
this.GoLast();
break;
}
}
In this example, there is a widget control that is a bar composed of buttons, the buttonbar is referenced to a D.B. table, and has several buttons for a specific action,
like select the first record of the table, edit, move to the next.
In order to do so, each button class has friend access to private & protected methods, of the given control. As previous answer in this post, usually friend classes act a single class, decomposed in several smaller classes.
It's not a finished example, its only a general idea.
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!
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());
// ...
}
No, you can't declare individual member functions as friends until they've been declared. You can only befriend the entire class.
It may or may not be relevant here, but it is useful to remind ourselves that there is a wild world beyond the scope of classes and objects where functions can roam free.
For example, I recently needed to close off a (singleton global static) system error log from a global exception handler based on a port of someone else's code. The normal include file for my error log conflicted with the exception handler code because both wanted to include "windows.h" for reasons I didn't look into. When this and other questions persuaded me I could not make a forward declaration of my ErrorLog class's member functions, what I did was wrap the necessary functions into a global scope function like this:
void WriteUrgentMessageToErrorLog( const char * message )
{
ErrorLog::LogSimpleMessage( message );
ErrorLog::FlushAccumulatedMessagesToDisk();
}
Some people are very particular about maintaining the integrity of their class structure at all cost... and seldom acknowledge that applications using those classes are inevitably built on top of something that lacks that structure. But it's out there, and used judiciously, it has its place.
Given the age of this question, I have not looked deeply into its relevance here. All I wanted to share was the opinion that sometimes a simple wrapping mechanism like this is a much cleaner and more readily understood alternative to something that has a lot more subtlety and cleverness about it. Subtlety and cleverness tends to get changed at some later date by someone required to add to it who didn't fully understand it. Before you know it, you have a bug...
I have a nested class in c++ which has to be public. But I need some of its methods visible to the outer world, and the rest visible only to the nesting class. That is:
class set {
public:
class iterator {
innerMethod();
public:
outerMethod();
}
}
I want to be able to write a method for set which uses innerMethod(). If I make it public, I can access it from outside as well, which is something that I definitely don't want. Is there a way to do it without doing the "friend class set" thing?
Thanks in advance!
There is NO GOOD WAY you can do this, without using friend keyword.
In the comment you said:
In the programming class I currently
take, using 'friend' was said to be
ill-advised and generally considered
"bad programming" for the most part,
unless there is really no other way
around it. So I try to avoid it as
much as possible.
friend breaks encapsulation, maybe that is the reason why your class teacher said it's bad-programming. But member-functions too break encapsulation, then why do you use them? Why not avoid them too? friend breaks encapsulation in the same way as do member-functions; so if you're comfortable using member-functions when they're needed, then you should be comfortable using friend also when they're needed. Both exist in C++ for a reason!
class set {
public:
class iterator
{
friend class set; //<---- this gives your class set to access to inner methods!
void innerMethod(){}
public:
void outerMethod(){}
};
iterator it;
void fun()
{
it.innerMethod();
it.outerMethod();
}
};
See this : How Non-Member Functions Improve Encapsulation
No, I don't think there are other non-hacky methods but using the friend-directive.
friend exists right for this kind of purpose, why would you avoid it?
Try asking: is there any way to add 2 numbers without adding them?
Sorry if I'm harsh, but friend class is for exactly that...
Yes there is.
I've been trying to advocate the method for a while now, the basic idea is to use a Key class.
While this does not actually remove the use of friend, it does reduce the set of exposed implementations details.
class set;
// 1. Define the Key class
class set_key: noncopyable { friend class set; set_key() {} ~set_key() {} };
class set
{
// 2. Define the iterator
class iterator
{
public:
void public_method();
void restricted_method(set_key&);
}; // class iterator
}; // class set
Now, restricted_method is public, so set does not need any special access to iterator. However the use of it is restricted to those able to pass a set_key instance... and conveniently only set may build such an object.
Note that set may actually pass a set_key object to someone else it trusts. It is a key in the traditional sense: if you give a key of your flat to someone, it may entrust it to another person. However because of the semantics of the key class (non copyable, only set may construct and destroy it) this is normally limited to the duration of the scope of the key object.
Note that a evil hack is always possible, namely *((set_key*)0). This scheme protects from Murphy, not Machiavelli (it's impossible in C++ anyway).
You can do something like this:
class set
{
public:
class iterator
{
protected:
iterator(){};
virtual ~iterator(){};
public:
//outer world methods...
};
private:
class privateIterator : public iterator
{
public:
privateIterator(){};
~privateIterator(){}
//inner methods;
};
public:
iterator* CreateIterator()
{
return new privateIterator();//this is used to be sure that you only create private iterator instances
}
};
I don't know if it's the right answer, but it does now uses friend key work and it hides some of the methods. The only problem is that you can't declare privateIterator and you always must use CreateIterator to create an instance...