是一个memcpy()等效于默认的复制构造函数? [英] is a memcpy() equivalent to the default copy constructor?

查看:70
本文介绍了是一个memcpy()等效于默认的复制构造函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题:


实际上,下面第36和37行通常相当于

默认复制构造函数(.e.g第33行)。我的问题是:


(a)ISO 14882是否保证第36和37行是等价的?b $ b来执行默认的复制构造函数(即第33行)?


(b)如果没有,第36-39行的行为是否由

标准定义好?


虽然我所知道的所有C ++编译器都通过

存储指向对象中vtable的指针来实现虚函数,但是标准并没有讨论关于这样的实现细节的
...


问候,

--jfc


1 #include< iostream>

2 #include< cstdlib>

3

4 class foo {

5 public:

6 int i;

7 foo():i(3){}

8 virtual void f(){std :: cout<< " FOO" <<的std :: ENDL; }

9虚拟〜富(){};

10};

11

12类bish: public foo {

13 public:

14 int j;

15 double d;

16 br / >
17 bish(int p):j(p),d(0.0){}

18 void f(){std :: cout<< " BISH" <<的std :: ENDL; }

19~bish(){};

20};

21

22 int

23 main(int argc,char * argv [])

24 {

25 char buf1 [sizeof(bish)];

26

27 bish b1(99);

28

29 //使用新位置构建。

30 bish * b2 = new((void *)buf1)bish(42);

31

32 //使用默认复制ctor复制

33 bish b3(b1);

34

35 //相当于复制结构?

36 bish * b4 =( bish *)new char [sizeof(bish)];

37 memcpy((char *)b4,(char *)& b1,sizeof(bish));

38

39 b4-> f();

40}

41

