Access of nested classes (which behave like friends, but aren't) - c++

Without long delay, here the code which I have no clue why it does what it does:
#include <iostream>
class A {
private:
void print() { std::cout << "A.print() called" << std::endl; };
public:
template<typename Foo>
class B; //NOTE: no friend!
public:
A();
B<double>* bd;
B<int>* bi;
};
template<typename Foo>
class A::B{
A* callback;
public:
B(A* a):callback(a){};
void print() { callback->print(); }; // Why is this working ???
};
A::A():bd(new B<double>(this)),bi(new B<int>(this)){}
int main(int argc, char **argv)
{
A a;
// a.print(); // error: ‘void A::print()’ is private
a.bd->print();
a.bi->print();
A::B<char> c(&a);
c.print();
A::B<double> d = *a.bd;
d.print();
return 0;
}
Well, it creates this ouput:
A.print() called
A.print() called
A.print() called
A.print() called
But why?
Background
I initially started my journey down the rabbit hole when I encountered a problem which I through to have to do with friends. So I read friend declaration not forward declaring (and the mentioned answers here and here). So while trying to set up an easy example (the result of which you see above), I found that I actually don't seem to need friend at all.
Question
So here is the bottom line question: Why does an instance of A::B have access to A's private function A::print()? (although I do realize that I might misunderstand what my children are--children as opposed to base vs. derived)

because nested class is a member of the enclosing class
standard $11.7.1
"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 shall be obeyed"
and the usual access rules specify that:
"A member of a class can also access all the names to which the class has access..."
specific examples has been given in the standard:
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
}
};
}

A nested class (or inner class) has access to the privates of the class it is nested within. It is in some sense already friends with that class. It is similar to the way that any A object has access to the privates of any other A object.
You use friend for classes that are defined outside of your class that you want to access its privates. Here's a simple example of this:
struct B;
class A
{
int x;
friend struct B;
};
struct B
{
void someFunc() {
A a;
a.x = 5;
}
};
int main(int argc, const char* argv[])
{
B b;
b.someFunc();
return 0;
}
Without making B a friend of A, it would not be able to access A's member x.

Related

Complex object inside another one

I have the following class
class A {
private:
B b;
public:
A();
}
class B {
public:
void foo();
void bar();
void foz();
........
}
B has a lot of methods. Sometimes is needed for a "customer" of class A to use method of class B. I could return a reference of B, but in this case I should return a const reference because returning a non-const reference of a private object is not good programming. If the reference is const, foo, bar and so on can't be called because they aren't const. So the only "clean" way seems to recreate the same interfaces in A using delegation to B. But this approach is not really good because I should recreate all the interfaces in A. As alternative I could set B as public in A, but it seems "strange" to me. What should I do in this case?
That is mainly an encapsulation question, and what you want to advertise in the public interface of class A.
If class B is also a public class - read can normally be used by users of class A and not a class internal to a library or framework - and if you want the existence of a B subobject to exist in the public documentation of class A and if you want to allow any operation on the B object, you can safely provide a getter.
If any of the above conditions is false, then the getter would break encapsulation and you would better define delegating methods in class A.
Depending on the general design, it could make sense to declare an interface class (say C) with only the methods that you want to allow from class A, and have B a subclass from C. Then you could safely declare a getter returning a reference on a C object:
class C {
public:
void foo(); // optionally virtual or pure virtual...
void bar();
void foz();
};
class B: public C {
.... // other members not relevant for what is public for A users
};
class A {
private:
B b;
public:
A();
C& getB() {
return b;
}
};
Solution 1. You create a getb() and return reference to B. Its not bad programming in you case particularly.
Solution 2. Create interface function for each corresponding function of b and call them.
void A::foo()
{
b.foo();
}
You can make the data member protectedinstead of private. Documentation says that protected members are not as private as private members, which are accessible only to members of the class in which they are declared, but they are not as public as public members, which are accessible in any function. protectedmembers (be they data members of method members) serve the role you're looking for : they are not accessible from everywhere (safe coding practices), but you can still manage them in clean ways when it makes sense :
If class A has an attribute of type B, is has access to B's
protected and publicmembers
friendfunctions can access both protected and publicmembers of a class they are friend with.
When preceding the name of a base class, the protected keyword specifies that the public and protected members of the base class are protected members of its derived classes.
Here, you're interested by the first item of the list : you can access B' methods from A; BUT B has still safeguards.
When I run the following code (adapted from your code) :
#include <iostream>
using std::cout;
using std::endl;
class B {
public:
void foo() { cout << "foo" << endl; };
void bar() { cout << "bar" << endl; };
void foz() { cout << "foz" << endl; };
};
class A {
protected: // <===== THIS IS THE SIGNIFICANT BIT
B b;
public:
A() {
b.foo();
b.bar();
b.foz();
cout << "A constructor" << endl;
};
};
int main(int argc, char** argv) {
A myA;
return 0;
}
I get the following console output :
foo
bar
foz
A constructor
Which shows that I can access B's methods from A.

