【问题标题】:C++ Accessing another classes public memberC++ 访问另一个类的公共成员
【发布时间】:2013-03-25 02:41:00
【问题描述】:

我有一个 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 需要访问映射的文件。

【问题讨论】:

  • 请显示更多代码
  • "COM 对象的主类有一个私有类"。这到底是什么意思呢?你有一个嵌套类?
  • 这不是真正的 C++...:P

标签: c++ winapi com file-mapping


【解决方案1】:

要访问非静态成员,您需要有一个类的实例。根据您的需要,将成员设为静态或创建实例。

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

这相当于

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

要解决此问题,您要么需要 CTTSEngObj 的实例,要么 m_pVoiceData 必须是静态的。

【讨论】:

  • 我在上面编辑了我的解释。你说的静态是什么意思?你能告诉我一个使两个成员静态的例子吗?
  • 关于你的解释:好的,明白了。 CTTSEngObj 不是类的实例。但是我可以从 Instantiated_CTTSEngObj.SomeClass.SomeOtherClass 访问 Instantiated_CTTSEngObj.SomeMember 吗???
  • 我现在创建了一个新类(global.cpp)并在那里声明了变量。但是,我仍然无法获得 memcpy(nEncodedBytes,m_pVoiceData[iFirstByteToRead], iLenCompressedBytes);去工作。我想这是不同的问题。
  • 给定一个具有内部类 B 的类 A,B 的成员对 A 的成员没有特殊的访问权限。因此,如果它们是公共的,则它可以访问,这似乎是您使用 m_pVoiceData 的情况,因此,在您的情况下,它们应该可以访问。至于新问题,如果代码足够不同,最好在新问题中提供示例代码
【解决方案2】:

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

    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
    }

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

【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-06
      • 1970-01-01
      • 1970-01-01
      • 2015-07-11
      • 2014-07-30
      • 1970-01-01
      • 2011-05-17
      相关资源
      最近更新 更多