0

I can't get difference between two variants:

class test {
    std::unique_ptr<std::vector<float>> m_field;
    test(const std::vector<float>&& values) : m_field{std::make_unique<vector<float>>(std::move(values))} {}
};  

And

class test {
    const std::vector<float>&& m_field;
    test(const std::vector<float>&& values) : m_field{std::move(values)} {}
}; 

In the first variant the default destructor will remove unique_ptr and inner vector automatically but what will happen in the second variant how will the default destructor work?
What variant is better?
P.S. Maybe it's easy but I am looking for and can't find. My English isn't good, please, don't send me to hard docs.

cpplearner
  • 13,776
  • 2
  • 47
  • 72
Denis Sologub
  • 7,277
  • 11
  • 56
  • 123
  • 1
    A plain reference (or pointer) does not affect lifetime of its referent, obviously. So the destructor of the 2nd `class test` will not destroy the object referred to by `m_field`. What are you really trying to do with having a member rvalue reference? And especially a `const` one? It seems like an X/Y question to me. Anyway, if you want to know what destructor is generated, you can just step through it with a debugger. – underscore_d Dec 08 '17 at 12:23
  • Do you want to move const object ? Move operation cannot be done on const object, this vector will be copied. – rafix07 Dec 08 '17 at 12:24
  • @underscore_d, But I use `std::move` so as I got my reference will become the holder and how can I remove this object later then? – Denis Sologub Dec 08 '17 at 12:24
  • 1
    No, a plain reference is just a reference; it does not imply ownership or control over lifetime. And `std::move()` is just a cast to rvalue reference; by itself, it doesn't move anything. If you want to actually store the `vector` in your class, make the member a value, and `move()` into that. This all makes me wonder: Do you have a C++ book? – underscore_d Dec 08 '17 at 12:25
  • Yeah, I have but by old standard unfortunately – Denis Sologub Dec 08 '17 at 12:26
  • You should instead explain what you're trying to do, not just how - so we can tell you how to do it properly, instead of reacting to confusion about an attempt that might be the wrong way to do it. – underscore_d Dec 08 '17 at 12:27
  • And I need to get it in the real time now =) Cuz I am from Java and C# worlds – Denis Sologub Dec 08 '17 at 12:27
  • I need to pass my vector object to this class `test` to it became owner and removed vector object when I will remove `test` class object. That vector will not be used outside more after passing it – Denis Sologub Dec 08 '17 at 12:30
  • 1
    So again, make the member a value (`const`) if you want, and `move()` into that in your constructor so that `vector`'s move ctor fires. Then your classes default dtor will destroy the member and call the `vector` dtor. – underscore_d Dec 08 '17 at 12:31
  • @underscore_d, oh, I got... Thank you so much for clear explanation! – Denis Sologub Dec 08 '17 at 12:34
  • 1
    This is effectively a dupe of [When is a C++ destructor called?](https://stackoverflow.com/questions/10081429/when-is-a-c-destructor-called), though I can't flag it as such. – underscore_d Dec 08 '17 at 12:48

1 Answers1

1

First test class is useful when we remove const in constructor, it should be

class test {
public:
std::unique_ptr<std::vector<float>> m_field;
test(std::vector<float>&& values) : m_field{std::make_unique<vector<float>>(std::move(values))} {}
};  

because move operation can be done on non-const object. For example

vector<float> v(20, 3.0);
test t(move(v));
cout << v.size() << endl; // print 20 if `const` will be in constructor definition
                     // print 0 if `const` specifier is missed in constructor, object was moved  

Second test class is nonsense. Destructor of this class does nothing. In constructor m_field member is initialized and points at passed vector, and it is all, nothing more is done in ctor/dtor of this class.

rafix07
  • 20,001
  • 3
  • 20
  • 33