2011-08-02 56 views
0

下面一段代碼元組的右值參考

#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; 
} 

我想到的是,在離開intermeidate範圍,載體自毀並且它試圖破壞元組中conatain。這反過來破壞了A的對象,但是一些我沒有看到任何對象被破壞。 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」的析構函數?

@編輯] @霍華德Hinnant:謝謝,它是非常有意義的。我不明白的是: 1)當我用一個右值構造一個元組並將它推送到矢量時,我確實得到了valgrind內存錯誤。例如。

myVec.push_back(std::make_tuple(10)); 
在最內側範圍並添加

auto& z = get<0>(myVec.at(2)); 
std::cout << z.get() << std::endl; 

在上述實施例的中間範圍的valgrind產生的存儲器錯誤,但是上面未示出的左值的引用。

2)有人可以解釋爲什麼下面的語句調用copu構造函數和立即desctructor?

myVec.push_back(std::make_tuple(a)); 

回答

1

「A」和「B」被破壞你離開最裏面的範圍,因爲你的輸出顯示:您通過get獲得中間範圍

Innermost scope 
Destructor 200, this: 0x7fefffc60 
Destructor 100, this: 0x7fefffc70 
Intermediate scope 

引用被晃來晃去:他們引用被破壞的物體。有~A()m_a來證實這一點。

當你離開Intermediate作用域時,它所擁有的vector和tuples被破壞。引用元組的析構函數是無操作的。

+0

感謝您的回答,它非常有意義。我在上面添加了更多的後續問題,你能否看看你是否可以回答他們? – Aravind