3
int main(){

  Test obj1(a,b,c);

  Test obj2(d,e,f);

  &obj1=&obj2;//This line wont work saying lvalue required on left side

}

What can i do to counter this error? I want to store address of obj2 into obj1 so their member variables become same(a=d,b=e,c=f) and when i change a member variable of obj1, it changes in obj2 aswell.

bolov
  • 72,283
  • 15
  • 145
  • 224
Huzaifa Imran
  • 119
  • 2
  • 8
  • Using obj1=obj2 doesnt helps because when i change value of obj1 member variables, it doesnt changes the member variables of obj2 – Huzaifa Imran May 05 '20 at 11:04
  • 1
    What is the actual problem you want to solve? What are you trying to accomplish? Do you want to make `obj1` to be a reference of `obj2` (so `obj1` and `obj2` are *the same* object)? – Some programmer dude May 05 '20 at 11:06
  • 3
    That's about the same as writing `7500 = 4344;` – Eljay May 05 '20 at 11:06
  • 1
    What should `&obj1 = &obj2;` mean or do? – KamilCuk May 05 '20 at 11:06
  • 1
    Pointers and references concepts should be explained in any [good C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). In short, you cannot do that - `obj1` and `obj2` are now declared as two separate objects and you cannot change their type. You can however create a reference for any of those of those objects, and changes made through reference will affect original object. – Yksisarvinen May 05 '20 at 11:06
  • Yes i want to make obj1 a reference of obj2 but not at the time of declaration i.e Test& obj1=obj2; – Huzaifa Imran May 05 '20 at 11:09
  • 1
    @HuzaifaImran Not possible. Reference variable must be initialized at declaration. You can use pointer variable as the answer suggests. – Yksisarvinen May 05 '20 at 11:10
  • 1
    Then perhaps pointers. But I still wonder what the *actual* problem you try to solve might be? Perhaps there are other solutions that doesn't require pointers? I also recommend you think about ownership semantics, who owns the object `obj2`? Should you perhaps be using e.g. [`std::shared_ptr`](https://en.cppreference.com/w/cpp/memory/shared_ptr), or raw non-owning pointers? – Some programmer dude May 05 '20 at 11:13
  • 1
    Your edit leaks memory - the first Test object is allocated but never used, and cannot be freed. – interjay May 05 '20 at 12:17
  • @interjay please don't include solution in the answer. You should instead accept an answer if it solved your problem. – bolov May 05 '20 at 12:23
  • @interjay i did not write my whole program here, just a glimpse of it. In my actual program, i am using the first Test object otherwise there would be no point of not declaring the first Test object as a reference directly – Huzaifa Imran May 05 '20 at 12:55

2 Answers2

5

What you are doing is like 42 = 64. It makes no sense. If you want to store the address of an object, you can use a pointer object:

Test obj1;
Test obj2;

Test * pobj = &obj1; // pointing to obj1
pobj = &obj2; // pointing to obj2

You could also use a reference to accomplish something similar, but since you mentioned you want to be able to rebind to a different object after the declaration, pointers are a better fit for your use case.

Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93
  • "since you mentioned you want to be able to rebind to a different object after the declaration, pointers are a better fit for your use case." I mildly to strongly disagree. If you use C++ then use C++. If you need to rebind then `std::reference_wrapper` is the solution imho. – bolov May 05 '20 at 12:21
  • @bolov pointers are a part of C++. `reference_wrapper` is really a pointer wrapper. – Aykhan Hagverdili May 05 '20 at 12:22
  • "pointers are a part of C++." By that logic so is `goto` and `malloc` and `const char* str = new char[20]`. They part of the C++ syntax. But a part of C++ that shouldn't be used. C++ has higher level abstractions which should be used instead. I admit there are some use cases for raw pointers in C++ but they are so so few beyond working with C code and this is definitely not one of them. imho. – bolov May 05 '20 at 12:27
  • `reference_wrapper` is really a pointer wrapper. And `while` is really a `goto` wrapper. – bolov May 05 '20 at 12:30
  • @bolov while all of those things you mentioned can be abused, they all have their own valid use cases. Anything can be abused/misused. If you want a non-owning pointer, that's an entirely valid use case. – Aykhan Hagverdili May 05 '20 at 12:31
  • Yes, when you use raw pointers in C++ they should definitely be non-owning. But because historically pointers weren't (and tbo they still aren't to this day) used exclusively for non-owning semantics it can become confusing whether the pointer is actually non-owning or not. Add on top of that the problem of the pointer being possibly null. A `T*` can mean a plethora of things (do I need to delete it or not? can it be null?) while a reference or a `std::reference_wrapper` is a safer alternative with a more constraint clear semantics (definitely non-owning and non-null). – bolov May 05 '20 at 12:51
  • @bolov I disagree. Things are what you make them. If your codebase is full of smart pointers and RAII, when a raw pointer is used, it's clear that it's a non-owner. Your silence speaks there. If you're dedicated, you can use a `reference_wrapper` as an owner as in this [here](https://godbolt.org/z/yQ5cpH). – Aykhan Hagverdili May 05 '20 at 13:25
  • in your example the `reference_wrapper` is definitely not a owner. It does not manage the lifetime of the integer and you have a memory leak. "If your codebase is full of smart pointers and RAII, when a raw pointer is used, it's clear that it's a non-owner. " yes, if you have such a clean codebase then definitely yes. "I disagree" you can and you certainly have a point. But I will remain on my opinion that a higher abstraction with a narrower semantics is better. – bolov May 05 '20 at 15:04
2

so their member variables become same(a=d,b=e,c=f) and when i change a member variable of obj1, it changes in obj2 aswell.

What you want is not pointers or addresses. What you describe is a reference:

Test obj1(a,b,c);

Test& obj2 = obj1;

If you want to be able to rebind the reference then use std::reference_wrapper:

Test obj1(a,b,c);
Test obj1b(d,e,f);

auto obj2 = std::ref(obj1);
obj2 = obj1b;
bolov
  • 72,283
  • 15
  • 145
  • 224
  • Well, [not exactly](https://stackoverflow.com/questions/61611610/pass-address-of-an-object-pass-another-object-c/61611724#comment108983823_61611610) – Aykhan Hagverdili May 05 '20 at 11:31
  • @Ayxan yes exactly this. I see the same problem over and over again. The OP has a problem X and in solving this problem he/she thinks needs to implement Y so asks primarily about Y while mentioning X in passing. People then race to solve Y without stopping to think if the OP really needs Y. In this case `X` is paragraph I quote and Y is the question about pointers and adresses. – bolov May 05 '20 at 12:15
  • OP never mentioned pointers in the question. The question states "I want to store address of obj2 into obj1" and a comment mentions some constraint. – Aykhan Hagverdili May 05 '20 at 12:24
  • @Ayxan "I want to store address of obj2 into obj1` that is the Y in the XY problem. – bolov May 05 '20 at 12:29
  • Thank you for raising my awareness about rebindable reference wrapper objects. I've seen them used in template metaprogramming, and hadn't investigated more deeply at that time, hence I hadn't realized their general applicability. – Eljay May 05 '20 at 19:43