-2

A brother suggested me that I pass the arguments in the constructor and other member functions of the class by reference instead and even return references from member functions, so that it avoids copying of variables all the time. I'm a very naive programmer and don't know how best to do it. Can you please tell me how to apply it to the following program:

#include <iostream>
#include <string>

using namespace std;

class Student {
    public:
        Student(string s, int i) {
            name = s;
            id = i;
        }
        void setName(string s) {
            name = s;
        }
        void setId(int i) {
            id = i;
        }
        string getName() {
            return name;
        }
        int returnId() {
            return id;
        }
    private:
        string name;
        int id;
};

int main() {
    Student s1("Seth",515);
}

This is what I did:

#include <iostream>
#include <string>

using namespace std;

class Student {
    public:
        Student(string& s, int& i) {
            name = s;
            id = i;
        }
        void setName(string& s) {
            name = s;
        }
        void setId(int& i) {
            id = i;
        }
        string& getName() {
            return name;
        }
        int& returnId() {
            return id;
        }
    private:
        string name;
        int id;
};

int main() {
    string s = "John";
    int i = 515;
    Student s1(s,i);
    return 0;
}

Is it alright to return reference variables, I mean don't they go out of scope in some cases?

abcde
  • 505
  • 1
  • 5
  • 8
  • 1
    In your example, all should be fine. The compiler will optimise away the copies – tofi9 Feb 10 '15 at 20:25
  • 2
    And try to read about c++ and copy constructors. Stack overflow members don't like lazy people :) – tofi9 Feb 10 '15 at 20:26
  • I already read about constructors and spend a lot of time on copy constructors as well. What do you mean by compiler optimization? – abcde Feb 10 '15 at 20:27
  • 2
    references to trivial types such as `int` are useless - it is just copy to a register - get from register. Also, consider to implement _move semantics_ for `s` – myaut Feb 10 '15 at 20:29
  • Please look at my edit. Is it worthwhile implementing it that way, or does it not even matter to the compiler? – abcde Feb 10 '15 at 20:29
  • @myaut: What do you mean by move semantics? Can you show me how to do it? Also, by useless, do you mean the memory consumption is negligible or does the compiler ignore it? – abcde Feb 10 '15 at 20:31
  • 1
    @AnonymousAndy, Move semantics: [SO question](http://stackoverflow.com/questions/3106110/what-is-move-semantics) – FreeNickname Feb 10 '15 at 20:46
  • 1
    It is true that passing parameters by (`const`) reference (or rvalue reference) is often more efficient than passing by value. But in the code you posted, you're often making copies of the passed-in data in which case it's probably a good idea to pass by value ( http://stlab.adobe.com/wiki/images/8/85/2008_06_26_classes_that_work.pdf ). – Max Lybbert Feb 10 '15 at 20:49

1 Answers1

1

I'm agree with Alexander completely: first, in your program it won't probably give you anything. Second, premature optimization is the root of all evil.

Still, if you're interested, in general passing a value by reference usually looks like this:

void myFunction(const MyComplicatedClass& argument) {...}

Here argument is passed as a reference to a constant object. This means that:

  1. Instead of passing a value to the function, we pass a reference, so our function, when it accesses argument, will, in essence, work with the same region of memory as the function, that called myFunction. BUT if it works with the same region of memory, it can mess it up. So
  2. We pass a reference to a constant object. It means, that the compiler will ensure, that we don't do anything, that can mess up the original object (which was passed to us asargument). It's not a 100% guarantee, we are talking about C++, it's relatively easy to shoot in the foot here, but the compiler will try his best :)

But it's important to understand, that there is no point in using this approach everywhere. For instance, there is no point in passing int value as a const reference, since it is a primitive type already. You might even make things less efficient. Many classes are implemented in a way, that makes copying a very cheap operation. And, finally, compilers nowadays are very smart. They can optimize out many things that you didn't think of.

Still, I don't say that this is useless. As with every tool, you should understand, how it works and when to use it. It comes with experience and studying.

As for returning a reference, never return a reference to local variables. They get deleted the moment they go out of scope, and your program will crash when you'll try to access a reference to a deleted content. You can, however, return references (const references) to anything, that you're sure will live long enough. For instance, class fields.

FreeNickname
  • 7,398
  • 2
  • 30
  • 60
  • Thanks a ton buddy, but when you said, "For instance, there is no point in passing int value as a const reference, since it is a primitive type already." what exactly do you mean? What do you mean by no point? Is it because the size is just 4 bytes anyway? – abcde Feb 10 '15 at 21:06
  • 1
    @AnonymousAndy, yes. A pointer (a reference is not always implemented as a pointer, but it) in 64-bit environment takes 8 bytes. The data itself takes 4. It makes no sense. – FreeNickname Feb 10 '15 at 21:30