2011-10-05 36 views
-4

编辑:
虽然格式错误这个问题有一个很好的catch.So,我编辑这在谁碰到这个问题绊倒以后的访问者更好的格式保留此。向量变更类的大小


在下面的代码示例可有人请解释为什么不同阶级的大小比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. 为什么输出1这里用g ++或Visual C++?

    cout < < g2;

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

    COUT < <的sizeof(G2)< < ENDL;

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

    COUT < <的sizeof(C)< < ENDL;

+0

请注意,如果memcpy代码被注释了,sizeof(C)将打印20,如果它未被注释,则打印14 ..请解释 –

+3

并至少提供一个问题... – RvdK

+4

请编辑您的问题,一些文本,解释问题是什么,输出是什么等等。解析这段长长的代码来阅读注释并不是很好。 – Mat

回答

3

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

cout <<sizeof(g2)<<endl; 

返回8因为g2就在你enviornment的指针的指针和尺寸8.


为什么是输出1这里以g ++或Visual C++?

cout << g2; 

<< operator不具有重载的版本,其接受的指针。所以指针被转换为一个bool类型,值为1,然后cout将其打印出来。

C++标准允许这样的:

C++ 03标准4.12布尔转换

1算术,枚举,指针,或指向构件类型的右值可以被转换为一个bool类型的右值。


为什么sizeof(C)打印14和不20在Visual C++。

cout<<sizeof(C)<<endl; 

它显示的C正确只是以十六进制(14 in hex == 20 in decimal)的大小。这是因为您之前使用了hex I/O管理器来打印地址。

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

将重新设置I/O操作机械手小数模式,它将输出20如您所愿。


字约printf和类型安全:

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

printf(“%p \ n”,g2);

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

警告:格式 '%P' 预计类型 'void *的',但参数2具有输入 '无效(C :: *)()'

+0

对于正常的函数指针,sizeof给出4 –

+0

@RishiMehta,因为函数指针不是常规指针。在你的平台上,它们恰好是4个字节。 –

+0

@Als很好的发现了布尔转换。我错过了。 –

0

sizeof结果对于给定类型从不改变。 (至少在一个 标准的C++程序G ++,我相信,支持沃拉斯在C++中,作为 扩展和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设置了输出 ,并且永远不会重置它,所以输出是十六进制。