如何解决问题理解参考文献和c ++中的副本
| 首先,对于问题标题中使用的术语不正确,我深表歉意。这完全有可能。我开始学习c ++,我会承认我在参考和副本方面遇到了非常困难的时期。参考下面的代码,我有以下问题: 在main.c中,参数是否传递给Carrier.add()函数(* it),引用或我放入向量中的计划对象的副本,或其他? 当将此参数添加到承运人的计划向量(在承运人类内部)时,是否添加了副本?自从我没有提供复制构造函数或告诉它进行复制以来,该如何工作?我认为它是自动生成的? 如果过于笼统,请忽略此选项。我想我的主要问题是我想/需要了解它是如何工作的,而这正是试图自己找出问题答案的问题所在。有没有一种方法可以使Visual Studio以与编译器相同的方式在我的实际代码中生成构造函数,因此我可以在调试模式下逐步检查它们,以查看其工作方式。现在,当我调试时,很难告诉我是否调用了编译器生成的副本构造函数(如果确实发生了这种情况)。 这是我的代码: main.c#include \"stdafx.h\"
#include <iostream>
#include \"Plan.h\"
#include \"Carrier.h\"
int _tmain(int argc,_TCHAR* argv[])
{
std::vector<Plan> plans;
for (int i = 0; i < 4; ++i) {
Plan p(i);
plans.push_back(p);
}
Carrier c(5);
for(std::vector<Plan>::iterator it = plans.begin(); it != plans.end(); ++it) {
//my question is about the line directly below this comment
c.add(*it);
}
return 0;
}
计划
#pragma once
class Plan
{
private:
int id;
public:
Plan(int id);
};
计划文件
#include \"Plan.h\"
Plan::Plan(int i)
{
id = i;
}
载体
#pragma once
#include <vector>
class Plan;
class Carrier
{
private:
int id;
std::vector<Plan> plans;
public:
Carrier(int i);
void add(Plan p);
};
Carrier.cpp
#include \"Carrier.h\"
#include \"Plan.h\"
Carrier::Carrier(int i) {
id = i;
}
void Carrier::add(Plan p) {
plans.push_back(p);
}
解决方法
(1)由于
Carrier::add
并不通过引用来接受其自变量,因此将其传递给副本。要使其具有参考性,请将其签名更改为
void Carrier::add(Plan const &p);
(2)当您执行“ 7”时,无论您通过引用还是通过值/副本传递“ 8”,都将创建一个副本;这是“ 9”(以及所有其他标准容器)语义的一部分。复制构造函数由编译器自动生成。
(3)我不是VC ++用户,但是编译器将生成的副本构造函数等效于
Plan::Plan(Plan const &other)
: id(other.id) // there\'s only one member,// but other members would be treated the same
{}
在空主体中,您可以添加一条打印语句,该语句指示调用了副本构造函数,但这并不是防水的。在某些情况下,允许C ++执行复制省略优化,这意味着跳过了实际复制。
,在回答第一个问题时,该Plan对象是按值传递的,因此它是传递给该函数的对象的副本。
如果需要参考,则需要创建如下函数:
void Carrier::add(Plan const & p)
您正在此处传递const对象Plan,因为您没有在函数中对其进行任何更改。在C ++中,这被认为是一种好习惯,如果您不打算对参数进行更改,而要通过引用或指针将其传递给该参数,请将其设置为12。
为了回答您的第二个问题,在这种情况下,容器(std :: vector)被传递了一个副本。
, 在main.c中,参数是否传递给Carrier.add()函数(* it),引用或我放入向量中的计划对象的副本,或其他?
这是副本,因为您已将add()
声明为void add(Plan p);
。如果要传递参考,则应将其声明为“ 15”。
当将此参数添加到承运人的计划向量(在承运人类内部)时,是否添加了副本?自从我没有提供复制构造函数或告诉它进行复制以来,该如何工作?我认为它是自动生成的?
是。编译器会为您生成它。有关更多详细信息,请参见此处。
有没有一种方法可以使Visual Studio以与编译器相同的方式在我的实际代码中生成构造函数,因此我可以在调试模式下逐步检查它们,以查看其工作方式。
据我所知,您不能将其指定为Visual Studio中的设置,以包括自动生成的副本构造函数的代码。
,1-*it
正在取消引用plans
向量的元素,并将它们按值传递给c.add
。因此,没错,在变量p
(ѭ21is方法的参数)中临时构造plans
向量的每个元素的副本,然后将其添加到Carrier
类的plans
向量中。
2-是的,添加了副本。不提供复制构造函数时的默认行为是复制要复制的对象的每个属性。您可以通过提供副本构造函数来修改此行为。
3-不难理解,编译器生成的复制构造函数是如何工作的。只需假设将传递的对象的每个属性都复制到要调用其副本构造函数的对象即可。
,为了理解pass-by-value
和pass-by-reference
,您需要知道什么是参考文献。 same26ѭ就像aliases
到相同的存储位置。
尽管下面的代码与您的问题无关,但我还是故意举了一个简单的示例来说明正在发生的事情。
#include<iostream>
void foo(int,int & ); //Declaration of foo
void foo(int copy,int &reference)
{
copy++; // Updates the Local Variable Copy
reference++; // Updates x
}
int main(){
int x=10;
int &reftox=x; // reference to x
foo(x,reftox);
std::cout << x;
}
输出为11
。与您的问题有关的其余疑问已得到解答。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。