is it ok to abuse reinterpret_cast to convert an object to a derive class when it is not?

The following code compiles and works correctly, allowing me to gain access to protected fields of a class. But is this an ok thing to do? Feel dirty, but what do i know coming from Java:
#include <iostream>
class Base {
public:
Base() : _f(42) {
}
int getF() { return _f; }
protected:
int _f;
};
class Der : public Base {
public:
void setF(int f) { _f = f; }
};
int main(int argc, char ** argv) {
Base *b = new Base();
std::cout << b->getF() << std::endl;
Der *d = reinterpret_cast<Der*>(b);
d->setF(37);
std::cout << b->getF()<< std::endl;
}
And if I am right and this is not ok, what is a good way expose internal encapsulated data fields of an object which normally don't need to be modified, but do need to be changed in testing? The instance is created deep inside other components, so changing its type is not trivial.
No, if you pretend an object is of type Der when it isn't, the behaviour is undefined. This could fail at runtime, and badly. Aside from the usual (specifically requesting your compiler to make invalid code crash), one way this could fail at runtime is if your compiler's optimiser assumes that since you are casting it to Der*, it must really be of type Der. If you then follow this by a call to a virtual function, the compiler may assume that since the dynamic type is already known as Der, virtual method lookup can be optimised away.
And if I am right and this is not ok, what is a good way expose internal encapsulated data fields of an object which normally don't need to be modified, but do need to be changed in testing?
The friend keyword seems appropriate for that. This keyword makes private (and protected) members of a class available outside of the class. Since your Base class should know which class or function will be unit-testing it, it can grant access to that class or function.
class Base {
friend class BaseTester;
// ...
protected:
int _f;
};
class BaseTester {
public:
static void test() {
Base *b = new Base();
b->_f = 37;
}
};
int main(int argc, char ** argv) {
BaseTester::test();
}
For completeness, there are a few holes in C++'s access checks that you could abuse if for some reason you cannot modify Base. Here's one:
#include <iostream>
class Base {
// ...
protected:
int _f;
};
class BaseHack : public Base {
public:
static constexpr int Base::*_f = &BaseHack::_f;
};
int main(int argc, char ** argv) {
Base *b = new Base();
b->*BaseHack::_f = 37;
}
Inside BaseHack, the expression &BaseHack::_f is allowed, because it names a protected member of a base class, accessed through its own class. But because _f is actually defined in class Base, its type is int Base::* rather than int BaseHack::*, and there is no rule preventing it from being used to access members of Base.

c++ how to properly declare friend class method of another class

consider the following example.
class A
{
int member;
};
class B
{
A& a_ref;
void manipulate()
{
a_ref.member++;
}
};
Now, obviously, B::manipulate can not access a_ref. I would like to allow (only) class B to get (reference) to A::member. I know that there exists friend keyword, but I do not know how to use it properly. My intention is, that I could change B::manipulate implementation to become this
int& A::only_B_can_call_this() // become friend of B somehow
{
return member;
}
void B::manipulate()
{
a_ref.only_B_can_call_this()++;
}
To make B a friend:
class A
{
int member;
friend /*class*/ B; // class is optional, required if B isn't declared yet
};
Note that friends are anti-patterns - if something is private, it probably shouldn't be accessed. What are you trying to accomplish? Why isn't A self-contained? Why does another class need to access its internal data?
Use friend if you have valid answers/reasons for these questions.
You simply add friend class <class_name>; to the class that wants to make its members accessible, where <class_name> is the name of the class that you want to provide access for.
class A
{
friend class B; // allow class B to access private members of A
int member;
};
class B
{
A& a_ref;
void manipulate()
{
a_ref.member++;
}
};

