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...