Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
170 views
in Technique[技术] by (71.8m points)

c++ - First member of class

I know the following is bad but i was under the impression that the first member of class is the starting address of the class. Is it wrong ?

   class A{
      public:
       int a;
       int b;
   };

   class B{
     public :
       int x;
   };

   int main()
   {
        B *pb=new B();
        A *pa=(A*)pb;
        pa->a++;
   }

I was under the impression that pb->x would be incremented by 1. Is it always true or undefined ? Why does it change when we have user defined constructors or virtual functions ?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This holds only true if your class is of standard_layout type. This you can test using the type trait is_standard_layout

 std::cout << std::is_standard_layout<A>::value << '
';
 std::cout << std::is_standard_layout<B>::value << '
';

For other classes, you have additional information stored in memory, which is compiler specific and not standardized. You can have a look at This question where some memory layouts are discussed and showed.

For your second example/question the standard has the following quote (5.2.10/7, N3337 draft):

An object pointer can be explicitly converted to an object pointer of a different type. When a prvalue v of type “pointer to T1” is converted to the type “pointer to cv T2”, the result is static_cast(static_cast(v)) if both T1 and T2 are standard-layout types (3.9) and the alignment requirements of T2 are no stricter than those of T1, or if either type is void. Converting a prvalue of type“pointer to T1” to the type “pointer to T2” (where T1 and T2 are object types and where the alignment requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer value. The result of any other such pointer conversion is unspecified.

If i read and interpret this correctly, then your example is unspecified, as the alignment requirements of A are bigger that those of B. However, the other way should be ok, e.g:

int main()
{
    A *pa=new A();
    B *pb=reinterpret_cast<B*>(pa);
    pb->x++;
    std::cout << pa->a;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...