Следующий фрагмент кода
#include <iostream>
#include <vector>
#include <tuple>
using namespace std;
class A {
int m_a;
public:
A(): m_a( 10 ) { std::cout << "Default Constructor " << m_a << ", this: " << this << std::endl; }
A( int a ): m_a( a ) { std::cout << "Main Constructor " << m_a << ", this: " << this << std::endl; }
A( const A& a ): m_a( a.m_a) { std::cout << "Copy Constructor: " << m_a << ", this: " << this << std::endl; }
A( const A&& a ): m_a( std::move(a.m_a) ) { std::cout << "RValue copy Constructor " << m_a << ", this: " << this << std::endl; }
int get() const { return m_a; }
virtual ~A() { std::cout << "Destructor " << m_a << ", this: " << this << std::endl; }
};
int main() {
{
typedef std::tuple< A&& > MyContainer;
std::vector< MyContainer > myVec;
{
A a(100);
A b(200);
myVec.push_back( std::make_tuple( a ) );
myVec.push_back( std::make_tuple( b ) );
std::cout << "Innermost scope" << std::endl;
}
std::cout << "Intermediate scope" << std::endl;
auto& x = get<0>(myVec.at(0));
auto& y = get<0>(myVec.at(1));
std::cout << x.get() << std::endl;
std::cout << y.get() << std::endl;
}
std::cout << "Outermost scope" << std::endl;
return 0;
}
Я ожидаю, что после выхода из промежуточной области вектор разрушается и пытается разрушить кортежи в conatain.Это, в свою очередь, разрушает объекты А, но я не вижу, чтобы какие-либо объекты разрушались.Valgrind также не показывает ошибок памяти.Ниже приводится вывод при запуске с valgrind $ valgrind ./a.out
==7366== Memcheck, a memory error detector
==7366== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==7366== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
==7366== Command: ./a.out
==7366==
Main Constructor 100, this: 0x7fefffc70
Main Constructor 200, this: 0x7fefffc60
Copy Constructor: 100, this: 0x7fefffcb0
Destructor 100, this: 0x7fefffcb0
Copy Constructor: 200, this: 0x7fefffcd0
Destructor 200, this: 0x7fefffcd0
Innermost scope
Destructor 200, this: 0x7fefffc60
Destructor 100, this: 0x7fefffc70
Intermediate scope
100
200
Outermost scope
==7366==
==7366== HEAP SUMMARY:
==7366== in use at exit: 0 bytes in 0 blocks
==7366== total heap usage: 2 allocs, 2 frees, 24 bytes allocated
==7366==
==7366== All heap blocks were freed -- no leaks are possible
==7366==
==7366== For counts of detected and suppressed errors, rerun with: -v
==7366== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 6)
Я, очевидно, здесь кое-что упускаю.Если вызовы «get ()» в промежуточной области видимости возвращают соответствующие значения (100 и 200), почему деструкторы «A» не вызываются, когда вектор (и кортежи) разрушается?
[РЕДАКТИРОВАТЬ] @ Ховард Хиннант: Спасибо, и это имеет смысл.Что я не понимаю, так это следующее: 1) Когда я создаю кортеж с помощью значения r и помещаю его в вектор, я получаю ошибки памяти valgrind.Например,
myVec.push_back( std::make_tuple( 10 ) );
во внутренней области видимости и добавление:
auto& z = get<0>(myVec.at(2));
std::cout << z.get() << std::endl;
к промежуточной области видимости в приведенных выше примерах приводит к ошибкам памяти valgrind, но не к указанным выше ссылкам lvalue
2) Может кто-нибудь объяснить, почему следующее утверждение вызывает конструктор copu и непосредственный десктруктор?
myVec.push_back( std::make_tuple( a ) );