我一直在使用Java 但是最近我不得不切换到C ++,我对一些不同的东西感到困惑。 我的问题是 在Java中,
class Ex
{
public static void main(String[]args){
Ex e = func();
}
static Ex func(){
Ex ee = new Ex();
ee.x = 1;
ee.y = 2;
return ee;
}
}
class Ex
{
int x;
int y;
}
e和ee相同。
但是在c ++中,
vector<int> func()
{
vector<int>a;
a.push_back(1);
a.push_back(2);
return a;
}
int main()
{
vector<int>aa = func();
}
在这种情况下,a和aa相同? 如果不一样,每次我想返回引导向量时,是否总是将其复制到调用区域?
答案 0 :(得分:1)
在某些方面,Java中的引用更像C ++中的指针。以下C ++代码段更接近Java代码,尽管我不建议您以这种方式编写程序:
vector<int>* func()
{
vector<int> *a = new vector<int>;
std::cout << "Address of a: " << a << std::endl;
a->push_back(1);
a->push_back(2);
return a;
}
int main()
{
vector<int> *aa = func();
std::cout << "Address of aa: " << aa << std::endl;
delete aa;
}
结果:
Address of a: 01173338
Address of aa: 01173338
要想更好地了解引用在C ++中的工作方式,请考虑以下代码:
void addToVector(vector<int>& a) {
a.push_back(2);
}
int main()
{
vector<int> a;
a.push_back(1);
addToVector(a);
std::cout << "Content of a: ";
for (int& i : a)
std::cout << i << " ";
std::cout << endl;
}
在这里,a
最终同时包含1
和2
,因为我们将a
的引用传递给修改它的函数。这类似于如何将引用传递给函数以修改Java中的对象。但是,如果您删除&
签名中的addToVector
,则a
最终将只包含1
,因为传递给addToVector
的内容只是一个该函数结尾处丢弃的副本。
现在不再在向量周围传递矢量(至少将复制其中的一部分,因为可以移动实际内容),现在向量在堆上并且仅传递了指针。就像在Java中那样,将返回引用的副本而不是实际对象的副本。
答案 1 :(得分:1)
在C ++中,过去通常是每次调用a
时将aa
复制到func
中。但是对于现代C ++和Copy elision,对象要么是给定内存(aa
中的直接构造函数,要么a
被构造然后移动。
答案 2 :(得分:0)
对于初学者来说,此Java代码
class Ex
{
public static void main(String[]args){
Ex e = func();
}
static Ex func(){
Ex ee = new Ex();
ee.x = 1;
ee.y = 2;
return ee;
}
}
class Ex
{
int x;
int y;
}
不正确。类Ex
被定义两次。
关于C ++代码
vector<int> func()
{
vector<int>a;
a.push_back(1);
a.push_back(2);
return a;
}
int main()
{
vector<int>aa = func();
}
然后,在退出函数func
后,其本地向量a
将不活动。 main中的向量可以获得与元素中的向量相同的内存范围。
但是main中的向量尽管“继承”了其数据,但并未引用该函数中的变量a。