c++ What happens when alias to unique_ptr goes out of scope?











up vote
-1
down vote

favorite












If I have a unique pointer and I create an alias for it in a function, and that alias goes out of scope, why doesn't the original unique_ptr also get destroyed? After all, 'b' as defined in the function below is basically the same object in memory as 'x'. What is going on behind the scenes?



#include <iostream>
#include <memory>

void testfunc(std::unique_ptr<int>& x) {
std::unique_ptr<int>& b = x;
}
int main() {
std::unique_ptr<int> a(new int(5));
std::cout << *a << std::endl; // 5
testfunc(a);
std::cout << *a << std::endl; // 5
}









share|improve this question


















  • 2




    What you have are references (not aliases) and they only reference an actual variable, whose life-time doesn't end. Look at them as a kind of (non-smart) pointer. when the life-time of a pointer ends, it doesn't mean what they are pointing to will end.
    – Some programmer dude
    Nov 10 at 8:06












  • @Someprogrammerdude "What you have are references (not aliases)" - technically, by definition, a reference IS an alias. How the compiler implements the alias is up to the compiler vendor to decide (most use a pointer).
    – Remy Lebeau
    Nov 10 at 9:49












  • It would not be much fun if every time you passed a variable to a function by reference it got destroyed. So called "out parameters" would be a thing of the pase....
    – Galik
    Nov 10 at 10:18

















up vote
-1
down vote

favorite












If I have a unique pointer and I create an alias for it in a function, and that alias goes out of scope, why doesn't the original unique_ptr also get destroyed? After all, 'b' as defined in the function below is basically the same object in memory as 'x'. What is going on behind the scenes?



#include <iostream>
#include <memory>

void testfunc(std::unique_ptr<int>& x) {
std::unique_ptr<int>& b = x;
}
int main() {
std::unique_ptr<int> a(new int(5));
std::cout << *a << std::endl; // 5
testfunc(a);
std::cout << *a << std::endl; // 5
}









share|improve this question


















  • 2




    What you have are references (not aliases) and they only reference an actual variable, whose life-time doesn't end. Look at them as a kind of (non-smart) pointer. when the life-time of a pointer ends, it doesn't mean what they are pointing to will end.
    – Some programmer dude
    Nov 10 at 8:06












  • @Someprogrammerdude "What you have are references (not aliases)" - technically, by definition, a reference IS an alias. How the compiler implements the alias is up to the compiler vendor to decide (most use a pointer).
    – Remy Lebeau
    Nov 10 at 9:49












  • It would not be much fun if every time you passed a variable to a function by reference it got destroyed. So called "out parameters" would be a thing of the pase....
    – Galik
    Nov 10 at 10:18















up vote
-1
down vote

favorite









up vote
-1
down vote

favorite











If I have a unique pointer and I create an alias for it in a function, and that alias goes out of scope, why doesn't the original unique_ptr also get destroyed? After all, 'b' as defined in the function below is basically the same object in memory as 'x'. What is going on behind the scenes?



#include <iostream>
#include <memory>

void testfunc(std::unique_ptr<int>& x) {
std::unique_ptr<int>& b = x;
}
int main() {
std::unique_ptr<int> a(new int(5));
std::cout << *a << std::endl; // 5
testfunc(a);
std::cout << *a << std::endl; // 5
}









share|improve this question













If I have a unique pointer and I create an alias for it in a function, and that alias goes out of scope, why doesn't the original unique_ptr also get destroyed? After all, 'b' as defined in the function below is basically the same object in memory as 'x'. What is going on behind the scenes?



#include <iostream>
#include <memory>

void testfunc(std::unique_ptr<int>& x) {
std::unique_ptr<int>& b = x;
}
int main() {
std::unique_ptr<int> a(new int(5));
std::cout << *a << std::endl; // 5
testfunc(a);
std::cout << *a << std::endl; // 5
}






c++ smart-pointers






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 10 at 8:02









user2520385

702514




