简体   繁体   中英

How to pass a reference in a constructor in C++?

I need a class A containing a class B. I need to change a value from class A from class B, so I need to pass a reference to B constructor. That's what I'm doing now:

class A
{
    B b;
    float value = 50;

    A()
    {
        b = B(value);
    }
}


class B
{
    float& value;
    float otherValue = 50; // I've declared this variable because the default constructor needs a value for the reference, but I don't really want this variable.

    B() : value(otherValue){};
    
    B(float _value) : value(_value){};   
}

I get the error: "A &A::operator =(const A &): attempting to reference a deleted function". I know it's because of B b; , but I need to declare b as an attribute of A. What's the correct way of doing this?

Thank you

This code works, but I did have to change the float& member in B to a float . Do you actually need to hold a reference to a float? There are a lot of ways that can go wrong.

#include <iostream>

class B {
  float value = 50;

 public:
  B() = default;
  B(float _value) : value(_value){};
  float getVal() const { return value; }
};

class A {
  B b;

 public:
  A() = default;
  float getBVal() const { return b.getVal(); }
};

int main() {
  A a;
  std::cout << a.getBVal() << '\n';
}

Output:

50

As mentioned, B could hold a pointer to a float instead of a reference.

class B {
  float* value = new float(50);

 public:
  B() = default;
  B(float _value) : value(new float(_value)){};
  ~B() {
    delete value;
    value = nullptr;
  }

  float getVal() const { return *value; }
};

You would also need (at a minimum) a copy constructor and assignment operator overload in B .

You can set the reference in the member initializer list of A constructors eg the following will print 51, modifying A's value via a B.

class B
{
    float& value;

    public:
        B(float& v) : value(v) {};

        void modify_value() {
            value++;
        }
};

class A
{
    B b;
    float value;

    public:
        A() : value(50), b(value)
        {}

        void modify_value() {
            b.modify_value();
        }

        float get_value() const {
            return value;
        }
};

int main()
{
    A a;
    a.modify_value();
    std::cout << a.get_value() << "\n";
}

Currently you default construct b , then try to assign it. You get one chance to initialise the reference in b , so do it the member initialiser.

You also need to define B before A

It's also a good idea to declare value in A before b , so that it is initialised when you pass it to B 's constructor. It isn't a problem with your code, but if you look at it's value in B::B that would be undefined behaviour

class B
{
    float& value;
public:    
    B(float& _value) : value(_value){}
};

class A
{
    float value = 50;
    B b;
public:    
    A() : b(value) {} 
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM