locked
Classes with __declspec (dllexport) affects compilation of CObject RRS feed

  • Question

  • Hi,

    Greetings. Can someone explain to me what is causing this call to not compile, it basically generates the error during compilation:

    error C2248: 'CObject::operator =' : cannot access private member declared in class 'CObject'

    class __declspec( dllexport ) ClassName : public CTypedPtrArray<InputA, InputBB*> 

    This code compiled successfully in VS 2003, but not in VS 2012. Alternatively, commenting out __declspec ( dllexport ) causes the code to compile as well.

    Really appreciate the assistance.

    Tuesday, October 29, 2013 4:44 PM

Answers

  • Hi,

    CObject declares a private copy constructor and operator =.


    So, the compiler doesn't generate a default copy constructor and operator= for the CObject-derived class. You need to implement copy constructor and assignment operator for the CObject-derived class yourself.

    It is also documented here, with sample code:

    http://msdn2.microsoft.com/en-us/library/ccb3dh5c.aspx

    According to your code snippet, if you remove the base class “public CTypedPtrArray<InputA, InputBB*>”, there will be no error. Or you need to implement copy constructor and assignment operator for the base class, if the template parameter class also derived from CObject, you also need to do the same thing for them.

    I reproduce the issue like this,

    class CSample : public CObject
    {
    private:
        short m_nValue;
    public:
    
    // uncomment the lines below to avoid the compiler errors
        //CSample() {}
        //CSample( const CSample &s )  // copy ctor
        //    { m_nValue = s.m_nValue; }
        //CSample& operator=( const CSample &s )  // assignment operator
        //    { m_nValue = s.m_nValue; return *this; }
    };
    
    
    
    class __declspec( dllexport )test: public CSample{
    	
    public:
    	void setvalue(int a);
    	int  getvalue(test c);
    	test(){};
    	~test(){};
    	test(int a){ value = a; }
    private:
    	int value;
    
    };
    
    void test::setvalue(int a){
    	value = a;
    }
    
    int test::getvalue(test c){
    
    	return c.value;
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	test demo1(20);
    	test demo2 =demo1;// this will need copy constructor and operator=
    	return 0;
    }
    

    When I comment the implementation code of CSample copy constructor and assignment operator, compiler will display

    e:\project\objecttest\mfclibrary1\mfclibrary1.cpp(27): error C2248: 'CObject::CObject' : cannot access private member declared in class 'CObject'

    1>          c:\program files (x86)\microsoft visual studio 11.0\vc\atlmfc\include\afx.h(559) : see declaration of 'CObject::CObject'

    1>          c:\program files (x86)\microsoft visual studio 11.0\vc\atlmfc\include\afx.h(534) : see declaration of 'CObject'

    1>              This diagnostic occurred in the compiler generated function 'CSample::CSample(const CSample &)'

    When I uncomment those code, it will compile well without any errors.

    Hope this can help you.

    Best Regards,

    May


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Wednesday, October 30, 2013 3:23 AM
  • Hi Aqui,

    Thanks for your feedback.

    Links below for your reference, may be helpful for you to proceed.

    /clr (Common Language Runtime Compilation)

    http://msdn.microsoft.com/en-us/library/k8d11d4s.aspx

    How to: Migrate to /clr

    http://msdn.microsoft.com/en-us/library/ms173265.aspx

    Best Wishes,

    May


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Wednesday, November 6, 2013 1:31 AM

