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.
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
Are private non static variable/methods accessible in static function? If yes,
then what is the use of "Private" access modifier?. Please go through the below code.
// Testclassheader.h file
class TestClass{
private:
int TestVariable; //Private Variable
int TestFunction(); //Private Method
public:
static void TeststaticFn(); //Static Method
};
void TestClass::TeststaticFn()
{
TestClass TestObj;
TestObj.TestVariable = 10; // Compiles perfectly
TestObj.TestFunction(); //Compiles Perfectly
}
// Another Class
//#include "Testclassheader.h"
class AnotherClass{
public:
int DummyFunc();
};
int AnotherClass::DummyFunc()
{
TestClass AnotherObj;
AnotherObj.TestVariable = 15; //error: 'TestVariable' is a private member of 'TestClass'
AnotherObj.TestFunction(); //error: 'TestFunction' is a private member of 'TestClass'
}
I tried the above code in Visual studio 12. Can anyone explain why private variable/methods are accessible in static method( which actually it should not)?
All functions of a given class have access to of that class's private members through any instance. You seem to think that private limit access to member functions of that particular instance, which is incorrect.
class foo
{
private:
int bar;
// access of the function doesn't matter, but let's use public
public:
// the only case you thought was legal:
void baz()
{
bar = 1;
}
// but this is perfectly legal
void qux(foo otherFoo)
{
otherFoo.bar = 1;
}
// also legal, as you discovered.
static void quux(foo iPittyTheFoo)
{
iPittyTheFoo.bar = 1;
}
};
class someOtherClass
{
// no function here (static or otherwise) has access to baz.
// UNLESS you "friend someOtherClass" inside class foo. Whether or not
// "friend" is ever a good idea is a matter of some debate.
};
void someGlobalFunction()
{
// Also cannot access bar.
Foo a;
a.bar = 1; // boom
}
// nope. Still cannot access bar.
foo b;
someOtherClass instance(b.bar); // boom
Also, "// throws error" is misleading. "Throw" exclusively refers to exception handling, not compile time errors. Compiler errors, linker errors, and runtime errors are each quite different and require different kinds of problem solving to deal with. When asking for help from someone not looking at the actual error output, you need to specify which it is. Just copy-paste-ing the error itself is generally a good idea, then we all have the same information.
In general, I suspect you've misunderstood the purpose of public:, protected:, and private:. We all had to learn it at some point.
In C++, public functions/methods and variables/members (different people use different terms) represent a class's "interface". These are what everything outside that class is allowed to use. What goes on behind that interface is none of their business (at least in theory).
protected functions and variables are available to classes that inherit from that class. "Your version of this class may be customized in these ways".
private functions and variables are no one else's concern. No touchy. As programs change, implementation details within a given class can vary wildly. The initial implementation of a class might (shudder) return a hardcoded value:
class X
{
...
private:
int Y() { return 1; }
};
Later versions of that same function might look up a value in a database, read from a file, whatever. "Which database?" Okay, now we need a parameter...
int Y(WhichDb thisOne) { return thisOne.lookupY(); }
So everywhere that was calling Y now needs to pass in a WhichDb (which should probably be a const reference, but that's a whole different topic). By changing the "function signature" of Y, we have broken all the code that called Y. In other words, all existing calls to Y are now compiler errors, because they don't pass in a WhichDb. In one sense, public/protected/private define just how much code a given change will affect/break.
Private? Just that class. No problem, I'm responsible for that class (because I can change it's header), so fixing that is no problem.
Protected? That class, plus everything that inherits from it. This could easily Break Someone Else's Code, which is generally bad. Breaking code you're not responsible for is a great way to lose customers.
Public? Anyone, anywhere could have called that function. "Breaking changes" to public interfaces are to be avoided.
So maybe your class is only ever used inside you company, in your department, by you. Public changes at that point are no big deal. On the other hand, Some Popular Library really cannot do that. I mean... they COULD, but they'd probably piss off lots of folks.
There are ways to change your public interface without breaking existing code. You can add new functions, you can add new parameters to existing functions THAT HAVE DEFAULTS: void foo(int bar = 2);. People who called foo() will still compile (and hopefully will still get the same behavior they depended on), but now people can call foo(3) to get new behavior.
Are private non static variable/methods accessible in static function?
Yes, private non static variable/methods are accessible by a static function that is part of the self-same class.
If yes, then what is the use of "Private" access modifier?
It prevents other classes from accessing the private class members and private instance members of the class.
Can anyone explain why private variable/methods are accessible in static method?
Because all the parts of a class are part of the class.
which actually [private variable/methods] should not [be accessible to static methods of the same class])?
That is incorrect.
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 +.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Pros and cons of using nested C++ classes and enumerations?
Consider the following declaration.
class A {
public:
class B{
};
};
Nothing special.
But what are the benefits of this?
What reasons may there be for putting one class inside of another?
There is no inheritance benefit between both classes.
If B is put inside of A for its private names sharing, then A is for B just a namespace, and there is reason to make B private, too.
What do you think about this?
Conceptually, it lets the programmer(s) know that class B relates specifically to class A. When you use class B outside of class A, you must use the type as A::B, which reminds you, every time, that B is related to A. This doesn't add any functionality, but shows a relationship.
Similarly, you don't have to use inheritance/composition, or classes at all. You can more or less simulate classes in C just by using structs and functions. It's just a way to keep the code cleaner and more straightforward and let the programmer relate the code to the design more easily. Classes accomplish this much more than public subclasses do, but that's just an example.
If it's a private/protected subclass (which I see it isn't in your example), then that obviously limits that class to the implementation of that class and that class's children, which might be desired (again design-wise) if the only use case of that class is in the implementation of that class (and possibly its children).
Benefit 1: The namespace aspect
Indeed, A provides a namespace for B, and this can help us structure our code much better. Consider a concrete example with vector for A, and iterator for B. Arguably,
class vector {
public:
class iterator { /*...*/ };
iterator begin() { /*...*/ }
};
is easier to type, to read, and to understand than
class vector_iterator {
/*...*/
};
class vector {
public:
vector_iterator begin() { /*...*/ }
};
Observe, in particular:
When the two classes (vector and iterator) depend on each other, i.e. use each other's members, the second version above would require one of the two to be forward-declared, and in some cases mutual type-dependencies might lead to unresolvable situations. (Using nested classes, it is much easier to avoid such problems, because within most parts of the nested class definition, the outer class is considered completely-defined. This is due to ยง9.2/2.)
You may very well have many other data types that maintain their own iterator, e.g. linked_list. Using the second version above, you'd need to define linked_list_iterator as a separate class. Class names would get ever longer and complicated the more of these 'dependent' types and alternative types you added.
Benefit 2: Templates
Continuing the example above, consider now a function template that takes a container (such as vector and linked_list defined above) as arguments and iterates over them:
template <typename Container>
void iterate(const Container &container) {
/*...*/
}
Inside this function, you'd obviously very much like to use the iterator type of Container. If that is a nested type, it's easy:
typename Container::iterator
But if it isn't, you would have to take the iterator type as a separate template parameter:
template <typename Container, typename Iterator>
void iterate(const Container &container) {
/*...*/
Iterator it = container.begin();
/*...*/
}
And if that iterator type does not appear among the function arguments, the compiler could not even guess the type. You'd have to explicitly add it in angle brackets each time you call the iterate function.
Final notes: None of this has much to do with whether the nested class is declared as public or private. My examples above suggest a situation in which a public nested type is clearly preferrable, because I suppose the iterator type should be able to be used outside the container class.
What reasons may be for putting one class inside of another one?
If you need to restrict the scope of B to only available for A, then internal class definition helps. Because it restricts the class scope to local.This is call scope localization.These are in more generic term called inner class declaration. Check this link.
This stackoverflow question helps you understand more.
I am working on a small project in C++ that requires me to create an object of a custom class I wrote in another one of my classes. The class is called FIRFilterModule, It has a simple blank constructor.
Being of a java background, my impulse is to create it like this:
class SensorInput{
public:
FIRFilterModule firFilter;
...More Class Members...
SensorInput():firFilter(FIRFilterModule()){}
...};
However this compiles with the ever so helpful error message of "Error within this context". I'm a little lost why that doesn't work. Increasing my confusion I changed the code to this:
class SensorInput{
public:
FIRFilterModule firFilter;
...More Class Members...
SensorInput(){}
...};
It works.
Can someone help me understand why this is so?
In this particular case, running of the default constructor for a member field, you don't have to do anything. The constructor is run automatically. So you can just write
class SensorInput{
public:
FIRFilterModule firFilter;
SensorInput() { ... }
};
The member initialization list is only needed when you need to call a constructor which has arguments or initialize POD types. For example say the FIRFilterModule had a constructor which took an int. Then you would use the memeber initialization list
SensorInput() : firFilter(42) { ... }
The code you posted is correct.
Maybe you forgot to include the header where FIRFilterModule is declared.
Otherwise, everything should work.
Let's say we're given this class with an inner struct.
class Some {
public:
struct Crap{};
Crap Process(Crap& c);
}
Some::Crap Some::Process(Crap& crap) { Crap moreCrap = .. }
It makes sense to me that the return type (Some::Crap) in "Process" is scoped.
It makes sense to me that no scoping is needed inside the body of "Process".
I do not understand why the inner struct parameter of Process (Crap& crap) does not require scoping.
Does anyone have any insight on this?
Thanks
In fact, the parameter type does need to be qualified (unless your example is incorrect and you intend for Process to be a member function of Some).
Assuming the following snippet:
class Some
{
public:
struct Crap{};
Crap Process(Crap&);
};
Some::Crap Some::Process(Crap& crap) { ... }
Basically, Crap does not require scoping inside the function parameter list and body for the same reason you don't need this-> to access data members and member functions: it is implicit because it is at the same scope.
The reason return type is needed is simply because the parser encounters the return type before the method name and cannot (is not required to?) deduce scope at that moment.
The question title says 'member function', but your example contains no member function. Assuming you meant Some::Process rather than just Process:
The class scope for the member function definition begins at the (, not at the {. I assume the reasoning is exactly so that things like this can be typed shorter.