0

我有一个 COM 对象。在主要课程中,我创建了两个公共成员。

public:
    HANDLE                  m_hVoiceData;
    void*                   m_pVoiceData;

它们用于映射文件。我在 COM 对象的实例化处映射文件。

COM 对象的主类有一个私有类。从这个私有类我想访问这些公共成员:

这就是我想要访问映射文件的方式:

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

但是编译器不喜欢这样。它说“非静态成员引用必须相对于某个对象”。

谁能告诉我如何正确地做到这一点?我知道在主类中公开成员,但我需要这样做,因为私有类(如上所述)也有私有类,它们都需要这个成员来访问某个映射文件。


这是我映射文件的地方:

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 );
}

进而

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 是一个类。它是 COM 对象主类的私有成员。

该类有子类,例如:CTTSEngObj.m_App.SomeSmallClass

SomeSmallClass 需要访问映射的文件。

4

3 回答 3

2

要访问非静态成员,您需要拥有该类的实例。根据您的需要,使成员成为静态成员或创建实例。

在您的代码m_pVoiceData中是一个实例成员,但您尝试直接从类中访问它CTTSEngObj::m_pVoiceData

这相当于

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

要解决此问题,您需要一个实例CTTSEngObjm_pVoiceData必须是静态的。

于 2013-04-03T12:23:23.107 回答
0

静态意味着对象只会被初始化一次,并且对于同一类的每个实例都是相同的,如下所示:

    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
    }

因此,如果您希望创建的每个对象都不同,则需要将其设置为非静态并通过该类的现有实例访问它。

于 2013-04-03T13:02:10.977 回答
0

静态变量是类特定的,成员变量是对象特定的。

  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;
}

因此,如果我们必须在对象之间共享一些公共数据并且成员变量是特定于对象的,则使用静态变量。

于 2015-01-17T12:07:55.757 回答