cli C++ funny static value in wrapper
//CCodeWrapperIF.h
public ref class CCodeWrapperIF
{
public:
CCodeWrapperIF// Default constructor
public:
static UINT8 funny;
void foo(void);
}
//CCodeWrapperIF.cpp
extern "C"
{
#include "CCodeWrapperIF.h"
}
[DllImport("CCode.DLL", CallingConvention = CallingConvention::Cdecl)]
extern "C" void CCode_Foo(void);
CCodeWrapperIF::CCodeWrapperIF(void)
{
}
CCodeWrapper开发者_StackOverflow中文版IF::foo(void)
{
CCode_Foo();
}
//a.h
public ref class A
{
private: static CCodeWrapperIF^ CCode_IFObject;
A(void)
{
CCode_IFObject=gcnew CCodeWrapperIF();
}
}
//b.h
public ref class B
{
private: static CCodeWrapperIF^ CCode_IFObject;
B(void)
{
}
}
//main.h
int main(cli::array<System::String ^> ^args)
{
A^ aObj=gcnew A();
B^ bObj=gcnew B();
// Funny thing is : bObj->CCode_IFObject->funny has correct value always!
// while if you watch the value of bObj->CCode_IFObject acturally it is not defined!!
}
can anyone explain this?
Static members don't need an instance.
bObj->CCode_IFObject->funny
is converted at compile-time to refer directly to CCodeWrapperIF::funny
.
EDIT: Adding relevant text from the standard, section Class member access [expr.ref]
, wording from the C++0x FCD
If E2 is declared to have type “reference to T,” then E1.E2 is an lvalue; the type of E1.E2 is T. Otherwise, one of the following rules applies.
— If E2 is a static data member and the type of E2 is T, then E1.E2 is an lvalue; the expression designates the named member of the class. The type of E1.E2 is T.
— If E2 is a non-static data member ... the expression designates the named member of the object designated by the first expression.
...
As you can see, for non-static members the "object delegated by the first expression" must be valid. But static members can be identified by the dot notation just like non-static members, and the first expression does not have to be any object at all, only the class matters.
精彩评论