Having a module interface, I thought it would be worthwhile to close the internal field from external access, i.e. do something like this:

class A { // Если будет проблема с оффсетами то думаю последовательное объявление // хоть как-то поможет public: virtual void some_public_method(); ... private: void* some_private_data; ... }; 

But give the include folder with the following headings:

 class A { public: virtual void some_public_method(); ... }; 

But, when returning headers, delete all private fields, i.e. leave only public methods. I would like to know whether such a decision will affect the performance of the class when working with internal fields?

  • one
    The question is not very clear, but it seems you need pimpl - αλεχολυτ
  • one
    It seems to me that this can not be done. - Qwertiy
  • 2
    @alexolut, he wants to leave in the h-file only the description of the public part, and the private one, respectively, will only be in the c-implementation. - Qwertiy
  • @Qwertiy: Yes, that's exactly what I want to do - LLENN
  • one
    So you define the interface (that is, the class with all virtual methods) separately. And the implementation class (with private fields) that implements this interface is not exposed. - VTT

4 answers 4

In the C ++ standard language, this is called a violation of the Rules of One Definition (ODR violation). Because in the same program there are two different definitions of the same class.

More specifically, the standard allows more than one definition if they are equivalent. Which means that different definitions should consist of the same sequence of tokens.

Paragraph 3.2 of the C ++ Standard:

6 There is a class type (Clause 9) ...
Given

- each definition of D shall consist of the same sequence of tokens; ...

Violation of this rule will be undefined behavior:

The behavior is undefined.


A solution to the problem in this case would be, for example, the use of the idiom PIMPL, as already mentioned, or the use of a purely virtual interface as the base class.

    I believe that it is impossible to do this, since the compiler, if the class is declared incorrectly, can access fields by incorrect offsets.

    • And if you mark the methods virtual for generating the vtable , it will not fix this problem? - LLENN

    void* unsuccessfully, learn PIMPL https://habr.com/post/111602/ well written also in "difficult tasks" (Sutter coat of arms).

    • one
      Um .. And how does this relate to the question? - Qwertiy
    • I do not understand where does the PIMPL ... - LLENN

    PIMPL = implementation pointer. A new class is created with a pointer to a secret object. Only the hpp of this class is laid out , in which the public methods of the secret object are mainly registered. A title of a secret object, as it were forgotten to lay out. Basically this idea was for the implementation of libraries. Minus in speed. Public.hpp:

     class Secret; class Public{ public: Public(); ~Public(); void PublicMethod(); private: Secret * s ; }; 

    Public.cpp:

     Public::Public():s(new Secret){} Public::~Public(){delete s;} void Public::PublicMethod(){s->PublicMethod();} 

    Secret.hpp:

     class Secret{ public: Secret(); void PublicMethod(); private: void PrivateMethod(); }; 

    Another option to restrict access to private fields is to create two classes, private and public. All load directly public class, and the implementation of the private is loaded automatically.

     // private.hpp class Private { protected: int privatex; int PrivateF(); }; // private.cpp # include "public.hpp" int Private::PrivateF(){return privatex+((Public*)this)->publicx;} // public.hpp # include "private.hpp" class Public : public Private { public : int publicx ; int PublicF(); }; // public.cpp # include "public.hpp" int Public::PublicF(){return privatex + PrivateF();} // main.cpp # include "public.hpp" int main(){ Public x; // x.privatex ; // нет доступа // x.PrivateF(); // нет доступа x.PublicF(); // ok x.publicx = 0; // ok } //> g++ -c main.cpp public.cpp private.cpp //> g++ main.o private.o public.o 

    This option does NOT increase compilation speed. Only modestly hides the implementation.

    • The class can be divided into two parts: private and public. They are in different files and do not load anyone. Look in my answer. - AlexGlebe