Class with no name, constructor, destructor

I've read about class with no name...
Got that
class
{
int i;
};
is not valied while
class
{
int i;
}A;
is valid.
But how to have a: 1) constructor and :2) destructor and: 3) how to pass as an argument???
If the class is unnamed then it can't have a custom constructor/destructor (although the compiler will generate the usual default ones for you). That means you can't pass an argument to it at construction. However, there's probably nothing stopping you from either (1) adding one or methods to the class to pass data to it after construction, or (2) giving the class a name in the first place.
The second thing is valid, but you cannot access the member i since it will be private. It is valid only because You have created an object A of that class type.
To have a constructor, I think you have to give the class a name. Use this:
class myclass
{
int i;
public:
myclass(int a) //This is the constructor
{
i = a;
}
~myclass() //This is the destructor
{
//Whatever you want to do on destroying the object
}
};
and instantiate that class as follows:
myclass A(10);
or similarly.
Note: This is just my interpretation, it can be done in many other ways.
You are doomed using the class locally and accessing it through the local object A, only.
You can use it in a template, though:
template <typename T>
inline void print(const T& a) {
std::cout << a.x << std::endl;
}
int main()
{
class {
public: int x;
} a;
a.x = 1;
print(a);
}

OOPS Memory Allocation for Base class under Inheritance?

Program:
class A
{
int a;
public:
void geta()
{
a=10;
}
void puta()
{
cout<<"a : "<<a;
}
};
class B : public A
{
int b;
public:
void getb()
{
geta(); b=20;
}
void putb()
{
puta(); cout<<"b : "<<b;
}
};
int main()
{
B ABC;
ABC.getb();
ABC.putb();
return 0;
}
The Problem:
The above program allocates memory for derived class object & calls its relevant methods.
The base class is inherited as public, and as the variable 'a' is a private member, it will not get inherited.
So, the program should not allocate memory for this variable.
But, when the above is executed, 'a' variable will be allocated even though it is not inherited.
Could anyone help me understand this?
Thank You.
as the variable 'a' is a private member, it will not get inherited. So, the program should not allocate memory for this variable.
Your assumption is mistaken. Public inheritance models an "is-a" relationship. That is, class Derived is-a Base. Anything you can do with a Base, you should be able to do with a Derived. In order for this to be true, it necessarily must contain everything that Base contains.
In your example, it's perfectly legal to say:
B b;
b.put_a();
that is, to use A methods on B object. This would not work if the a member was absent.
The base class is inherited as public, and as the variable 'a' is a private member, it will not get inherited.
When a base class member is declared as private it doesn't mean it does not get inherited. It just means that the member variable will be inherited (will be part of the derived class) but won't be accessible.
For example, in:
class A {
private:
int a;
int b;
// ...
};
class B : public A {};
auto main() -> int {
B b;
}
When we allocate B b; we are allocating both a and b member objects of the class A.
The variable a is inherited, though you have no access to it. For example, the following code would work:
class A {
private:
int x;
public:
int getXfromA() { return x; }
};
class B : public A {
public:
int getXfromB() { return getXfromA(); }
};
However, x cannot be directly accessed from B class here.
You're confusing storage with access control.
If object B inherits from object A, it has all of object A's methods and members, even if it cannot access them directly.
The purpose of private and protected is access control. If you mark members and methods as private, then nothing outside can access those methods and members. But, those things are part of the object nonetheless.
This allows you to implement class invariants without exposing the details, including classes that inherit from the base.
Here's an example that encapsulates capturing the creation time of an object in the base class:
#include <time.h>
#include <iostream>
class Base
{
private:
time_t create_time;
public:
Base()
{
create_time = time(0);
}
time_t get_create_time() { return create_time; }
};
class Derived : public Base
{
public:
Derived() { }
};
int main()
{
Derived D;
std::cout << D.get_create_time() << std::endl;
}
Derived doesn't know or need to know how the creation time was captured. It's a class invariant it inherited by deriving from Base.
This is a pretty simple example, but you could imagine more complex examples.