复制建设 [英] copy construction

查看:62
本文介绍了复制建设的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在关于C ++中的复制构造的章节中代码中的
(见下文),作者说如果你按值传递对象

,如HowMany h2 = f(h); ....然后创建一个按位对象w / o
调用类的构造函数。然而他说当我们离开

函数范围HowMany f(HowMany x)然后调用析构函数。

为什么这个不一致?根据我的意见,即使是析构函数也应该*不*

。我可以理解,有点明智的复制意味着一个''C''就像只需将参数推入堆栈的方法一样。当fn''f''是
结束时,它应该只是意味着堆栈(由

值生成的本地对象)弹出而不调用它detructor。


i希望我不要问一个愚蠢的qn。但我很困惑这个根本。


----------------- *继承人代码* --------- ---------------------


class HowMany {

static int objectCount;

public:

HowMany(){objectCount ++; }

static void print(const string& msg =""){

if(msg.size()!= 0)out<< msg<< ":";

out<< " objectCount ="

<< objectCount<<结束;

}

~HowMany(){

objectCount--;

print(&〜; HowMany ()");

}

};

int HowMany :: objectCount = 0;


//传递和返回BY VALUE:

HowMany f(HowMany x){

x.print(&x; f()中的参数);

返回x;

}


int main(){

HowMany h;

HowMany :: print(构造h之后);

HowMany h2 = f(h);

HowMany :: print(" ;在调用f()之后;

} ///:〜

解决方案

trying_to_learn写道:< blockquote class =post_quotes>我在代码中的C ++副本构建章节(见下文),作者说如果你按值传递对象
,如HowMany h2 = f( H); ....然后创建一个按位对象,用于调用类的构造函数。然而他说当我们离开函数范围HowMany f(HowMany x)然后调用析构函数。
为什么会出现这种不一致?根据我的意见,即使是析构函数也应该*不被*调用。我可以理解,有点明智的复制意味着一个''C''就像简单地将参数推入堆栈的方法一样。当fn''f''结束时,它应该只是意味着堆栈(由
值构成的本地对象)弹出而不调用它的析构函数。

----------------- *继承人的代码* ------------- -----------------

类HowMany {
static int objectCount;
public:
HowMany(){ objectCount ++; }
static void print(const string& msg =""){
if(msg.size()!= 0)out<< msg<< ":" ;;
out<< " objectCount ="
<< objectCount<< endl;
}
~HowMany(){
objectCount--;
print(&#; HowMany()");
}
} ;
int HowMany :: objectCount = 0;

//传递并返回BY VALUE:
HowMany f(HowMany x){
x.print("在f()")内的x参数;
返回x;
}
int main(){
HowMany h;
HowMany :: print (构造h之后);
HowMany h2 = f(h);
HowMany :: print(调用f()之后);
} // /:〜



原因是,因为你没有用户定义的副本

类的构造函数,编译器为你生成了一个(

当然你看不到任何被调用的迹象)。当h通过

值时,会调用自动增强的复制构造函数,它在

中的行为只是执行按位复制,虽然它看不到

被调用。所以实际上对称性仍然存在,副本

构造函数对你来说是不可见的。


trying_to_learn写道:

我正在阅读C ++中关于复制构造的章节。在代码中(见下文),作者说[那],如果我按照HowMany h2 = f(h)中的值传递对象,那么就会创建一个不带调用的按位对象类的构造函数。
然而,他说[当] [执行的线程]
留下函数f的范围(HowMany),然后调用析构函数。


将h的副本复制为按值传递。

为什么会出现这种不一致的情况?根据我的说法,即使是析构函数也不应该被调用。我可以理解,有点明智的复制意味着一个''C''就像简单地将参数推入堆栈的方法一样。

根据我的说法,当f(HowMany)返回时,它应该简单意味着堆栈
(由值生成的本地对象)弹出而不调用其析构函数。


实际上,你的C / C ++编译器会自动发出代码来执行此操作。

但它会调用你的析构函数。 清理首先。

例如,如果你的构造函数调用new来为你的一个对象中的

指针数据成员分配内存,

你的析构函数应调用delete来释放该内存

*之前*该对象是从堆栈中弹出。

我希望[我]不要问一个愚蠢的问题
但我对这个根本感到困惑。
----------------- *继承人代码* ------------------------ ------

cat main.cc
#include< iostream>


class HowMany {

private:

static int objectCount;

public:

static void print(const std :: string& msg ="") {

if(0!= msg.size())

std :: clog<< msg<< ":";

std :: clog<< " objectCount =" << objectCount<< std :: endl;

}

HowMany(void){

++ objectCount;

print(" ; HowMany :: HowMany(void)");

}

HowMany(const HowMany& n){

++ objectCount;

print(" HowMany :: HowMany(const HowMany&)");

}

~HowMany(void){

--objectCount;

print(" HowMany ::〜HowMany(void)");

}

};


int HowMany :: objectCount = 0;


//传递并返回BY VALUE:

HowMany f(HowMany x){

x.print(f(HowMany)中的x参数);

返回x;

}


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

HowMany h;

HowMany :: print (构建h之后);

HowMany h2 = f(h);

HowMany :: print(调用f()之后) ;

返回0;

}

g ++ -Wall -ansi -pedantic -o main main.cc
./main



HowMany :: HowMany(void):objectCount = 1
构建h后的
:objectCount = 1

HowMany :: HowMany(const HowMany&): objectCount = 2

x里面的参数f(HowMany):objectCount = 2

HowMany :: HowMany(const HowMany&):objectCount = 3

HowMany ::〜HowMany(void):objectCount = 2

调用f()后:objectCount = 2

HowMany ::〜HowMany(void):objectCount = 1

HowMany ::〜HowMany(void):objectCount = 0




" trying_to_learn" <无**** @ no.no>在消息中写道

news:cn ********** @ gist.usc.edu ...

我在关于复制构造的章节中C ++
在代码中(见下文),作者说如果你在HowMany中通过值传递对象
h2 = f(h); ....然后创建一个按位对象,而不是调用类的构造函数。


那是垃圾。在C ++类中,在不调用

类构造函数的情况下,* never *创建。作者可能要提出的一点是,在下面的例子中,它是编译器生成的复制构造函数,它被称为
。但即使这样,作者也应该指出编译器生成的b $ b复制构造函数是*不是*按位复制而且没有像

按位对象这样的东西。


这听起来像是作为作者的Bullschildt?


如果你将自己的复制构造函数添加到HowMany,那么你会看到它
按值传递对象时调用



类HowMany {

static int objectCount;

public:

HowMany(){objectCount ++; } $ / $

//复制构造函数

HowMany(const HowMany& rhs){objectCount ++; }

然而他说当我们离开函数范围HowMany f(HowMany x)然后
析构函数被调用。
为什么这个不一致?根据我的意见,即使是析构函数也不应该被调用。我可以理解,有点明智的复制意味着像'C'这样的方法,只需将参数推入堆栈即可。当fn''f''结束时,我会看到它,它应该只是意味着在没有调用它的析构函数的情况下弹出堆栈(由值生成的本地对象)。


每次创建一个类对象时,都会调用一个构造函数(即使它是一个

编译器生成的)。每次销毁一个类对象时,都会调用析构函数

(即使它是编译器生成的)。没有这样的东西

作为一个按位对象或C ++中的按位副本。

我希望我不要问一个愚蠢的qn。但我很困惑这个根本。




不,我认为你有一个愚蠢的作者试图让简单的

变得复杂。 />

john


i am on the chapter on copy construction in C++
in the code (see below), the author says if u pass the object by value
as in HowMany h2 = f(h); ....then a bitwise object is created w/o
calling the constructor of the class. However he says when we leave
scope of function HowMany f(HowMany x) then the destructor is called.
why this inconsistency?. Accdng to me even the destructor should *not*
be called. i can understand that bit wise copy means a ''C'' like method
of simply pushing the arguments into stack. accdng to me when fn ''f'' is
over, it should simply mean that stack (local object that was made by
value)is popped out without calling its detructor.

i hope im not asking a stupid qn. but im confused abt this fundamental.

-----------------*heres the code*------------------------------

class HowMany {
static int objectCount;
public:
HowMany() { objectCount++; }
static void print(const string& msg = "") {
if(msg.size() != 0) out << msg << ": ";
out << "objectCount = "
<< objectCount << endl;
}
~HowMany() {
objectCount--;
print("~HowMany()");
}
};
int HowMany::objectCount = 0;

// Pass and return BY VALUE:
HowMany f(HowMany x) {
x.print("x argument inside f()");
return x;
}

int main() {
HowMany h;
HowMany::print("after construction of h");
HowMany h2 = f(h);
HowMany::print("after call to f()");
} ///:~

解决方案

trying_to_learn wrote:

i am on the chapter on copy construction in C++
in the code (see below), the author says if u pass the object by value
as in HowMany h2 = f(h); ....then a bitwise object is created w/o
calling the constructor of the class. However he says when we leave
scope of function HowMany f(HowMany x) then the destructor is called.
why this inconsistency?. Accdng to me even the destructor should *not*
be called. i can understand that bit wise copy means a ''C'' like method
of simply pushing the arguments into stack. accdng to me when fn ''f'' is
over, it should simply mean that stack (local object that was made by
value)is popped out without calling its detructor.

i hope im not asking a stupid qn. but im confused abt this fundamental.

-----------------*heres the code*------------------------------

class HowMany {
static int objectCount;
public:
HowMany() { objectCount++; }
static void print(const string& msg = "") {
if(msg.size() != 0) out << msg << ": ";
out << "objectCount = "
<< objectCount << endl;
}
~HowMany() {
objectCount--;
print("~HowMany()");
}
};
int HowMany::objectCount = 0;

// Pass and return BY VALUE:
HowMany f(HowMany x) {
x.print("x argument inside f()");
return x;
}

int main() {
HowMany h;
HowMany::print("after construction of h");
HowMany h2 = f(h);
HowMany::print("after call to f()");
} ///:~


The reason is that, because you don''t have a user defined copy
constructor for class HowMany, the compiler generated one for you (of
course you cannot see any sign of it being called). When h is passed by
value, the automatically augmented copy constructor, whose behavior in
this case is simply doing bitwise copy, is called, though it cannot see
it being called. So actually the symmetry still exists, with the copy
constructor invisible to you.


trying_to_learn wrote:

I am [reading] the chapter on copy construction in C++. In the code (see below),
the author says [that], if I pass the object by value as in HowMany h2 = f(h),
then a bitwise object is created w/o calling the constructor of the class.
However, he says [that], when [the thread of execution]
leaves scope of function f(HowMany), then the destructor is called.
To make a copy of h to "pass by value".
Why this inconsistency? According to me even the destructor should *not*
be called. I can understand that bit wise copy means a ''C'' like method
of simply pushing the arguments into stack.

According to me, when f(HowMany) returns, it should simply mean that the stack
(local object that was made by value) is popped out without calling its destructor.
Actually, your C/C++ compiler emits code to do this automatically.
But it calls your "destructor" to "clean up" first.
If, for example, your constructor called new to allocate memory for a
pointer data member in one of your objects,
your destructor should call delete to deallocate that memory
*before* the object is "popped off of the stack".
I hope [that] I''m not asking a stupid question
but I''m confused about this fundamental. -----------------*heres the code*------------------------------

cat main.cc #include <iostream>

class HowMany {
private:
static int objectCount;
public:
static void print(const std::string& msg = "") {
if(0 != msg.size())
std::clog << msg << ": ";
std::clog << "objectCount = " << objectCount << std::endl;
}
HowMany(void) {
++objectCount;
print("HowMany::HowMany(void)");
}
HowMany(const HowMany& n) {
++objectCount;
print("HowMany::HowMany(const HowMany&)");
}
~HowMany(void) {
--objectCount;
print("HowMany::~HowMany(void)");
}
};

int HowMany::objectCount = 0;

// Pass and return BY VALUE:
HowMany f(HowMany x) {
x.print("x argument inside f(HowMany)");
return x;
}

int main(int argc, char* argv[]) {
HowMany h;
HowMany::print("after construction of h");
HowMany h2 = f(h);
HowMany::print("after call to f()");
return 0;
}
g++ -Wall -ansi -pedantic -o main main.cc
./main


HowMany::HowMany(void): objectCount = 1
after construction of h: objectCount = 1
HowMany::HowMany(const HowMany&): objectCount = 2
x argument inside f(HowMany): objectCount = 2
HowMany::HowMany(const HowMany&): objectCount = 3
HowMany::~HowMany(void): objectCount = 2
after call to f(): objectCount = 2
HowMany::~HowMany(void): objectCount = 1
HowMany::~HowMany(void): objectCount = 0



"trying_to_learn" <no****@no.no> wrote in message
news:cn**********@gist.usc.edu...

i am on the chapter on copy construction in C++
in the code (see below), the author says if u pass the object by value as
in HowMany h2 = f(h); ....then a bitwise object is created w/o calling
the constructor of the class.
That''s rubbish. In C++ class objects are *never* created without calling a
class constructor. Probably the point the author is trying to make is that
in the example below it is the compiler generated copy constructor that is
called. But even then the author should appeciate that a compiler generated
copy constructor is *not* a bitwise copy and there is no such thing as a
bitwise object.

This sound like Bullschildt, who is the author?

If you add your own copy constructor to HowMany, then you will see that it
is called when you pass an object by value.

class HowMany {
static int objectCount;
public:
HowMany() { objectCount++; }

// copy constructor
HowMany(const HowMany& rhs) { objectCount++; }
However he says when we leave scope of function HowMany f(HowMany x) then
the destructor is called.
why this inconsistency?. Accdng to me even the destructor should *not* be
called. i can understand that bit wise copy means a ''C'' like method of
simply pushing the arguments into stack. accdng to me when fn ''f'' is over,
it should simply mean that stack (local object that was made by value)is
popped out without calling its detructor.
Everytime a class object is created a constructor is called (even if it is a
compiler generated one). Every time a class object is destroyed a destructor
is called (even if it is a compiler generated one). There is no such thing
as a bitwise object or a bitwise copy in C++.

i hope im not asking a stupid qn. but im confused abt this fundamental.



No I think you have a stupid author who is trying to make the simple
complicated.

john


这篇关于复制建设的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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