1

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 ?

DarkMatter
  • 306
  • 2
  • 13

1 Answers1

4

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.

newacct
  • 119,665
  • 29
  • 163
  • 224
  • Thanks for detailed answer. Would you recommend always using PImpl, even when you only need default constructor (so PImpl becomes second nature), or would you use the category/extension solution to avoid the extra PImpl code in this case ? – DarkMatter Feb 08 '17 at 07:48