All replies

  • Hi,

    CObject declares a private copy constructor and operator =.


    So, the compiler doesn't generate a default copy constructor and operator= for the CObject-derived class. You need to implement copy constructor and assignment operator for the CObject-derived class yourself.

    It is also documented here, with sample code:

    http://msdn2.microsoft.com/en-us/library/ccb3dh5c.aspx

    According to your code snippet, if you remove the base class “public CTypedPtrArray<InputA, InputBB*>”, there will be no error. Or you need to implement copy constructor and assignment operator for the base class, if the template parameter class also derived from CObject, you also need to do the same thing for them.

    I reproduce the issue like this,

    class CSample : public CObject
    {
    private:
        short m_nValue;
    public:
    
    // uncomment the lines below to avoid the compiler errors
        //CSample() {}
        //CSample( const CSample &s )  // copy ctor
        //    { m_nValue = s.m_nValue; }
        //CSample& operator=( const CSample &s )  // assignment operator
        //    { m_nValue = s.m_nValue; return *this; }
    };
    
    
    
    class __declspec( dllexport )test: public CSample{
    	
    public:
    	void setvalue(int a);
    	int  getvalue(test c);
    	test(){};
    	~test(){};
    	test(int a){ value = a; }
    private:
    	int value;
    
    };
    
    void test::setvalue(int a){
    	value = a;
    }
    
    int test::getvalue(test c){
    
    	return c.value;
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	test demo1(20);
    	test demo2 =demo1;// this will need copy constructor and operator=
    	return 0;
    }
    

    When I comment the implementation code of CSample copy constructor and assignment operator, compiler will display

    e:\project\objecttest\mfclibrary1\mfclibrary1.cpp(27): error C2248: 'CObject::CObject' : cannot access private member declared in class 'CObject'

    1>          c:\program files (x86)\microsoft visual studio 11.0\vc\atlmfc\include\afx.h(559) : see declaration of 'CObject::CObject'

    1>          c:\program files (x86)\microsoft visual studio 11.0\vc\atlmfc\include\afx.h(534) : see declaration of 'CObject'

    1>              This diagnostic occurred in the compiler generated function 'CSample::CSample(const CSample &)'

    When I uncomment those code, it will compile well without any errors.

    Hope this can help you.

    Best Regards,

    May


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Wednesday, October 30, 2013 3:23 AM
  • Hi May,

    Thank you for your response. In terms of your input, the issue is actually - for some reason occurs when I put in __declspec( dllexport ) and not the base class.

    class __declspec( dllexport ) ClassName : public CTypedPtrArray<InputA, InputBB*>

    /*Gets the error

    error C2248: 'CObject::operator =' : cannot access private member declared in class 'CObject' */

    class ClassName : public CTypedPtrArray<InputA, InputBB*>

    /* Compiles properly */



    Thursday, October 31, 2013 2:04 PM
  • Hi,

    According to your error message, as what I post last, CObject declares a private copy constructor and operator =,  so, the compiler doesn't generate a default copy constructor and operator= for the CObject-derived class. You need to implement copy constructor and assignment operator for the CObject-derived class yourself. Did you try to do this suggestion?

    How did you define the parameter for CTypedPtrArray, what is InputA and InputBB* ? Are InputA and InputBB derived from CObject class? Also if you just write like this class __declspec( dllexport ) ClassName without  

    public CTypedPtrArray<InputA, InputBB*> , then how about the result?

    I did a similar reproduce in VS2012, there is no problem for me.

    So, maybe you can provide a small reproduce code through skydrive, then feedback your url here, then we can reproduce again.

    Best Wishes,

    May


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.



    Friday, November 1, 2013 6:13 AM
  • Hi May,

    Your insights are greatly appreciated.

    The following raw code snippet will reproduce the said error (I used a different datatype CMap but they pretty much behave the same) .

    #include <afxtempl.h>
    class __declspec( dllexport ) CDllExportTest : public CObject  
    {
    };
    class __declspec( dllexport ) CDllExportTestMap : public CMap<int, int, CDllExportTest*, CDllExportTest*&>  /*comment this dllexport__declspec( dllexport ) to make it compile properly*/
    {
    };

    Also, your initial suggestion of trying to compile just __declspec( dllexport ) ClassName, compiled correctly.
    Friday, November 1, 2013 9:52 PM
  • Hi,

    Thanks for your feedback.

    The issue actually is explained by my first reply. Now based on your reproduce code, I reproduce again.

    The root cause is that CDllExportTestMap's  base class CMap has a parameter of CDllExportTest, but CDllExportTest is CObject-derived class. CObject declares a private copy constructor and operator =. So, the compiler doesn't generate a default copy constructor and operator= for the CObject-derived class. You need to implement copy constructor and assignment operator for the CObject-derived class yourself. Otherwise, if you create a CDllExportTestMap class instance demo1, then you want to create another CDllExportTestMap instance demo2 with assignment of demo1. You will meet the “error C2248: 'CObject::CObject' : cannot access private member declared in class 'CObject' ”.

    First, I didn't write anything, just to compile the code you provided. It compiles well.

    When I create class instance but without assignment, it can compile well.

    But when I create another instance with assignment of the previous instance, it will display the error.

    PS: Because I only can post two pictures in one reply, so this picture I will post later.

    Hope this is clear for you.

    Best Wishes,

    May


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.


    Monday, November 4, 2013 2:23 AM
  • > But when I create another instance with assignment of the previous instance, it will display the error.

    For this picture:


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Monday, November 4, 2013 2:29 AM
  • Hi May,

    Thank you for the extensive explanation. While I understand that not properly creating a copy constructor will shoot out the error, I'd like to reiterate that the compilation error occured even before my implementation or use of the class.

    I actually cannot replicate your working code unless i take out

    __declspec( dllexport )

    An information that might have been missed out is my environment. I am currently using VS 2012 with this code compiled as a dynamically linked library under /clr:oldsyntax option.

    Here is the error I got when i tried your initial test code

    #include <afxtempl.h>
    class __declspec( dllexport ) CDllExportTest : public CObject  
    {
    };
    class  __declspec( dllexport ) CDllExportTestMap : public CMap<int, int, CDllExportTest*, CDllExportTest*&>
    {
    };
    int _tmain(int argc, _TCHAR* argv[]){
    	CDllExportTestMap demo1;
    	//CDllExportTestMap demo2=-demo1;
    }


    1>------ Build started: Project: TestProj, Configuration: Debug Win32 ------
    1>cl : Command line warning D9035: option 'clr:oldsyntax' has been deprecated and will be removed in a future release
    1>  DllExportTest.cpp
    1>  _WIN32_WINNT not defined. Defaulting to _WIN32_WINNT_MAXVER (see WinSDKVer.h)
    1>C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\atlmfc\include\afxtempl.h(1329): error C2248: 'CObject::CObject' : cannot access private member declared in class 'CObject'
    1>          C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\atlmfc\include\afx.h(561) : see declaration of 'CObject::CObject'
    1>          C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\atlmfc\include\afx.h(534) : see declaration of 'CObject'
    1>          This diagnostic occurred in the compiler generated function 'CMap<KEY,ARG_KEY,VALUE,ARG_VALUE>::CMap(const CMap<KEY,ARG_KEY,VALUE,ARG_VALUE> &)'
    1>          with
    1>          [
    1>              KEY=int,
    1>              ARG_KEY=int,
    1>              VALUE=CDllExportTest *,
    1>              ARG_VALUE=CDllExportTest *&
    1>          ]
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

    Your input is greatly appreciated.

    Monday, November 4, 2013 3:55 PM
  • Hi,

    Why you set  /clr:oldsyntax option? My reproduce code is without this setting and my reproduce code is win32 console application.

    How about you remove /clr:oldsyntax option?

    Best Wishes,

    May


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Tuesday, November 5, 2013 6:34 AM
  • Hi May,

    The project where I pulled out the source code from was from an old VS 2003 project which we migrated to VS2012 - from which the project compiler option was set to this. Removing the /clr:oldsyntax option did resolve the error, but I assume would need to make use of of the compiler option for us to proceed. I was wondering if there is some sort for option that I can use to exclude this.

    Regards,
    Aqui

    Tuesday, November 5, 2013 4:17 PM
  • Hi Aqui,

    Thanks for your feedback.

    Links below for your reference, may be helpful for you to proceed.

    /clr (Common Language Runtime Compilation)

    http://msdn.microsoft.com/en-us/library/k8d11d4s.aspx

    How to: Migrate to /clr

    http://msdn.microsoft.com/en-us/library/ms173265.aspx

    Best Wishes,

    May


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Wednesday, November 6, 2013 1:31 AM
  • I met the same problem  and your solution seems doesn't work.

    it can only be compiled successful if use the No Common Language Runtime Support

    the code as following:

    class  __declspec(dllexport) CDllExportTestMap : public CMap<int, int, CString*, CString*&>
    {

    };
    int _tmain(int argc, _TCHAR* argv[]){
            CDllExportTestMap demo1;
    }

    I include this code in a win32 console application. I need compile the application with Common Language Runtime support.

    Thanks

    Thursday, November 26, 2015 3:51 AM