关于使用返回的引用

时间:2014-08-19 12:52:47

标签: c++ reference

我在尝试理解C ++中返回引用的正确用法时遇到了一些麻烦。 我有一个内部有“大”对象的课程。我希望能够通过返回一个const引用来在类“只读”模式之外使用这个对象。

问题是我不太明白何时复制对象以及何时不复制对象。

关于返回引用的大部分问题,关于返回在堆栈上分配的对象,这不是我特别的问题,所以我准备了这个小例子:

class foo {
  int a;

public:
  foo() {
    a = 3;
  }

  int& getInt() {
    return a;
  }

  const int& useInt() {
    return a;
  }

  void print() {
    cout << "Inside class: a = " << a << endl;
  }
};

int main() {
  foo foo1;

  int& goodRef = foo1.getInt();
  int badRef = foo1.getInt();

  goodRef = 4;
  badRef = 5;

  foo1.print();

  foo1.getInt() = 6;
  foo1.print();

  int usingIt = 10*foo1.useInt();
}

我的理解是:

  • int& goodRef = foo1.getInt();中没有复制任何内容,只有 a 所拥有的类。
  • int badRef = foo1.getInt();中,badRef是a的副本,因此有2个单独的对象, a badRef

因此,根据什么类型的对象捕获它被复制的返回值,或者不是,所以我的问题是:

当我使用int usingIt = 10*foo1.useInt();中的引用时,它是否被复制,然后用于乘法或仅使用类中的值?

在这个例子中没关系,因为它只是一个int,但如果它是一个大对象,那将是一件大事。

谢谢!

编辑:感谢所有的答案,但是我觉得在课堂上有这样的方法很糟糕,我只是为了这个例子而放了它们。

我的实际类里面有一堆对象和一个接口和bla bla,但是一个特定的对象是glm :: mat4。我想要的是能够写出像glm::vec4 finalVec = foo1.getMatrix() * vec这样的东西。但我不希望整个矩阵被复制然后相乘,而是我想使用已经在我的类中的矩阵来执行乘法,同时不让用户修改它。我认为类似useInt的东西,但mat4会起作用,但我不确定,这就是我问这个问题的原因。

glm specificatioon对我来说非常混乱,但我认为运营商*被描述为:

glm::mat4 operator* (glm::mat4 const & m, glm::vec4 const & v);

3 个答案:

答案 0 :(得分:2)

在您的示例int usingIt = 10*foo1.useInt();中,operator*(),取决于它的参数签名和内部,可能会导致您的对象的副本发生,此时它将被分配(而不是复制)再次)到usingIt的值。如果您的对象是聚合或类对象类型,则通常使用编译器优化步骤来省略使用对象类型的赋值运算符的副本。

通常,只要您将l值引用类型(即T&const T&)复制到聚合或类对象到非引用类型(即,键入{{1 }},在返回的对象引用上调用复制构造函数,构造函数,赋值运算符或转换运算符。

答案 1 :(得分:0)

使用const引用时,只能使用此对象的const方法。例如。当你有STL矢量时你可以获得大小,但你不能将push_back元素添加到它。

vector<int> a;
vector<int> &c = a;
const vector<int> &b = a;
a.size();
b.size();
a.push_back(4);
c.push_back(4);
//our vector is now 4 4
//b.push_back(4); compilation error

在C ++中,您要复制时要复制:例如
复制功能: int x(vector<int> b)
不复制的功能: int x(vector<int> &b)
You can read more here

答案 2 :(得分:0)

如果getInt返回int&,为什么要在int中捕获返回值?您期望编译器更改源代码以使用对int的引用?除了复制引用所指向的对象的值之外,它不能做任何其他事情。

另一方面,我认为你有一个坏榜样。您可以定义一个返回const引用的方法:

int const & getInt() { return a; }

或者你提供了两个方法,一个是const,一个是非const:

int& getInt() { return a; }

int const & getInt() const { return a; }

同时拥有getIntuseInt并不会阻止任何人使用getInt并实际以非预期的方式更改对象的值。