1

I have a COM object. In the main class I made two public members.

public:
    HANDLE                  m_hVoiceData;
    void*                   m_pVoiceData;

They are for mapping a file. I map the file at the instantiation of the COM object.

The main class of the COM object has a private class. From this private class I want to access these public members:

This is how I want to access the mapped file:

memcpy(nEncodedBytes,& CTTSEngObj::m_pVoiceData[iFirstByteToRead], iLenCompressedBytes);

But the compiler does not like this. It says that "A non-static member reference has to be relative to a certain object".

Can anybody please tell me how to do this correctly? I know that making a member public in a main class, but I need to do it because the private class (as mentioned above) also has private classes, and they all need this member to access a certain mapped file.


This is where I map the file:

STDMETHODIMP CTTSEngObj::SetObjectToken(ISpObjectToken * pToken)
{

HRESULT hr = SpGenericSetObjectToken(pToken, m_cpToken);

//--- Map the voice data so it will be shared among all instances
//  Note: This is a good example of how to memory map and share
//        your voice data across instances.
TCHAR szFileName[MAX_PATH+1];
GetModuleFileName(_Module.m_hInst, szFileName, MAX_PATH+1);
StrCpy(PathFindFileName(szFileName), _T("data.dat"));

if( SUCCEEDED( hr ) )
{
    USES_CONVERSION;//needed to make T2W work
    hr = MapFile( T2W(szFileName), &m_hVoiceData, &m_pVoiceData );
}

And then

STDMETHODIMP CTTSEngObj::Speak( DWORD dwSpeakFlags,
                            REFGUID rguidFormatId,
                            const WAVEFORMATEX * pWaveFormatEx,
                            const SPVTEXTFRAG* pTextFragList,
                            ISpTTSEngineSite* pOutputSite )
{

HRESULT hr = S_OK;

//--- Check args
if( SP_IS_BAD_INTERFACE_PTR( pOutputSite ) ||
    SP_IS_BAD_READ_PTR( pTextFragList )  )
{
    hr = E_INVALIDARG;
    return hr;
}

m_App.DoSomething();

m_App is a class. It is a private member of the COM object main class.

This class has subclasses, for example: CTTSEngObj.m_App.SomeSmallClass

And SomeSmallClass needs to access the mapped file.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
tmighty
  • 10,734
  • 21
  • 104
  • 218

3 Answers3

2

To access non-static members you need to have an instance of the class. Either make the members static or create an instance, depending on what you need.

In your code m_pVoiceData is an instance member but you try to access it directly from the class CTTSEngObj::m_pVoiceData

this is equivalent to

class A
{
  int a;
};
main()
{
  int b = A.a; //same error
}

To fix this you either need an instance of CTTSEngObj or m_pVoiceData must be static.

msam
  • 4,259
  • 3
  • 19
  • 32
  • I have edited my explanation on top. What do you mean by STATIC? Can you show me an example for making the 2 members static? – tmighty Apr 03 '13 at 12:37
  • About your explanation: Okay, understood. CTTSEngObj is not an instance of a class. But can I access the Instantiated_CTTSEngObj.SomeMember from Instantiated_CTTSEngObj.SomeClass.SomeOtherClass??? – tmighty Apr 03 '13 at 12:40
  • I created a new class now (global.cpp) and declared the variables there. However, I can still not get memcpy(nEncodedBytes,m_pVoiceData[iFirstByteToRead], iLenCompressedBytes); to work. I guess that is different question. – tmighty Apr 03 '13 at 12:49
  • given a class A with inner class B, members of B have no special access to the members of A. So it has access if they are public, which seems to be your case with `m_pVoiceData`, hence in your case they should be accessible. As for the new question, if the code is different enough it might be a better idea to give example code in a new question – msam Apr 03 '13 at 12:54
0

Static means that the object will only be initilized once and will be the same for every instance of the same class, something like this:

    class A 
    {
    public:
    static int a;
    };

    void main()
    {
        A::a = 3; // now a will contain 3 for every instance of the class;
        cout << A::a; //calling the static member without an instance of the class outputs 3
        A someA; //create some instances of the class
        A otherA;

        cout << someA.a; // outputs 3

        someA.a = 7; // assing 7 to a

        cout << otherA.a; // outputs 7 for we modified the value of the static member in another instance
    }

So if you want a to be different for every object you create, you need to set it as non-static and the access it through an existing instance of the class.

Alan Cor
  • 226
  • 1
  • 4
  • 10
0

Static variables are class specific and member variables are object specific.

  class MyClass
  {
    static int s_ObjectCount;
    unsigned int m_id;
   public:
    MyClass(int id):m_id(id)
    {
       s_ObjectCount++;
    } 

   ~MyClass()
   {
     s_ObjectCount++;
   }
   static int GetObjectCount()
   {
     return s_ObjectCount;
   }
 };
 int MyClass::s_ObjectCount = 0;

 int main(int argc, char* argv[])
 {
  MyClass a(12345);
  MyClass b(123456);
  printf("%d",MyClass::GetObjectCount());// outputs 2
  return 0;
}

So static variables are used if we have to share some common data among the objects and member variables are specific to objects.

GingerJack
  • 3,044
  • 1
  • 17
  • 19