У меня есть 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 должен получить доступ к сопоставленному файлу.
Для доступа к нестатическим членам вам необходим экземпляр класса. Либо сделайте члены статичными, либо создайте экземпляр, в зависимости от того, что вам нужно.
В вашем коде m_pVoiceData
является членом экземпляра, но вы пытаетесь получить к нему доступ непосредственно из класса CTTSEngObj::m_pVoiceData
это эквивалентно
class A
{
int a;
};
main()
{
int b = A.a; //same error
}
Чтобы это исправить, вам нужен экземпляр CTTSEngObj
или же m_pVoiceData
должен быть статичным.
Статический означает, что объект будет инициализирован только один раз и будет одинаковым для каждого экземпляра одного и того же класса, примерно так:
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
}
Поэтому, если вы хотите, чтобы a отличалось для каждого создаваемого вами объекта, вам нужно установить его как нестатический и обращаться к нему через существующий экземпляр класса.
Статические переменные зависят от класса, а переменные-члены зависят от объекта.
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;
}
Таким образом, статические переменные используются, если мы должны делиться некоторыми общими данными между объектами, а переменные-члены специфичны для объектов.