3

Is it possible to make a member variable/function has the same access ability of private plus accessibility from the class that it is member of?

In code:

class A{
Has-A specifier: //imaginary syntax
    int x;
};
class B{
    void do_somthing(){
        a.x=5; //OK
    }
    A a;
};
int main(){
     A.x=5 // Denied- x is not accessible 
}

In other words, I want that the class B to be friend automatically without adding any code line to any class that relate to it with Has-A relationship. Is it possible?

Note: I know that friendship will allow it to access all its private members not just x. If it could friendship on variable/function level, it would be great. If not, a global friendship is also nice.

Humam Helfawi
  • 19,566
  • 15
  • 85
  • 160
  • 2
    No, that's not possible. Sent a clearer proposal to the [c++ standards commitee](https://isocpp.org/std/the-committee). – πάντα ῥεῖ Dec 15 '16 at 18:17
  • Making `A::x` protected, and inheriting `B` from `A` perhaps? – Jack Deeth Dec 15 '16 at 18:18
  • @πάνταῥεῖ I'm sure you have reasons to write that as a comment instead of an answer? If the question is a duplicate of a standards committe proposal it must be a pretty good question! – Jack Deeth Dec 15 '16 at 18:19
  • 1
    @JackDeeth Well, I'm not sure if you could achieve something like that using some template meta programming trickery already, but I'm actually too lazy to research about that. – πάντα ῥεῖ Dec 15 '16 at 18:21
  • One way would be to write a custom preprocessor, as described, for example, in http://stackoverflow.com/questions/3545875/custom-gcc-preprocessor. – Stephan Lechner Dec 15 '16 at 20:14
  • Another way could be to use preprocessor makros like "#ifndef memberpublic #define memberpublic private: " where class A is defined, and override this definition with #define memberpublic public: where ever the headerfile of class A is to be included and access to A.x shall be permitted. Still tricky and error prone, but maybe it helps. – Stephan Lechner Dec 15 '16 at 20:22

1 Answers1

2

I have tested the following setup in XCode with apple compiler and GNU++ language dialect; the setup has to be used - if to be used at all - with care. See remarks at the end of the answer.

Suppose a header file defining class A as follows:

// testprivateA.h:
#ifndef memberpublic
#define memberpublic private:
#endif

class A {

memberpublic

    int x;
};

#undef memberpublic

... and a separate headerfile defining class B:

// testprivateB.h:
#include "testprivateA.h"

class B {

public:
    void test();

    A a;
};

At the place where member function B::test() is implemented, define memberpublic as public::

// testprivateB.cpp:
#define memberpublic public:
#include "testprivateB.h"

void B::test()
{
    a.x = 5;  // OK
}

Whereas at any other place, where class A is used, let memberpublic remain undefined; accessing member variable A.x then yields a compiler error:

// anyOtherFile.cpp:
#include "testprivateB.h"
void testfail()
{
    A a;
    a.x = 5; // Error: 'x' is a private member of 'A'
}

One now may ask if this behaviour is according to c++ standard or not. And the answer to this question is - actually not (though it took me a while to find out why).

Though there may be more than one definition of a class in a program, above setting contradicts the One Definition Rule, because different access specifiers lead to different sequences of tokens:

There can be more than one definition in a program, as long as each definition appears in a different translation unit, of each of the following: class type, enumeration type, inline function with external linkage inline variable with external linkage (since C++17), class template, non-static function template, static data member of a class template, member function of a class template, partial template specialization, as long as all of the following is true: - each definition consists of the same sequence of tokens (typically, appears in the same header file)

Still it could work, but the main issue is the connection of memory layout and access specifiers as defined in access specifiers - cppreference.com:

Any number of access specifiers may appear within a class, in any order. Member access specifiers may affect class layout: the addresses of non-static data members are only guaranteed to increase in order of declaration for the members with the same access. For StandardLayoutType, all non-static data members must have the same access. ...

Still it can work, if all non-static data members in the respective class have the same access specifier. If it is a good solution, one may decide...

Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58
  • Hm... I'll be interested in hearing from someone who knows the C++ Standard better than I do as to whether or not this behavior is standardized. – Silvio Mayolo Dec 15 '16 at 21:02
  • @Silvio: I spent some more time in investigating standard conformity. Results say that my proposed solution is not standard conform, and it 'could' work only for specific cases. Nevertheless, I kept the solution and discussed this topic at the end of the answer. – Stephan Lechner Dec 29 '16 at 22:38