【问题标题】:I am confused about "reference" between java and c++ [duplicate]我对java和c ++之间的“参考”感到困惑[重复]
【发布时间】:2019-07-09 08:24:28
【问题描述】:

我一直在使用 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是一样的?? 如果不一样,每次我要返回vector,是不是一直复制到调用区?

【问题讨论】:

  • 在你的 c++ 代码中,aaa 不是同一个对象。而且,是的,每次您调用func() 时,您都会执行一次复制。
  • aaa 以及不同的对象。 C++ func() 返回构成对象的数据,而不是对象的引用或指针。
  • 当前已移动(未应用复制省略时)。
  • 在移动机制之前,C++ 会将数据从你的函数复制到一个新的向量中。在现代 C++ 中,您可以移动该内存或依赖编译器提供的一些优化。您可能想检查 RVO 机制:ibm.com/developerworks/community/blogs/…
  • 如您所见,“参考”一词在两种语言中具有不同的含义。请注意,您的 C++ 代码根本不使用任何引用(至少不是为 C++ 定义的,其中返回值必须是 vector&lt;int&gt;&amp;)。 Java 术语“引用”可以更多地被认为是 C++ 措辞中的一个指针(不完全但足够接近)。

标签: java c++


【解决方案1】:

在 C++ 中,过去每次调用 func 时都会将 a 复制到 aa 中。但是对于现代 C++ 和 Copy elision,对象要么是给定内存 (aa) 中的直接构造函数,要么是 a 被构造然后移动。

【讨论】:

    【解决方案2】:

    Java 中的引用在某些方面更像 C++ 中的指针。下面的 C++ sn-p 会更接近 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 最终包含12,因为我们将a 的引用传递给修改它的函数。这类似于您如何将引用传递给函数以修改 Java 中的对象。但是,如果您删除addToVector 签名中的&amp;,那么a 最终将只包含1,因为传递给addToVector 的只是在函数末尾丢弃的副本.

    而不是传递向量(将被复制,至少其中一些,因为实际内容可以移动),向量现在在堆上并且只传递指针。这就像在 Java 中返回引用的副本而不是实际对象的副本。

    【讨论】:

    • 请不要向新手推荐pointers+new。我建议创建该函数,以便它修改给定的向量,如void func(std::vector&lt;int&gt;&amp;)。这也有助于理解引用,因为在 java 中这是行不通的。
    • @nada 好主意。我希望现在很清楚带有指针的代码仅用于演示目的,并添加了一个示例来展示 C++ 中的引用(以及它与传递复制的区别)。
    【解决方案3】:

    对于初学者来说,这个 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,尽管它“继承”了它的数据。

    【讨论】:

      猜你喜欢
      • 2023-03-08
      • 1970-01-01
      • 2016-06-22
      • 2013-07-28
      • 2018-08-15
      • 1970-01-01
      • 2015-02-11
      • 1970-01-01
      • 2019-07-11
      相关资源
      最近更新 更多