修改
虽然格式错误但这个问题有一个很好的问题。所以,我正在编辑这个以保留这个更好的格式,以便将来访问这个问题的访问者。
在下面的代码示例中,有人可以解释为什么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
以下是我的问题:
为什么g ++或visual C ++中的输出1
在这里?
cout&lt;&lt; G2;
为什么sizeof
返回8
?请解释一下。
cout&lt;&lt; sizeof(g2)&lt;&lt; ENDL;
为什么sizeof(C)
在Visual C ++中打印14
而不是20
?如果是,为什么会这样呢?
cout&lt;&lt; sizeof(C)&lt;&lt; ENDL;
答案 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
的输出,并且从不重置它,输出是十六进制的。