8

I want to pass an object of Class A (call it a) by reference (in the broad sense, i.e. either by A& or by A*) to the constructor of another Class B. I do not want 'a' to be modified inside B ('a' is read only and it is big in size which is why I want to pass it by reference). I know of two options:

1) Pass 'a' as

const A & a_

2) Pass 'a' as

const A * a_

The disadvantage of option 1 is that I can mistakenly pass an r-value. The disadvantage of option 2 is that I can mistakenly pass a null pointer.

My questions are: 1) Am I right about the disadvantages above? 2) Is there another recommended way of passing 'a' by reference?

I saw the answers in the link below. But I am curious if there are other options than what is posted in that question. Are there benefits of passing by pointer over passing by reference in C++?

Community
  • 1
  • 1
Ned_the_Dolphin
  • 154
  • 2
  • 10

3 Answers3

18

Pass by const A &.

You can prevent accidental passing of rvalues by declaring an rvalue overload of that function = delete. For example:

struct A { };

void func(const A & a) { }
void func(A && a) = delete;

int main()
{
    A a;
    func(a);   // compiles
    func(A()); // doesn't compile
}
Emil Laine
  • 41,598
  • 9
  • 101
  • 157
  • 1
    There is one tricky issue that I bumped into when dealing with this: if you really want to disable *all* rvalues, it's better to use `void func(const A&&) = delete;` instead. Looks weird and dirty, but it does the job. That's because otherwise legacy code that returns by `const` value (not recommended, but unfortunately frequently used in factory-like functions) will bind to `func(const &);` instead. Related: http://stackoverflow.com/q/33244951/3093378 – vsoftco Oct 31 '15 at 17:07
4

Take a look at std::reference_wrapper's constructors: http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper/reference_wrapper

It has an extra deleted constructor that takes rvalue reference, so if you try to pass an rvalue to it, that constructor wins overload resolution and you get an error.

You can do the same thing: declare both const A& and A&& constructors, and delete the latter. Then nobody will be able to pass in an rvalue.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312
-3

The code:

#include <iostream>
using namespace std;

struct A
{ };

int func_one(A& var) {
    A * insertVal=new A;
    if (&var==nullptr)
        return 0;
    else
        return 1;
}

int main() {
    A refVar;
    int x;
    x=func_one(refVar);

    return 1;
}