矢量改变班级的大小

时间:2011-10-05 11:03:04

标签: c++ pointers sizeof

修改
虽然格式错误但这个问题有一个很好的问题。所以,我正在编辑这个以保留这个更好的格式,以便将来访问这个问题的访问者。


在下面的代码示例中,有人可以解释为什么memcpy之后类的大小与预期的不同?是什么原因?

Here 是Ideone的在线演示。

#include<iostream>
#include<vector>
#include<cstdio>
#include<cstring>

using namespace std;

class A
{
    public:
        int a;
        virtual void f1() { cout <<"inside a::f1\n"; }
        A() { a = 1; }
};

class B
{
    public:
        int b;
        virtual void f2() { cout <<"inside b::f2\n"; }
        virtual void f5() { cout <<"inside b::f5\n"; }
        B() { b = 2; }
};

class C : public A, public B
{
    public:
        int c;
        void f1() { cout <<"inside c::f1\n"; }
        void f2() { cout <<"inside c::f2\n"; }

        virtual void f3() { cout <<"inside c::f3\n"; }
        virtual void f4() { cout <<"inside c::f4\n"; }
        C() { c = 3; }
};


int fun()
{
    int a = 1;
    return a * 2;
}

int main()
{
    C c;
    C c2;
    int (*g)() = &fun;

    void (A::*g1)() = &A::f1;
    void (C::*g2)();

    g2 = &C::f1;
    (c.*g2)();

    printf("%p\n",g2);
    cout << sizeof(g2) << endl;

    g2 = &C::f2;
    (c.*g2)();

    printf("%p\n", g2);

    // Why is the output 1 here in g++ or visual C++?
    cout << g2;
    // Why is the sizeof returning 8? Please explain.
    cout << sizeof(g2) << endl;

    g2 = &C::f1;
    std::vector<unsigned char> a_vec(sizeof(g2));

    memcpy(&a_vec[0], &g2, sizeof(g2));
    for(size_t i = 0; i < sizeof(g2); ++i)     
    {         
        cout << hex << static_cast<unsigned>(a_vec[i]) << " ";
    } 
    cout << endl;

    g2 = &C::f2;
    std::vector<unsigned char> a_vec1(sizeof(g2));
    memcpy(&a_vec1[0], &g2, sizeof(g2));

    for(size_t i = 0; i < sizeof(g2); ++i)     
    {         
        cout << hex << static_cast<unsigned>(a_vec1[i]) << " ";
    } 
    cout << endl;

    cout << sizeof(g) <<endl;
    cout << sizeof(g1) <<endl;
    cout << sizeof(g2) <<endl;

    // Why is sizeof(C) printing 14 and not 20 in visual C++?
    // If yes why is this so ?
    cout << sizeof(C) << endl;
    cout << sizeof(c2) << endl;
    cout << (&c) << endl;
    cout << c.a << endl;
    cout << c.b << endl;
    cout << c.c << endl;

    return 0;
}

从上面的代码示例中得到的输出是:

inside c::f1
0x1
8
inside c::f2
0x5
18
1 0 0 0 0 0 0 0 
5 0 0 0 0 0 0 0 
4
8
8
14
14
0xbffe375c
1
2
3   

以下是我的问题:

  1. 为什么g ++或visual C ++中的输出1在这里?

      

    cout&lt;&lt; G2;

  2. 为什么sizeof返回8?请解释一下。

      

    cout&lt;&lt; sizeof(g2)&lt;&lt; ENDL;

  3. 为什么sizeof(C)在Visual C ++中打印14而不是20?如果是,为什么会这样呢?

      

    cout&lt;&lt; sizeof(C)&lt;&lt; ENDL;

2 个答案:

答案 0 :(得分:3)

为什么sizeof返回8。请解释一下?

cout <<sizeof(g2)<<endl;  

返回8,因为g2是指针,并且环境中指针的大小为8。


为什么g ++或visual C ++中的输出1在这里?

cout << g2; 

<< operator没有接受指针的重载版本。因此指针转换为bool类型,值为1,cout打印它。

C ++标准允许:

C ++ 03标准4.12布尔转换

  

1算术,枚举,指针或指向成员类型的指针的右值可以转换为bool类型的右值。


为什么sizeof(C)在Visual C ++中打印14而不是20

cout<<sizeof(C)<<endl;  

仅以十六进制显示C的大小(14 in hex == 20 in decimal)。这是因为您之前使用hex I / O manippulator打印地址。

cout<<dec<<sizeof(C)<<endl;

会再次将I / O操纵器设置为十进制模式,并按预期输出20


关于printf和类型安全的说法

printf不是类型安全的。当使用printf时,用户有责任将适当的formart描述符和数据类型传递给它。如果存在不匹配,则会发生未定义的行为。未定义的行为意味着程序可能崩溃或显示任何奇怪的行为。

  

printf(&#34;%p \ n&#34;,g2);

是未定义行为的示例,格式描述符和数据类型不匹配。请注意,编译器会抱怨这一点,您应该始终注意并检查编译器发出的此类警告。

  

警告:格式'%p'需要类型'void *',但参数2的类型为'void(C :: *)()'

答案 1 :(得分:0)

给定类型的sizeof结果永远不会改变。 (至少对于 符合C ++程序。我认为,g ++支持C ++中的VLA 扩展,sizeof包含VLA的对象可能会发生变化。) 关于你的明确问题:

printf( "%p\n", g2 );

是未定义的行为。您正在将指向成员的指针传递给输出 格式化程序需要void*。 (g ++会对此发出警告,我 相信,至少有某些选择。)你可能会得到一些 任何事情(包括程序崩溃)。指向成员的指针 void*,无法转换为void*

cout << g2;

我无法相信这会编译。

cout << sizeof(g2) << endl;

sizeof(g2)返回8,因为这是指向成员的指针的大小 在你的系统上。

cout << sizeof(C) << endl;

打印14,因为这是类型对象的十六进制大小 您系统上的C。换句话说,sizeof(C)是20.你已经 设置hex的输出,并且从不重置它,输出是十六进制的。