702514








  • 2




    What you have are references (not aliases) and they only reference an actual variable, whose life-time doesn't end. Look at them as a kind of (non-smart) pointer. when the life-time of a pointer ends, it doesn't mean what they are pointing to will end.
    – Some programmer dude
    Nov 10 at 8:06












  • @Someprogrammerdude "What you have are references (not aliases)" - technically, by definition, a reference IS an alias. How the compiler implements the alias is up to the compiler vendor to decide (most use a pointer).
    – Remy Lebeau
    Nov 10 at 9:49












  • It would not be much fun if every time you passed a variable to a function by reference it got destroyed. So called "out parameters" would be a thing of the pase....
    – Galik
    Nov 10 at 10:18
















  • 2




    What you have are references (not aliases) and they only reference an actual variable, whose life-time doesn't end. Look at them as a kind of (non-smart) pointer. when the life-time of a pointer ends, it doesn't mean what they are pointing to will end.
    – Some programmer dude
    Nov 10 at 8:06












  • @Someprogrammerdude "What you have are references (not aliases)" - technically, by definition, a reference IS an alias. How the compiler implements the alias is up to the compiler vendor to decide (most use a pointer).
    – Remy Lebeau
    Nov 10 at 9:49












  • It would not be much fun if every time you passed a variable to a function by reference it got destroyed. So called "out parameters" would be a thing of the pase....
    – Galik
    Nov 10 at 10:18










2




2




What you have are references (not aliases) and they only reference an actual variable, whose life-time doesn't end. Look at them as a kind of (non-smart) pointer. when the life-time of a pointer ends, it doesn't mean what they are pointing to will end.
– Some programmer dude
Nov 10 at 8:06






What you have are references (not aliases) and they only reference an actual variable, whose life-time doesn't end. Look at them as a kind of (non-smart) pointer. when the life-time of a pointer ends, it doesn't mean what they are pointing to will end.
– Some programmer dude
Nov 10 at 8:06














@Someprogrammerdude "What you have are references (not aliases)" - technically, by definition, a reference IS an alias. How the compiler implements the alias is up to the compiler vendor to decide (most use a pointer).
– Remy Lebeau
Nov 10 at 9:49






@Someprogrammerdude "What you have are references (not aliases)" - technically, by definition, a reference IS an alias. How the compiler implements the alias is up to the compiler vendor to decide (most use a pointer).
– Remy Lebeau
Nov 10 at 9:49














It would not be much fun if every time you passed a variable to a function by reference it got destroyed. So called "out parameters" would be a thing of the pase....
– Galik
Nov 10 at 10:18






It would not be much fun if every time you passed a variable to a function by reference it got destroyed. So called "out parameters" would be a thing of the pase....
– Galik
Nov 10 at 10:18














4 Answers
4






active

oldest

votes

















up vote
0
down vote



accepted










A reference is can be considered like an alias to an element, hence it references another variable by taking up its value and working just like it does, but it doesn't get destroyed until called by the destructor or forcibly destroyed by the programmer which will also destroy the variable it references... since a reference is just an editable alias... However their lifespan differs since a non-reference type can be moved and it becomes out of scope...




"What is going on behind the scenes?"




Inside the memory, the reference allows us to change the value of an element and if often used instead of pointers which were a common practice in C... But, its value cannot be moved unless passed... A reference's value won't change unless changed using an assignment operation directly or indirectly i.e, from the function parameter x which itself is an alias...



Like: x = std::make_unique<int>(6); will change the value of a to 6 instead... But what you have done here instead is...



auto& b = x;


Nothing actually happens except the value that x(references to a) is referencing to is copied and passed to b (which just acts like another alias)... So it is similar to doing: auto& b = a;, but since a is outside the scope, it references a's value indirectly...



#include <iostream>
#include <memory>

void testfunc(std::unique_ptr<int>& x)
{
auto& b(x); // 'b' is an alias of 'x' and 'x' is an alias of 'a'
b = std::make_unique<int>(6); // Setting 'b' to 6 meaning setting 'a' to 6...
/* Now you can't do 'x = b' since you cannot assign a value to an alias and it is
like a 'circular assignment operation'...*/
}
int main()
{
std::unique_ptr<int> a(new int(5));
std::cout << *a << std::endl; // 5 : Nothing happens, just initialization...
testfunc(a); // It does not affect the reference...
std::cout << *a << std::endl; /* 6 : Since reference is an 'alias', you
changed 'a' as well...*/
} // It is freed after use by the destructor...


So, a general advice from people would be that you should avoid references if you are unsure of what it does (It can change the real variable if you are unknown of its consequences)... and take some time to learn about them...



If you destroy the original however..., all the references themselves will become invalidated... In such a case, when trying to access the value of destroyed (nullified) object is undefined causing undefined behavior...






