Hi All,
I'm trying to figure out how to pass an object to a function by constant reference. If I write a single class, can I write a function in this class that accepts an object of this class by constant reference? If so (or in any case) how does one write a function to accept an object by constant reference? Apologies if this seems muddled, I'm having difficulty getting my head around it and I can't find examples anywhere.
Here's an attempt I made. It's a class Machine which has three stated and I want to write a function which increments the integer state of a Machine object using "pass by constant reference".

#include<iostream>
#include<string>

using namespace std;

class Machine
{
      
public:

    string owner;
    string make;
    int rackID;

    Machine();

    virtual void displayMachineDetails();
    virtual void increment();
};

void Machine::displayMachineDetails()
{
    cout <<"\nMachine owner: " << owner << "\nMake:         " << make
                              << "\nRack ID:      " << rackID << endl;
}

//This is the function to which I want to pass an object by constant reference
void increment(const Machine &aMachine, int amount = 1)  {                                                        
  rackID = rackID - amount;                              
}                                                        

int main()
{
  Machine a = Machine("Me", "IBM", 1);
  a.increment();
}

Dani AI

Generated

Clarification and a compact corrected pattern for the Machine example.

The main problem in the original snippet is attempting to change a Machine through a const reference: a parameter declared const Machine& is read-only, so any assignment to its members is a compile-time error. There are also a couple of structural issues: the call to a 3-argument constructor while only a default constructor was declared, and a mixing of a member increment declaration with a separate free-function of the same name.

A clear, safe pattern is to encapsulate state, give a matching constructor, mark read-only operations const, and choose one of two idioms depending on intent:

  • If the object should change itself, make it a member that modifies its own state.
  • If a free function should modify an argument, accept a non-const reference or pointer.
  • If a function only needs to observe an object, accept a const reference to avoid copies.

Example (new, minimal illustration):

class Machine {
private:
    std::string owner_;
    std::string make_;
    int rackID_;

public:
    Machine(const std::string& owner, const std::string& make, int rackID)
        : owner_(owner), make_(make), rackID_(rackID) {}

    int getRackID() const { return rackID_; }
    void setRackID(int id) { rackID_ = id; }

    // member modifies its own state
    void increment(int amount = 1) { rackID_ += amount; }

    // read-only
    void display() const;
};

Free-function variants:

void increment(Machine& m, int amount = 1) { m.setRackID(m.getRackID() + amount); }
void printMachine(const Machine& m) { m.display(); } // pass-by-const-ref: no copy, no modification

Notes tied to the thread: is correct that a const reference cannot be used to change the object; 's remark about using the object’s this pointer applies when the method should alter its own state; ’s example shows the canonical use of const Machine& for read-only access. Additional hygiene: make data members private, mark accessors const, provide matching constructors, and avoid defining both a member and a contradictory free function with the same role.

Recommended Answers

All 3 Replies

you can do that, no issues but your example is not the best one. If its the same object you might as well use the 'this' pointer. You can try looking at some standard copy constructor declarations. probably the most basic and important use of a const object reference.

void increment(const Machine &aMachine, int amount = 1)  
{                                                        
  rackID = rackID - amount;                              
}

1. You are passing aMachine as constant reference and you are trying to change a member of aMachine. This is illegal, since it's constant. You could pass a reference: Machine &aMachine

2. void increment should not belong to the class (in order to do what you want)

From looking at you code I don't think you are clear on (a) the objective
(b) how to use const references. So I am going to re-write a bit
to do something (Unlikely to be what you want) but hopefully that will separate between (a) and (b).

Let us start with machine.

It has a method increment, Let us say that add a value to to rackID.
That doesn't need to take ANOTHER machine object.

Then we are going to write a method add that takes another machine object and adds their rackIDs together.

Here is the class definition:

class Machine
{    
public:
    std::string owner;
    std::string make;
    int rackID;

    Machine() : rackID(0) {}
    virtual ~Machine() {}
    virtual void displayMachineDetails();
    void increment(const int =1);
    void add(const Machine&);
};

Now let me write increment, basic stuff

void
Machine::increment(const int Index)
{
   rackID+=Index;
}

void
Machine::add(const Machine& A)
{
   rackID+=A.rackID;
   return;
}

Note in add, we add TWO Machine objects and the SECOND object does not change. I reference the second object without changing it. Since A is also and object then you can access A's private members. This would not be the case for say void Machine::Test(const Other& X) .


I use a reference because (a) a copy would be expensive (b) you have not provided a copy constructor and that can lead to problems, and you have a string object, so it will.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.