[见 http://www.gotw.ca/resources/clcm.htm for info about

[comp.lang.c ++。moderated。第一次海报:做到这一点! ]

QUESTION:

In practice, lines 36 and 37 below are usually equivalent to the
default copy constructor (.e.g line 33). My questions are:

(a) Does ISO 14882 guarantee that lines 36 and 37 are equivalent
to executing the default copy constructor (i.e. lines 33)?

(b) If not, is the behavior for lines 36-39 well defined by the
standard?

While all C++ compilers I know of implement virtual functions by
storing a pointer to a vtable in the object the standard doesn''t talk
about implementation details like this ...

Regards,
--jfc

1 #include <iostream>
2 #include <cstdlib>
3
4 class foo {
5 public:
6 int i;
7 foo(): i(3) {}
8 virtual void f() { std::cout << "foo" << std::endl; }
9 virtual ~foo() {};
10 };
11
12 class bish : public foo {
13 public:
14 int j;
15 double d;
16
17 bish(int p): j(p), d(0.0) {}
18 void f() { std::cout << "bish" << std::endl; }
19 ~bish() {};
20 };
21
22 int
23 main(int argc,char *argv[])
24 {
25 char buf1[sizeof(bish)];
26
27 bish b1(99);
28
29 // consttruct with placement new.
30 bish * b2 = new((void *)buf1) bish(42);
31
32 // copying with the default copy ctor
33 bish b3(b1);
34
35 // equivalent to copy construction?
36 bish * b4 = (bish *) new char[sizeof(bish)];
37 memcpy((char *)b4, (char *)&b1, sizeof(bish));
38
39 b4->f();
40 }
41
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

推荐答案



" jonathan cano" <福**** @ gmail.com> skrev i en meddelelse

news:11 ********************** @ o13g2000cwo.googlegr oups.com ...

"jonathan cano" <fu****@gmail.com> skrev i en meddelelse
news:11**********************@o13g2000cwo.googlegr oups.com...
问题:

实际上,下面的第36和37行通常等同于
默认的复制构造函数(.eg第33行)。我的问题是:

(a)ISO 14882是否保证第36和37行与执行默认复制构造函数(即第33行)相同?


Nope。

(b)如果没有,第36-39行的行为是否由
标准明确定义?


你可以这么说。行为是未定义的。

您似乎也有对齐问题。对于foo结构,buf1将不会正确对齐

,并且我不认为bish4需要

才能正确对齐(尽管我不完全确定)。

虽然我所知道的所有C ++编译器都通过在对象中存储指向vtable的指针来实现虚函数,但标准并没有像这样讨论实现细节。 。
正确。
问候,
- jfc
QUESTION:

In practice, lines 36 and 37 below are usually equivalent to the
default copy constructor (.e.g line 33). My questions are:

(a) Does ISO 14882 guarantee that lines 36 and 37 are equivalent
to executing the default copy constructor (i.e. lines 33)?
Nope.

(b) If not, is the behavior for lines 36-39 well defined by the
standard?
You could say so. The behaviour is "undefined".
You also seem to have a problem with alignment. buf1 will NOT be aligned
properly for a foo structure, and I do not believe that bish4 is required to
be properly aligned (although i am not completely sure here).

While all C++ compilers I know of implement virtual functions by
storing a pointer to a vtable in the object the standard doesn''t talk
about implementation details like this ... Correct.
Regards,
--jfc



[snip]


/ Peter

[见 http://www.gotw.ca /resources/clcm.htm 有关的信息]

[comp.lang.c ++。moderated。第一次海报:做到这一点! ]


[snip]

/Peter
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]





jonathan cano写道:
Hi,

jonathan cano wrote:
在实践中,行下面的36和37通常等同于
默认复制构造函数(.eg第33行)。我的问题是:

(a)ISO 14882是否保证第36和37行与执行默认复制构造函数(即第33行)相同?


不,没有这样的保证。

最有问题的是foo类中的虚函数,虽然它可能是
因为weel似乎在某些平台上工作。

(b)如果没有,那么第36-39行的行为是否由
标准定义?
In practice, lines 36 and 37 below are usually equivalent to the
default copy constructor (.e.g line 33). My questions are:

(a) Does ISO 14882 guarantee that lines 36 and 37 are equivalent
to executing the default copy constructor (i.e. lines 33)?
No, there is no such guarantee.
The most problematic are virtual functions in the foo class, although it
might as weel appear to work on some platforms.
(b) If not, is the behavior for lines 36-39 well defined by the
standard?




编号你不能记忆非POD类型。


此外,我认为不能保证新的char []会分配

正确对齐bish的内存块(代码中的b4)。

当然,对于本地char []数组没有这样的保证(

中的buf1你的代码)。


这可能是你代码中的另一个问题。不是你问的是什么

,但仍然很重要。


-

Maciej Sobczak: http://www.msobczak.com/

编程: http://www.msobczak.com/prog/


[见 http://www.gotw.ca/resources/ clcm.htm 有关的信息]

[comp.lang.c ++。moderated。第一次海报:做到这一点! ]



No. You cannot memcpy non-POD types.

Moreover, I think there is no guarantee that new char[] will allocate
the memory block that is correctly aligned for bish (b4 in your code).
Certainly, there is no such guarantee for local char[] arrays (buf1 in
your code).

This could be another problem in your code. Not what you''re asking
about, but still important.

--
Maciej Sobczak : http://www.msobczak.com/
Programming : http://www.msobczak.com/prog/

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


jonathan cano写道:
jonathan cano wrote:
问题:

实际上,下面第36和37行通常相当于
默认的复制构造函数(.eg第33行)。我的问题是:

(a)ISO 14882是否保证第36和37行与执行默认复制构造函数(即第33行)相同?

(b)如果没有,第36-39行的行为是否由
标准定义?

虽然我所知道的所有C ++编译器都通过存储指针来实现虚函数对象中的vtable,标准没有谈到这样的实现细节......

问候,
- jfc

[snip]

30 bish * b2 = new((void *)buf1)bish(42);
36 bish * b4 =(bish *)new char [sizeof(bish)];
37 memcpy((char *)b4,(char *)& b1,sizeof(bish));
QUESTION:

In practice, lines 36 and 37 below are usually equivalent to the
default copy constructor (.e.g line 33). My questions are:

(a) Does ISO 14882 guarantee that lines 36 and 37 are equivalent
to executing the default copy constructor (i.e. lines 33)?

(b) If not, is the behavior for lines 36-39 well defined by the
standard?

While all C++ compilers I know of implement virtual functions by
storing a pointer to a vtable in the object the standard doesn''t talk
about implementation details like this ...

Regards,
--jfc
[snip]
30 bish * b2 = new((void *)buf1) bish(42); 36 bish * b4 = (bish *) new char[sizeof(bish)];
37 memcpy((char *)b4, (char *)&b1, sizeof(bish));




复制构造是一个成员操作;初始化对象

,就像调用每个成员的副本构造函数一样。通常,

调用每个成员的副本构造函数。


对于某些类(POD),这可能等同于memcpy,但在

一般不是。


对于具有虚函数的类,memcpy几乎是
肯定是错的;例如:


struct A {virtual f(){cout<< " A :: F" ;; } $;

struct B:public A {virtual f(){cout<< " B :: F" ;; } bb;

A a(b); //复制ctor A :: A在这里调用。


在这种情况下,将B的某些部分记忆到A中,充其量是未定义的

行为。

-

A. Kanawati
NO ************* @ comcast.net


[见 http://www.gotw.ca/resources/clcm.htm 了解有关的信息]

[comp.lang.c ++。moderated。第一次海报:做到这一点! ]



Copy construction is a member-wise operation; the object is initialized
as if the copy constructors of each member where invoked. Typically,
the copy constructors of each member are invoked.

For certain classes (PODs), this may be equivalent to memcpy, but in
general it is not.

In the case of classes with virtual functions, memcpy is almost
certainly the wrong thing; for example:

struct A { virtual f() { cout << "A::f"; } };
struct B : public A { virtual f() { cout << "B::f"; } };

B b;
A a(b); // copy ctor A::A is called here.

In this case, memcpying some part of B into A is, at best, Undefined
Behavior.
--
A. Kanawati
NO*************@comcast.net

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


这篇关于是一个memcpy()等效于默认的复制构造函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