share|improve this answer























  • "stores addresses inside it" thats an implementation detail that may or may not be so.
    – Swordfish
    Nov 10 at 8:59












  • "and never goes out of scope" references go out of scope like all other variables.
    – Swordfish
    Nov 10 at 9:00


















up vote
1
down vote













What you're using is a reference, and a reference in C++ is a distinct type from what it is referencing. You can interact with an object through a reference, but the reference itself and the object being referred to have separate lifetimes. When one is destroyed, the other doesn't automatically get destroyed. This means you can pass a reference into a function and then at the end of a function when the reference is destroyed the original object is still valid. This allows passing around large complex objects without needing to copy or even moving them. It's a implementation detail, but it's common for compilers to simply use a pointer "behind the scenes" as references.



As a side note, this aspect of references in C++ leads to the infamous dangling reference issue. If you hold a reference to some object and that object is destroyed the reference you have is now technically invalid, and you'll invoke undefined behavior if you use it. Unfortunately there is nothing built into the language to automatically detect or deal with this situation. You must architect your program to avoid it.






share|improve this answer




























    up vote
    0
    down vote













    #include <iostream>
    #include <memory>

    void testfunc(std::unique_ptr<int>& x) { // you take a reference to a unique_ptr
    std::unique_ptr<int>& b = x; // which will do nothing to the lifetime of
    } // the unique_ptr you pass to the function,
    // then you assign the passed parameter
    // to another reference. again, that does
    // nothing to the lifetime of the original.
    int main() {
    std::unique_ptr<int> a(new int(5));
    std::cout << *a << std::endl; // 5
    testfunc(a);
    std::cout << *a << std::endl; // 5
    }





    share|improve this answer






























      up vote
      0
      down vote














      After all, 'b' as defined in the function below is basically the same object in memory as 'x'.




      Not at all. x is a reference. A reference is not an object, and no constructor or destructor is called for it. There are no "aliases" for variables. There are for types, also known as typedefs.



      Consider the same code with pointers instead:



      void testfunc(std::unique_ptr<int>* x) {
      std::unique_ptr<int>* b = x;
      }
      int main() {
      std::unique_ptr<int> a(new int(5));
      std::cout << *a << std::endl; // 5
      testfunc(&a);
      std::cout << *a << std::endl; // 5
      }


      The only time a reference can affect the lifetime of an object is when a reference binds to a temporary, but even then, it extends the lifetime rather than reducing it:



      struct A {};

      int main() {
      {
      A(); // Constructed and destructed
      }

      {
      A const& a = A(); // Constructed
      // Other instructions
      } // Destructed
      }


      Demo






      share|improve this answer























      • A reference can very well be considered an alias.
        – Swordfish
        Nov 10 at 8:52












      • @Swordfish Loosely, maybe. But "an alias for X" means "another name for X", not "a reference to X". Which is apparently the whole point of confusion in the question. On the other hand, a type alias is exaclty that: another name for exactly the same thing.
        – Nelfeal
        Nov 10 at 9:17










      • A reference to foo x; is an alias to x.
        – Swordfish
        Nov 10 at 9:25











      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53237109%2fc-what-happens-when-alias-to-unique-ptr-goes-out-of-scope%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      4 Answers
      4






      active

      oldest

      votes








      4 Answers
      4






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      0
      down vote



      accepted










      A reference is can be considered like an alias to an element, hence it references another variable by taking up its value and working just like it does, but it doesn't get destroyed until called by the destructor or forcibly destroyed by the programmer which will also destroy the variable it references... since a reference is just an editable alias... However their lifespan differs since a non-reference type can be moved and it becomes out of scope...




      "What is going on behind the scenes?"




      Inside the memory, the reference allows us to change the value of an element and if often used instead of pointers which were a common practice in C... But, its value cannot be moved unless passed... A reference's value won't change unless changed using an assignment operation directly or indirectly i.e, from the function parameter x which itself is an alias...



      Like: x = std::make_unique<int>(6); will change the value of a to 6 instead... But what you have done here instead is...



      auto& b = x;


      Nothing actually happens except the value that x(references to a) is referencing to is copied and passed to b (which just acts like another alias)... So it is similar to doing: auto& b = a;, but since a is outside the scope, it references a's value indirectly...



      #include <iostream>
      #include <memory>

      void testfunc(std::unique_ptr<int>& x)
      {
      auto& b(x); // 'b' is an alias of 'x' and 'x' is an alias of 'a'
      b = std::make_unique<int>(6); // Setting 'b' to 6 meaning setting 'a' to 6...
      /* Now you can't do 'x = b' since you cannot assign a value to an alias and it is
      like a 'circular assignment operation'...*/
      }
      int main()
      {
      std::unique_ptr<int> a(new int(5));
      std::cout << *a << std::endl; // 5 : Nothing happens, just initialization...
      testfunc(a); // It does not affect the reference...
      std::cout << *a << std::endl; /* 6 : Since reference is an 'alias', you
      changed 'a' as well...*/
      } // It is freed after use by the destructor...


      So, a general advice from people would be that you should avoid references if you are unsure of what it does (It can change the real variable if you are unknown of its consequences)... and take some time to learn about them...



      If you destroy the original however..., all the references themselves will become invalidated... In such a case, when trying to access the value of destroyed (nullified) object is undefined causing undefined behavior...






      share|improve this answer























      • "stores addresses inside it" thats an implementation detail that may or may not be so.
        – Swordfish
        Nov 10 at 8:59












      • "and never goes out of scope" references go out of scope like all other variables.
        – Swordfish
        Nov 10 at 9:00















      up vote
      0
      down vote



      accepted










      A reference is can be considered like an alias to an element, hence it references another variable by taking up its value and working just like it does, but it doesn't get destroyed until called by the destructor or forcibly destroyed by the programmer which will also destroy the variable it references... since a reference is just an editable alias... However their lifespan differs since a non-reference type can be moved and it becomes out of scope...




      "What is going on behind the scenes?"




      Inside the memory, the reference allows us to change the value of an element and if often used instead of pointers which were a common practice in C... But, its value cannot be moved unless passed... A reference's value won't change unless changed using an assignment operation directly or indirectly i.e, from the function parameter x which itself is an alias...



      Like: x = std::make_unique<int>(6); will change the value of a to 6 instead... But what you have done here instead is...



      auto& b = x;


      Nothing actually happens except the value that x(references to a) is referencing to is copied and passed to b (which just acts like another alias)... So it is similar to doing: auto& b = a;, but since a is outside the scope, it references a's value indirectly...



      #include <iostream>
      #include <memory>

      void testfunc(std::unique_ptr<int>& x)
      {
      auto& b(x); // 'b' is an alias of 'x' and 'x' is an alias of 'a'
      b = std::make_unique<int>(6); // Setting 'b' to 6 meaning setting 'a' to 6...
      /* Now you can't do 'x = b' since you cannot assign a value to an alias and it is
      like a 'circular assignment operation'...*/
      }
      int main()
      {
      std::unique_ptr<int> a(new int(5));
      std::cout << *a << std::endl; // 5 : Nothing happens, just initialization...
      testfunc(a); // It does not affect the reference...
      std::cout << *a << std::endl; /* 6 : Since reference is an 'alias', you
      changed 'a' as well...*/
      } // It is freed after use by the destructor...


      So, a general advice from people would be that you should avoid references if you are unsure of what it does (It can change the real variable if you are unknown of its consequences)... and take some time to learn about them...



      If you destroy the original however..., all the references themselves will become invalidated... In such a case, when trying to access the value of destroyed (nullified) object is undefined causing undefined behavior...






      share|improve this answer























      • "stores addresses inside it" thats an implementation detail that may or may not be so.
        – Swordfish
        Nov 10 at 8:59












      • "and never goes out of scope" references go out of scope like all other variables.
        – Swordfish
        Nov 10 at 9:00













      up vote
      0
      down vote



      accepted







      up vote
      0
      down vote



      accepted






      A reference is can be considered like an alias to an element, hence it references another variable by taking up its value and working just like it does, but it doesn't get destroyed until called by the destructor or forcibly destroyed by the programmer which will also destroy the variable it references... since a reference is just an editable alias... However their lifespan differs since a non-reference type can be moved and it becomes out of scope...




      "What is going on behind the scenes?"




      Inside the memory, the reference allows us to change the value of an element and if often used instead of pointers which were a common practice in C... But, its value cannot be moved unless passed... A reference's value won't change unless changed using an assignment operation directly or indirectly i.e, from the function parameter x which itself is an alias...



      Like: x = std::make_unique<int>(6); will change the value of a to 6 instead... But what you have done here instead is...



      auto& b = x;


      Nothing actually happens except the value that x(references to a) is referencing to is copied and passed to b (which just acts like another alias)... So it is similar to doing: auto& b = a;, but since a is outside the scope, it references a's value indirectly...



      #include <iostream>
      #include <memory>

      void testfunc(std::unique_ptr<int>& x)
      {
      auto& b(x); // 'b' is an alias of 'x' and 'x' is an alias of 'a'
      b = std::make_unique<int>(6); // Setting 'b' to 6 meaning setting 'a' to 6...
      /* Now you can't do 'x = b' since you cannot assign a value to an alias and it is
      like a 'circular assignment operation'...*/
      }
      int main()
      {
      std::unique_ptr<int> a(new int(5));
      std::cout << *a << std::endl; // 5 : Nothing happens, just initialization...
      testfunc(a); // It does not affect the reference...
      std::cout << *a << std::endl; /* 6 : Since reference is an 'alias', you
      changed 'a' as well...*/
      } // It is freed after use by the destructor...


      So, a general advice from people would be that you should avoid references if you are unsure of what it does (It can change the real variable if you are unknown of its consequences)... and take some time to learn about them...



      If you destroy the original however..., all the references themselves will become invalidated... In such a case, when trying to access the value of destroyed (nullified) object is undefined causing undefined behavior...






      share|improve this answer














      A reference is can be considered like an alias to an element, hence it references another variable by taking up its value and working just like it does, but it doesn't get destroyed until called by the destructor or forcibly destroyed by the programmer which will also destroy the variable it references... since a reference is just an editable alias... However their lifespan differs since a non-reference type can be moved and it becomes out of scope...




      "What is going on behind the scenes?"




      Inside the memory, the reference allows us to change the value of an element and if often used instead of pointers which were a common practice in C... But, its value cannot be moved unless passed... A reference's value won't change unless changed using an assignment operation directly or indirectly i.e, from the function parameter x which itself is an alias...



      Like: x = std::make_unique<int>(6); will change the value of a to 6 instead... But what you have done here instead is...



      auto& b = x;


      Nothing actually happens except the value that x(references to a) is referencing to is copied and passed to b (which just acts like another alias)... So it is similar to doing: auto& b = a;, but since a is outside the scope, it references a's value indirectly...



      #include <iostream>
      #include <memory>

      void testfunc(std::unique_ptr<int>& x)
      {
      auto& b(x); // 'b' is an alias of 'x' and 'x' is an alias of 'a'
      b = std::make_unique<int>(6); // Setting 'b' to 6 meaning setting 'a' to 6...
      /* Now you can't do 'x = b' since you cannot assign a value to an alias and it is
      like a 'circular assignment operation'...*/
      }
      int main()
      {
      std::unique_ptr<int> a(new int(5));
      std::cout << *a << std::endl; // 5 : Nothing happens, just initialization...
      testfunc(a); // It does not affect the reference...
      std::cout << *a << std::endl; /* 6 : Since reference is an 'alias', you
      changed 'a' as well...*/
      } // It is freed after use by the destructor...


      So, a general advice from people would be that you should avoid references if you are unsure of what it does (It can change the real variable if you are unknown of its consequences)... and take some time to learn about them...



      If you destroy the original however..., all the references themselves will become invalidated... In such a case, when trying to access the value of destroyed (nullified) object is undefined causing undefined behavior...







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 10 at 15:30

























      answered Nov 10 at 8:24









      Ruks

      780111




      780111












      • "stores addresses inside it" thats an implementation detail that may or may not be so.
        – Swordfish
        Nov 10 at 8:59












      • "and never goes out of scope" references go out of scope like all other variables.
        – Swordfish
        Nov 10 at 9:00


















      • "stores addresses inside it" thats an implementation detail that may or may not be so.
        – Swordfish
        Nov 10 at 8:59












      • "and never goes out of scope" references go out of scope like all other variables.
        – Swordfish
        Nov 10 at 9:00
















      "stores addresses inside it" thats an implementation detail that may or may not be so.
      – Swordfish
      Nov 10 at 8:59






      "stores addresses inside it" thats an implementation detail that may or may not be so.
      – Swordfish
      Nov 10 at 8:59














      "and never goes out of scope" references go out of scope like all other variables.
      – Swordfish
      Nov 10 at 9:00




      "and never goes out of scope" references go out of scope like all other variables.
      – Swordfish
      Nov 10 at 9:00












      up vote
      1
      down vote













      What you're using is a reference, and a reference in C++ is a distinct type from what it is referencing. You can interact with an object through a reference, but the reference itself and the object being referred to have separate lifetimes. When one is destroyed, the other doesn't automatically get destroyed. This means you can pass a reference into a function and then at the end of a function when the reference is destroyed the original object is still valid. This allows passing around large complex objects without needing to copy or even moving them. It's a implementation detail, but it's common for compilers to simply use a pointer "behind the scenes" as references.



      As a side note, this aspect of references in C++ leads to the infamous dangling reference issue. If you hold a reference to some object and that object is destroyed the reference you have is now technically invalid, and you'll invoke undefined behavior if you use it. Unfortunately there is nothing built into the language to automatically detect or deal with this situation. You must architect your program to avoid it.






      share|improve this answer

























        up vote
        1
        down vote













        What you're using is a reference, and a reference in C++ is a distinct type from what it is referencing. You can interact with an object through a reference, but the reference itself and the object being referred to have separate lifetimes. When one is destroyed, the other doesn't automatically get destroyed. This means you can pass a reference into a function and then at the end of a function when the reference is destroyed the original object is still valid. This allows passing around large complex objects without needing to copy or even moving them. It's a implementation detail, but it's common for compilers to simply use a pointer "behind the scenes" as references.



        As a side note, this aspect of references in C++ leads to the infamous dangling reference issue. If you hold a reference to some object and that object is destroyed the reference you have is now technically invalid, and you'll invoke undefined behavior if you use it. Unfortunately there is nothing built into the language to automatically detect or deal with this situation. You must architect your program to avoid it.






        share|improve this answer























          up vote
          1
          down vote










          up vote
          1
          down vote









          What you're using is a reference, and a reference in C++ is a distinct type from what it is referencing. You can interact with an object through a reference, but the reference itself and the object being referred to have separate lifetimes. When one is destroyed, the other doesn't automatically get destroyed. This means you can pass a reference into a function and then at the end of a function when the reference is destroyed the original object is still valid. This allows passing around large complex objects without needing to copy or even moving them. It's a implementation detail, but it's common for compilers to simply use a pointer "behind the scenes" as references.



          As a side note, this aspect of references in C++ leads to the infamous dangling reference issue. If you hold a reference to some object and that object is destroyed the reference you have is now technically invalid, and you'll invoke undefined behavior if you use it. Unfortunately there is nothing built into the language to automatically detect or deal with this situation. You must architect your program to avoid it.






          share|improve this answer












          What you're using is a reference, and a reference in C++ is a distinct type from what it is referencing. You can interact with an object through a reference, but the reference itself and the object being referred to have separate lifetimes. When one is destroyed, the other doesn't automatically get destroyed. This means you can pass a reference into a function and then at the end of a function when the reference is destroyed the original object is still valid. This allows passing around large complex objects without needing to copy or even moving them. It's a implementation detail, but it's common for compilers to simply use a pointer "behind the scenes" as references.



          As a side note, this aspect of references in C++ leads to the infamous dangling reference issue. If you hold a reference to some object and that object is destroyed the reference you have is now technically invalid, and you'll invoke undefined behavior if you use it. Unfortunately there is nothing built into the language to automatically detect or deal with this situation. You must architect your program to avoid it.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 10 at 12:08









          bobshowrocks

          31916




          31916






















              up vote
              0
              down vote













              #include <iostream>
              #include <memory>

              void testfunc(std::unique_ptr<int>& x) { // you take a reference to a unique_ptr
              std::unique_ptr<int>& b = x; // which will do nothing to the lifetime of
              } // the unique_ptr you pass to the function,
              // then you assign the passed parameter
              // to another reference. again, that does
              // nothing to the lifetime of the original.
              int main() {
              std::unique_ptr<int> a(new int(5));
              std::cout << *a << std::endl; // 5
              testfunc(a);
              std::cout << *a << std::endl; // 5
              }





              share|improve this answer



























                up vote
                0
                down vote













                #include <iostream>
                #include <memory>

                void testfunc(std::unique_ptr<int>& x) { // you take a reference to a unique_ptr
                std::unique_ptr<int>& b = x; // which will do nothing to the lifetime of
                } // the unique_ptr you pass to the function,
                // then you assign the passed parameter
                // to another reference. again, that does
                // nothing to the lifetime of the original.
                int main() {
                std::unique_ptr<int> a(new int(5));
                std::cout << *a << std::endl; // 5
                testfunc(a);
                std::cout << *a << std::endl; // 5
                }





                share|improve this answer

























                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  #include <iostream>
                  #include <memory>

                  void testfunc(std::unique_ptr<int>& x) { // you take a reference to a unique_ptr
                  std::unique_ptr<int>& b = x; // which will do nothing to the lifetime of
                  } // the unique_ptr you pass to the function,
                  // then you assign the passed parameter
                  // to another reference. again, that does
                  // nothing to the lifetime of the original.
                  int main() {
                  std::unique_ptr<int> a(new int(5));
                  std::cout << *a << std::endl; // 5
                  testfunc(a);
                  std::cout << *a << std::endl; // 5
                  }





                  share|improve this answer














                  #include <iostream>
                  #include <memory>

                  void testfunc(std::unique_ptr<int>& x) { // you take a reference to a unique_ptr
                  std::unique_ptr<int>& b = x; // which will do nothing to the lifetime of
                  } // the unique_ptr you pass to the function,
                  // then you assign the passed parameter
                  // to another reference. again, that does
                  // nothing to the lifetime of the original.
                  int main() {
                  std::unique_ptr<int> a(new int(5));
                  std::cout << *a << std::endl; // 5
                  testfunc(a);
                  std::cout << *a << std::endl; // 5
                  }






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Nov 10 at 8:11

























                  answered Nov 10 at 8:06









                  Swordfish

                  1




                  1






















                      up vote
                      0
                      down vote














                      After all, 'b' as defined in the function below is basically the same object in memory as 'x'.




                      Not at all. x is a reference. A reference is not an object, and no constructor or destructor is called for it. There are no "aliases" for variables. There are for types, also known as typedefs.



                      Consider the same code with pointers instead:



                      void testfunc(std::unique_ptr<int>* x) {
                      std::unique_ptr<int>* b = x;
                      }
                      int main() {
                      std::unique_ptr<int> a(new int(5));
                      std::cout << *a << std::endl; // 5
                      testfunc(&a);
                      std::cout << *a << std::endl; // 5
                      }


                      The only time a reference can affect the lifetime of an object is when a reference binds to a temporary, but even then, it extends the lifetime rather than reducing it:



                      struct A {};

                      int main() {
                      {
                      A(); // Constructed and destructed
                      }

                      {
                      A const& a = A(); // Constructed
                      // Other instructions
                      } // Destructed
                      }


                      Demo






                      share|improve this answer























                      • A reference can very well be considered an alias.
                        – Swordfish
                        Nov 10 at 8:52












                      • @Swordfish Loosely, maybe. But "an alias for X" means "another name for X", not "a reference to X". Which is apparently the whole point of confusion in the question. On the other hand, a type alias is exaclty that: another name for exactly the same thing.
                        – Nelfeal
                        Nov 10 at 9:17










                      • A reference to foo x; is an alias to x.
                        – Swordfish
                        Nov 10 at 9:25















                      up vote
                      0
                      down vote














                      After all, 'b' as defined in the function below is basically the same object in memory as 'x'.




                      Not at all. x is a reference. A reference is not an object, and no constructor or destructor is called for it. There are no "aliases" for variables. There are for types, also known as typedefs.



                      Consider the same code with pointers instead:



                      void testfunc(std::unique_ptr<int>* x) {
                      std::unique_ptr<int>* b = x;
                      }
                      int main() {
                      std::unique_ptr<int> a(new int(5));
                      std::cout << *a << std::endl; // 5
                      testfunc(&a);
                      std::cout << *a << std::endl; // 5
                      }


                      The only time a reference can affect the lifetime of an object is when a reference binds to a temporary, but even then, it extends the lifetime rather than reducing it:



                      struct A {};

                      int main() {
                      {
                      A(); // Constructed and destructed
                      }

                      {
                      A const& a = A(); // Constructed
                      // Other instructions
                      } // Destructed
                      }


                      Demo






                      share|improve this answer























                      • A reference can very well be considered an alias.
                        – Swordfish
                        Nov 10 at 8:52












                      • @Swordfish Loosely, maybe. But "an alias for X" means "another name for X", not "a reference to X". Which is apparently the whole point of confusion in the question. On the other hand, a type alias is exaclty that: another name for exactly the same thing.
                        – Nelfeal
                        Nov 10 at 9:17










                      • A reference to foo x; is an alias to x.
                        – Swordfish
                        Nov 10 at 9:25













                      up vote
                      0
                      down vote










                      up vote
                      0
                      down vote










                      After all, 'b' as defined in the function below is basically the same object in memory as 'x'.




                      Not at all. x is a reference. A reference is not an object, and no constructor or destructor is called for it. There are no "aliases" for variables. There are for types, also known as typedefs.



                      Consider the same code with pointers instead:



                      void testfunc(std::unique_ptr<int>* x) {
                      std::unique_ptr<int>* b = x;
                      }
                      int main() {
                      std::unique_ptr<int> a(new int(5));
                      std::cout << *a << std::endl; // 5
                      testfunc(&a);
                      std::cout << *a << std::endl; // 5
                      }


                      The only time a reference can affect the lifetime of an object is when a reference binds to a temporary, but even then, it extends the lifetime rather than reducing it:



                      struct A {};

                      int main() {
                      {
                      A(); // Constructed and destructed
                      }

                      {
                      A const& a = A(); // Constructed
                      // Other instructions
                      } // Destructed
                      }


                      Demo






                      share|improve this answer















                      After all, 'b' as defined in the function below is basically the same object in memory as 'x'.




                      Not at all. x is a reference. A reference is not an object, and no constructor or destructor is called for it. There are no "aliases" for variables. There are for types, also known as typedefs.



                      Consider the same code with pointers instead:



                      void testfunc(std::unique_ptr<int>* x) {
                      std::unique_ptr<int>* b = x;
                      }
                      int main() {
                      std::unique_ptr<int> a(new int(5));
                      std::cout << *a << std::endl; // 5
                      testfunc(&a);
                      std::cout << *a << std::endl; // 5
                      }


                      The only time a reference can affect the lifetime of an object is when a reference binds to a temporary, but even then, it extends the lifetime rather than reducing it:



                      struct A {};

                      int main() {
                      {
                      A(); // Constructed and destructed
                      }

                      {
                      A const& a = A(); // Constructed
                      // Other instructions
                      } // Destructed
                      }


                      Demo







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited Nov 10 at 8:17

























                      answered Nov 10 at 8:06









                      Nelfeal

                      4,170621




                      4,170621












                      • A reference can very well be considered an alias.
                        – Swordfish
                        Nov 10 at 8:52












                      • @Swordfish Loosely, maybe. But "an alias for X" means "another name for X", not "a reference to X". Which is apparently the whole point of confusion in the question. On the other hand, a type alias is exaclty that: another name for exactly the same thing.
                        – Nelfeal
                        Nov 10 at 9:17










                      • A reference to foo x; is an alias to x.
                        – Swordfish
                        Nov 10 at 9:25


















                      • A reference can very well be considered an alias.
                        – Swordfish
                        Nov 10 at 8:52












                      • @Swordfish Loosely, maybe. But "an alias for X" means "another name for X", not "a reference to X". Which is apparently the whole point of confusion in the question. On the other hand, a type alias is exaclty that: another name for exactly the same thing.
                        – Nelfeal
                        Nov 10 at 9:17










                      • A reference to foo x; is an alias to x.
                        – Swordfish
                        Nov 10 at 9:25
















                      A reference can very well be considered an alias.
                      – Swordfish
                      Nov 10 at 8:52






                      A reference can very well be considered an alias.
                      – Swordfish
                      Nov 10 at 8:52














                      @Swordfish Loosely, maybe. But "an alias for X" means "another name for X", not "a reference to X". Which is apparently the whole point of confusion in the question. On the other hand, a type alias is exaclty that: another name for exactly the same thing.
                      – Nelfeal
                      Nov 10 at 9:17




                      @Swordfish Loosely, maybe. But "an alias for X" means "another name for X", not "a reference to X". Which is apparently the whole point of confusion in the question. On the other hand, a type alias is exaclty that: another name for exactly the same thing.
                      – Nelfeal
                      Nov 10 at 9:17












                      A reference to foo x; is an alias to x.
                      – Swordfish
                      Nov 10 at 9:25




                      A reference to foo x; is an alias to x.
                      – Swordfish
                      Nov 10 at 9:25


















                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53237109%2fc-what-happens-when-alias-to-unique-ptr-goes-out-of-scope%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Schultheiß

                      Verwaltungsgliederung Dänemarks

                      Liste der Kulturdenkmale in Wilsdruff