title: C++ and Maya: constructor is private within this context
body: <p>I'm compiling a program that uses the Autodesk Maya API, and getting an error about a constructor being private within this context:</p>
  
  <pre><code>/usr/autodesk/maya2013-x64/include/maya/MFnTransform.h: In member function ‘MayaEggGroup* MayaEggLoader::MakeGroup(EggGroup*, EggGroup*)’:
  /usr/autodesk/maya2013-x64/include/maya/MFnTransform.h:181:2: error: ‘MFnTransform::MFnTransform(const MFnTransform&amp;)’ is private
  pandatool/src/mayaegg/mayaEggLoader.cxx:373:60: error: within this context
  </code></pre>
  
  <p>A little background - I'm building <a href="http://www.panda3d.org" rel="nofollow">Panda3D</a>, (an open-source game engine), on Ubuntu 12.04, with Maya 2013. It's choking on a part of the build where it's compiling exporters that convert files from Maya into Panda's model format.  </p>
  
  <p>I (sort of) understand what the error means, but not how to solve it.  The odd thing is that the same code compiles fine with Maya 2011 and Maya 2012, and the class declaration (MFnTransform) has not changed in Maya 2013 as far as I can tell.  </p>
  
  <p>Here's the g++ command in full:</p>
  
  <pre><code>g++ -ftemplate-depth-30 -fPIC -c -o built/tmp/mayaegg2013_loader.o -Ibuilt/tmp -Ibuilt/include -I/usr/include/python2.7 -I/usr/include/eigen3 -I/usr/autodesk/maya2013-x64/include -DMAYAVERSION=MAYA2013 -DMAKEPANDA= -Ipandatool/src/mayaegg -Ipandatool/src/maya -pthread -msse2 -ggdb -D_DEBUG pandatool/src/mayaegg/mayaEggLoader.cxx   
  </code></pre>
  
  <p>And some of the relevant bits of code.</p>
  
  <p>In mayaEggLoader.cxx, here's where the error originates:</p>
  
  <pre class="lang-cpp prettyprint-override"><code>class MayaEggGroup
  {
  public:
    string  _name;
    MObject _parent;
    MObject _group;
  
    bool _addedEggFlag;
  };
  MayaEggGroup *MayaEggLoader::MakeGroup(EggGroup *group, EggGroup *context)
  {
      MStatus status;
      MayaEggGroup *result = new MayaEggGroup;
      ...
      MFnTransform tFn = MFnTransform(result-&gt;_group, &amp;status);
  </code></pre>
  
  <p>and from MFnTransform.h, here's the beginning of the definition of MFnTransform:</p>
  
  <pre class="lang-cpp prettyprint-override"><code>class OPENMAYA_EXPORT MFnTransform : public MFnDagNode
  {
  declareDagMFn( MFnTransform, MFn::kTransform );
  public:
  MObject     create( MObject parent = MObject::kNullObj,MStatus * ReturnStatus = NULL );
      ...
  </code></pre>
  
  <p>I don't see where a private constructor is defined at all ... how do I go hunting for it?  Or can that error mean that something else is actually wrong?</p>
  
  <p>Updates:</p>
  
  <p>It turns out this is a known bug introduced in the Maya 2013 C++ API:</p>
  
  <blockquote>
    <p>MAYA-6512: MFnDependencyNode, MFnDagNode copy constructor should be public, not private 
    Workaround: Create a new functionset which operates on the same object, for example: 
    MFnDependencyNode fn2(fn1.object());
    If you want to pass a functionset to another method, pass a reference instead. </p>
  </blockquote>
  
  <p>Ok, but what if I need to set a member variable?  Here is another place where I'm getting the same error.</p>
  
  <pre><code>MayaBlendDesc::
  MayaBlendDesc(MFnBlendShapeDeformer deformer, int weight_index) 
  {
      _weight_index=weight_index;
      _deformer=deformer;
      ostringstream strm;
      strm &lt;&lt; _deformer.name().asChar() &lt;&lt; "." &lt;&lt; _weight_index;
      set_name(strm.str());
  
      _anim = (EggSAnimData *)NULL;
  }
  </code></pre>
  
  <p>On the line "_deformer=deformer".</p>
  
  <p>Here is the definition of MayaBlendDesc.  This is code I can edit.</p>
  
  <pre><code>////////////////////////////////////////////////////////////////////
  //       Class : MayaBlendDesc
  // Description : A handle to a Maya blend shape description.  This is
  //               just one target of a Maya BlendShape object, and
  //               thus corresponds more or less one-to-one with a
  //               single Egg morph target.  (We don't attempt to
  //               support Maya's chained target shapes here; should we
  //               need to later, it would mean breaking each of those
  //               target shapes on the one continuous Maya slider into
  //               a separate MayaBlendDesc object, and synthesizing the
  //               egg slider values appropriately.)
  ////////////////////////////////////////////////////////////////////
  class MayaBlendDesc : public ReferenceCount, public Namable {
  public:
    MayaBlendDesc(MFnBlendShapeDeformer deformer, int weight_index);
    ~MayaBlendDesc();
  
    void set_slider(PN_stdfloat value);
    PN_stdfloat get_slider() const;
  
  private:
    void clear_egg();
  
    MFnBlendShapeDeformer _deformer;
    int _weight_index;
  
    EggSAnimData *_anim;
  
  public:
    static TypeHandle get_class_type() {
      return _type_handle;
    }
    static void init_type() {
      ReferenceCount::init_type();
      Namable::init_type();
      register_type(_type_handle, "MayaBlendDesc",
                    ReferenceCount::get_class_type(),
                    Namable::get_class_type());
    }
  
  private:
    static TypeHandle _type_handle;
  
    friend class MayaNodeTree;
  };
  </code></pre>
  
  <p>Here's the definition of MFnBlendShape and its ancestors (part of the Maya API, which I can't touch):</p>
  
  <pre><code>class OPENMAYAANIM_EXPORT MFnBlendShapeDeformer : public MFnDependencyNode
  {
      declareMFn(MFnBlendShapeDeformer, MFnDependencyNode );
  
  public:
      //! Specifies the space to use for the deformation origin.
      enum Origin {
          kLocalOrigin,   //!&lt; \nop
          kWorldOrigin    //!&lt; \nop
      };
  
      //! Specifies where in the shape's history to place the deformer.
      enum HistoryLocation {
          kFrontOfChain,  //!&lt; \nop
          kNormal     //!&lt; \nop
      };
  
      MObject  create(  MObject baseObject,
                        Origin originSpace = kLocalOrigin,
                        MStatus * ReturnStatus = NULL );
      MObject  create(  const MObjectArray&amp; baseObjects,
                        Origin originSpace = kLocalOrigin,
                        HistoryLocation = kNormal,
                        MStatus * ReturnStatus = NULL );
      MStatus  addBaseObject( MObject &amp; object );
      MStatus  getBaseObjects( MObjectArray &amp; objects ) const;
  
      MStatus  addTarget( const MObject &amp; baseObject, int weightIndex,
                          const MObject &amp; newTarget, double fullWeight );
  
      MStatus  removeTarget( const MObject &amp; baseObject,
                             int weightIndex,
                             const MObject &amp; target,
                             double fullWeight );
      MStatus  getTargets( MObject baseObject, int weightIndex,
                           MObjectArray &amp; targetObjects ) const;
  
      unsigned int numWeights( MStatus * ReturnStatus = NULL ) const;
  
      MStatus  weightIndexList( MIntArray&amp; indexList ) const;
  
      MStatus  targetItemIndexList( unsigned int weightIndex,
                                    MObject baseObject,
                                    MIntArray&amp; targetItemIndices ) const;
  
      float    weight( unsigned int index, MStatus * ReturnStatus = NULL ) const;
      MStatus  setWeight( unsigned int index, float weight );
  
      float    envelope( MStatus * ReturnStatus = NULL ) const;
      MStatus  setEnvelope( float envelope );
  
      Origin   origin( MStatus * ReturnStatus = NULL ) const;
      MStatus  setOrigin( Origin space );
  
  BEGIN_NO_SCRIPT_SUPPORT:
  
      declareMFnConstConstructor( MFnBlendShapeDeformer, MFnDependencyNode );
  
  END_NO_SCRIPT_SUPPORT:
  
  protected:
  // No protected members
  
  private:
  // No private members
  };
  </code></pre>
  
  <p>MFnDependencyNode:</p>
  
  <pre><code>// ****************************************************************************
  // CLASS DECLARATION (MFnDependencyNode)
  
  //! \ingroup OpenMaya MFn
  //! \brief Dependency node function set.
  /*!
    MFnDependencyNode allows the creation and manipulation of dependency
    graph nodes.  Traversal of the dependency graph is possible using
    the getConnections method.
  
    This function set does not support creation or removal of connections.
    MDGModifier should be used for that purpose.
  */
  class OPENMAYA_EXPORT MFnDependencyNode : public MFnBase
  {
      declareMFn(MFnDependencyNode, MFnBase);
  
  public:
      //! Specifies the scope of the attribute.
      enum MAttrClass {
          kLocalDynamicAttr = 1,  //!&lt; Dynamically added, applies to this specific node.
          kNormalAttr,        //!&lt; Static attribute which is part of the original definition for this node type.
          kExtensionAttr,     //!&lt; Extension attribute which is part of all nodes of this or derived node types
          kInvalidAttr        //!&lt; None of the above
      };
  
      MObject         create( const MTypeId &amp;typeId,
                                  MStatus* ReturnStatus = NULL );
      MObject         create( const MTypeId &amp;typeId,
                                  const MString&amp; name,
                                  MStatus* ReturnStatus = NULL );
  
      MObject         create( const MString &amp;type,
                                  MStatus* ReturnStatus = NULL );
      MObject         create( const MString &amp;type,
                                  const MString&amp; name,
                                  MStatus* ReturnStatus = NULL );
  
      MTypeId         typeId( MStatus* ReturnStatus = NULL ) const;
      MString         typeName( MStatus* ReturnStatus = NULL ) const;
      MString         name( MStatus * ReturnStatus = NULL ) const;
      MString         pluginName( MStatus * ReturnStatus = NULL ) const;
  
      MString         setName( const MString &amp;name,
                               bool createNamespace = false,
                               MStatus * ReturnStatus = NULL );                        
      MStatus         getConnections( MPlugArray&amp; array ) const;
      unsigned int        attributeCount( MStatus* ReturnStatus=NULL) const;
      MObject         attribute(  unsigned int index,
                                  MStatus* ReturnStatus=NULL) const;
      MObject         reorderedAttribute( unsigned int index,
                                  MStatus* ReturnStatus=NULL) const;
      MObject         attribute(  const MString&amp; attrName,
                                  MStatus* ReturnStatus=NULL) const;
      MAttrClass      attributeClass( const MObject&amp; attr,
                                      MStatus* ReturnStatus=NULL) const;
      MStatus         getAffectedAttributes ( const MObject&amp; attr,
                                      MObjectArray&amp; affectedAttributes ) const;
      MStatus         getAffectedByAttributes ( const MObject&amp; attr,
                                      MObjectArray&amp; affectedByAttributes ) const;
      MPlug           findPlug(   const MObject &amp; attr, bool wantNetworkedPlug,
                                  MStatus* ReturnStatus=NULL) const;
      MPlug           findPlug(   const MString &amp; attrName, bool wantNetworkedPlug,
                                  MStatus* ReturnStatus=NULL) const;
      // Obsolete
      MPlug           findPlug(   const MObject &amp; attr,
                                  MStatus* ReturnStatus=NULL) const;
      // Obsolete
      MPlug           findPlug(   const MString &amp; attrName,
                                  MStatus* ReturnStatus=NULL) const;
      MStatus         addAttribute    ( const MObject &amp; attr );
      MStatus         removeAttribute ( const MObject &amp; attr );
      MPxNode *       userNode( MStatus* ReturnStatus=NULL ) const;
      bool            isFromReferencedFile(MStatus* ReturnStatus=NULL) const;
      bool            isShared(MStatus* ReturnStatus=NULL) const;
      bool            hasUniqueName(MStatus* ReturnStatus=NULL) const;
      MString         parentNamespace(MStatus* ReturnStatus=NULL) const;
      bool            isLocked(MStatus* ReturnStatus=NULL) const;
      MStatus         setLocked( bool locked );
      static MString  classification( const MString &amp; nodeTypeName );
      bool            isNewAttribute( const MObject&amp; attr,
                                  MStatus* ReturnStatus=NULL) const;
      static unsigned int allocateFlag(
                          const MString pluginName, MStatus* ReturnStatus=NULL
                      );
      static MStatus  deallocateFlag(const MString pluginName, unsigned int flag);
      static MStatus  deallocateAllFlags(const MString pluginName);
      MStatus         setFlag(unsigned int flag, bool state);
      bool            isFlagSet(unsigned int flag, MStatus* ReturnStatus=NULL) const;
      bool            isDefaultNode(MStatus* ReturnStatus=NULL) const;
  
      MStatus         setDoNotWrite ( bool flag );
      bool            canBeWritten(MStatus* ReturnStatus=NULL) const;
  
      bool            hasAttribute(const MString&amp; name, MStatus* ReturnStatus=NULL) const;
  
      MObject         getAliasAttr(bool force, MStatus* ReturnStatus=NULL);
      bool            setAlias(const MString&amp; alias,const MString&amp; name, const MPlug&amp; plug, bool add=true,
                      MStatus* ReturnStatus=NULL);
      bool            findAlias(const MString&amp; alias, MObject&amp; attrObj, MStatus* ReturnStatus=NULL) const;
      bool            getAliasList(MStringArray&amp; strArray, MStatus* ReturnStatus=NULL);
      MString         plugsAlias(const MPlug&amp; plug, MStatus* ReturnStatus=NULL);
  
      MStatus         setIcon( const MString &amp;filename );
      MString         icon( MStatus* ReturnStatus=NULL ) const;
  
  
  
  BEGIN_NO_SCRIPT_SUPPORT:
  
      //! OBSOLETE FUNCTION, NO SCRIPT SUPPORT
      MString         setName( const MString &amp;name,
                               MStatus * ReturnStatus );
  
      //! NO SCRIPT SUPPORT
      declareMFnConstConstructor( MFnDependencyNode, MFnBase );
      //! NO SCRIPT SUPPORT
      bool            getPlugsAlias(const MPlug&amp; plug, MString&amp; aliasName, MStatus* ReturnStatus=NULL);
  
  END_NO_SCRIPT_SUPPORT:
  
      // turn on timing on for all nodes in the DG
      static void enableDGTiming(bool enable);
  
      // For turning node timing on and off, and querying the state...
      MStatus         dgTimerOn();
      MStatus         dgTimerOff();
  
      //! Possible states for the node's timer.
      enum MdgTimerState {
          kTimerOff,      //!&lt; \nop
          kTimerOn,       //!&lt; \nop
          kTimerUninitialized,    //!&lt; \nop
          kTimerInvalidState  //!&lt; \nop
      };
  
      MdgTimerState   dgTimerQueryState( MStatus* ReturnStatus = NULL );
  
      // For resetting node timers to zero...
      MStatus         dgTimerReset();
  
      //! The different timer metrics which can be queried.
      enum MdgTimerMetric {
          // Primary metrics. The qualities that we measure.
          kTimerMetric_callback,  //!&lt; Time spent within node callbacks for this node.
          kTimerMetric_compute,   //!&lt; Time spent within the compute method for this node.
          kTimerMetric_dirty, //!&lt; Time spent propogating dirty messages from this node.
          kTimerMetric_draw,  //!&lt; Time spent drawing this node.
          kTimerMetric_fetch, //!&lt; Time spent fetching data from plugs.
  
          // Sub metrics. These are finer-grained breakdowns of the primary
          // metrics. There could be many combinations of the above metrics.
          // Currently we only support the following.
          kTimerMetric_callbackViaAPI,    //!&lt; Time spent in callbacks which were registered through the API.
          kTimerMetric_callbackNotViaAPI, //!&lt; Time spent in callbacks not registered through the API (i.e internal Maya callbacks).
          kTimerMetric_computeDuringCallback, //!&lt; Time spent in this node's compute while executing node callbacks on any node.
          kTimerMetric_computeNotDuringCallback   //!&lt; Time spent in this nodes compute when not executing any node callbacks on any nodes.
      };
  
      //! The types of timers which can be queried.
      enum MdgTimerType {
          /*!
          Time spent performing an operation, not including any time
          spent by child operations. For example, if we are drawing a
          node and that requires a compute, self time will only include
          the time spent drawing and not the compute time. Self time
          measures wall-clock time as opposed to CPU time and the values
          are in seconds.
          */
          kTimerType_self,
  
          /*!
          Time spent performing an operation including all time spent by
          child operations. For example, if we are drawing a node and
          that requires a compute, inclusive time is the time for the
          draw plus compute. Inclusive time measure wall-clock time as
          opposed to CPU time and the values are in seconds.
          */
          kTimerType_inclusive,
  
          /*!
          The number of operations that occurred. Ideally we should
          return an integer when this timer type is queried, but there
          are two advantages to using a double. 1) it keeps the interface
          consistent and 2) integer has a fixed upper bound of roughly
          four billion so using a double allows us to exceed this.
          */
          kTimerType_count
      };
  
      // Query the timer value given a given metric and timer type.
      double  dgTimer( const MdgTimerMetric           timerMetric,
                              const MdgTimerType      timerType,
                              MStatus* ReturnStatus = NULL ) const;
  
      // Query the callback timer values.
      MStatus dgCallbacks( const MdgTimerType         type,
                              MStringArray            &amp;callbackName,
                              MDoubleArray            &amp;value );
  
      // Query the callbackId timer values.
      MStatus dgCallbackIds( const MdgTimerType       type,
                              const MString           &amp;callbackName,
                              MCallbackIdArray        &amp;callbackId,
                              MDoubleArray            &amp;value );
  
      // Obsolete
      MStatus addAttribute    ( const MObject &amp; attr, MAttrClass type );
      // Obsolete
      MStatus removeAttribute ( const MObject &amp; attr, MAttrClass type );
  
  protected:
  // No protected members
  
  private:
  // No private members
  };
  </code></pre>
  
  <p>and MFnBase:</p>
  
  <pre><code>// ****************************************************************************
  // CLASS DECLARATION (MFnBase)
  
  //! \ingroup OpenMaya MFn
  //! \brief  Function Set Base Class. 
  /*!
    Defines the interface for the API RTTI and Maya Object attachment
    methods common to all Function Set Classes.
  
    Implements the Function Set compatibility test methods for all
    Function Sets.
  
    The API provides access to Maya Objects as generic MObjects.  Under
    the C++ class scheme MObjects simply have type MObject with no base
    or derived hierarchy.  However, MObjects may be many different types
    of model or scene objects, from Attributes to Transforms, within
    Maya.  This allows many different types of objects to be moved
    across or accessed through the API without undue concern on the part
    of plug-in developers for the type of object being manipulated.
  
    Since it is impractical to provide every applicable method on
    MObjects, the methods applicable to Maya Objects are encapsulated in
    Function Sets.  Function Sets can be attached to compatible MObjects
    to provide an external interface to methods appropriate to that
    MObject.  All Function Sets provide a method setObject() which
    attaches them to the specified Maya Object.  Additionally, most
    Function Sets provide a version of their constructor which attaches
    the new Function Set to a specified MObject.
  
    The link between an MObject and the role it performs as a Maya scene
    or model object, as well as the compatibility between MObjects and
    Function Sets is managed by the API Run-Time Type Identification
    (RTTI) system.  The two key concepts of this system are the Maya
    Object type and the Function Set type (both are MFn::Type).  All
    MObjects have one and only one Maya Object type.  All Function Sets
    have one and only one Function Set type.  MObjects may, however, be
    compatible with many types of Function Sets.  This compatibility
    follows the class hierarchy of the Function Sets.  Thus an MObject
    with Maya Object type MFn::kNurbsSurface would be compatible with
    MFnNurbsSurface, MFnDagNode, MFnDependencyNode, MFnNamedObject and
    MFnBase.
  
    Any MObject can be queried with the MObject::hasFn() method to
    determine if it is comaptible with a given Function Set.
  
    The purpose of the Base Function Set (MFnBase) is to provide methods for
    determining whether or not a Function Set is compatible with a given Maya
    Object (MObject) type (MFn::Type) or a specific MObject.  See:
                      MFnBase::hasObj(MFn::Type)
                              and
                      MFnBase::hasObj(const MObject &amp;)
  
    As well, this Function Set provides virtual methods for determining the type
    of a Function Set under the API RTTI system.
  */
  class OPENMAYA_EXPORT MFnBase
  {
  public:
      virtual             ~MFnBase();
      virtual MFn::Type   type() const;
      bool                hasObj( MFn::Type ) const;
      bool                hasObj( const MObject &amp; ) const;
      MObject             object( MStatus* ReturnStatus = NULL ) const;
      virtual MStatus     setObject( MObject &amp; object );
  
  BEGIN_NO_SCRIPT_SUPPORT:
  
      //! NO SCRIPT SUPPORT
      virtual MStatus     setObject( const MObject &amp; object );
  
  END_NO_SCRIPT_SUPPORT:
  
      static const char* className();
  
  protected:
      MFnBase();
      void                setPtr( MPtrBase* );
      void                setPtr( const MPtrBase* );
      void                setPtrNull();
      virtual bool        objectChanged( MFn::Type, MStatus * );
      MPtrBase*           f_ptr;      // initialized/set with volatile
      const MPtrBase*     f_constptr; // initialized/set with volatile/const
  
      // Specific for function sets which use internally reference
      // counted objects!  Only those function sets which use these
      // objects need to set this to true.  By default it is set to
      // false.
      //
      // Classes which do not use internally reference counted objects
      // must not tamper with this boolean value. Doing so can cause
      // crashes when dealing with manually deleted objects.
      //
      bool                fIsReferenceCounted;
  
  private:
      MFnBase( const MFnBase &amp;rhs );
      MFnBase &amp; operator=( const MFnBase &amp; );
      MFnBase * operator&amp; () const;
  };
  
  // ****************************************************************************
  #define declareMinimalMFn( MFnClass )                               \
      public:                                                         \
          virtual MFn::Type type() const;                             \
          virtual ~MFnClass();                                        \
                                                                      \
          static const char* className();                             \
                                                                      \
      private:                                                        \
          MFnClass( const MFnClass &amp;rhs );                            \
          MFnClass &amp; operator=( const MFnClass &amp; );                   \
          MFnClass * operator&amp; () const;
  
  #define declareMFn( MFnClass, MFnParentClass )                      \
      declareMinimalMFn( MFnClass );                                  \
      public:                                                         \
          MFnClass() {};                                              \
          MFnClass( MObject &amp; object, MStatus * ReturnStatus = NULL )
  
  #define declareMFnConstConstructor( MFnClass, MFnParentClass )      \
          MFnClass( const MObject &amp; object, MStatus * ReturnStatus = NULL )
  
  // Standard MFn class interface *without* the class constructor. This
  // is to allow derived MFn classes to optionally specify their own
  // custom constructor. For example if they wanted to declare that they
  // use internally reference counted objects, they could set fIsReferenceCounted
  // to true inside their own custom constructor.
  //
  #define declareMFnNoVoidConstructor( MFnClass, MFnParentClass )     \
      declareMinimalMFn( MFnClass );                                  \
      public:                                                         \
          MFnClass( MObject &amp; object, MStatus * ReturnStatus = NULL )
  
  #define declareMFnNoVoidConstructorConstConstructor( MFnClass, MFnParentClass )         \
          MFnClass( const MObject &amp; object, MStatus * ReturnStatus = NULL )
  
  
  #endif /* __cplusplus */
  #endif /* _MFnBase */
  </code></pre>