Search code examples
c++objective-cobjective-c++pimpl-idiom

Using C++ class in Objective-C - Why use PImpl idiom?


Suppose I have a simple C++ class:

// MyCPPClass.hpp
class MyCPPClass {
    std::uint8_t m_num1 = 0;
    std::uint8_t m_num2 = 0;

    std::string GetText() const;
}

and I want to use this in an Objective-C class:

// MyObjCClass.h
@interface MyObjCClass {


    @public
        MyCPPClass _cppObj;
}

What do I really gain from using PImpl idiom over just embedding it directly into the Obj-C class (as above), aside from having to write more code for the PImpl part ?


Solution

  • The downside is this C++ type MyCPPClass is now in the header file MyObjCClass.h, which other Objective-C classes that use MyObjCClass will have to import. Importing a header is like putting it into the code, so these other Objective-C classes now have C++ in their code, and so will now have to be changed to Objective-C++ files or they won't compile. This is often not desirable, as these other files shouldn't need C++. Although this problem can be solved by declaring your instance variable not in the main class declaration in the header, but in the "extension" (declared like a category but with no name in the parentheses) or in the @implementation, which are in the implementation file, so other classes don't have to import it.

    Another problem with C++ classes as instance variables of Objective-C classes is that your C++ object can only be constructed using the default constructor (i.e. no constructor arguments), as there is no way to provide an initializer for an instance variable of an Objective-C class. So if you want to construct it with constructor arguments, you must use pimpl.