2013-07-26 20 views
0

我有這個類代碼重構嘗試使用多態性和std ::地圖

struct B { 
    B(int x=0) { } 
    virtual void something() { 
      std::cout << "B()"; 
    } 
}; 

struct A { 
    B b; 
    int a; 
    A(int a, int b_) : a(a), b(b_) {a} 
}; 

我已經實現了另一個C類

struct C : public B { 
    C(int x) : B(b) { } 
    virtual void something() { 
      std::cout << "C()"; 
    } 
}; 

是什麼讓一個用C++而不是最好的方法B?

我已經嘗試過這樣的:

struct A { 
     B & b; 
     int a; 
     A(int a, B &b_) : a(a), b(b_) {a} 
    }; 

但後來我不得不使用std::map<int, A> 這是給編譯錯誤:

'A::A' : no appropriate default constructor available. 

,所以我這樣做:

struct A { 
      B & b; 
      int a; 
      A(int a=0, B &b_=B()) : a(a), b(b_) {a} 
     }; 

在我的主要

std::map<int,A> mmap; 
for(int i=0;i<5;++i) { 
    auto & b = C(); 
    mmap.insert(std::make_pair(i,A(i,b))) ; 
} 

但是這些C在mmap的A中的對象只要auto & b超出範圍就變成B.

它不工作。如何解決它?

+4

您不能將臨時對象綁定到非常量引用。 – chris

+0

@chris我應該怎麼做,然後在A的構造函數? –

回答

1

在A構造函數中,您嘗試分配B的臨時實例以引用B,這是非法的。

,你所要做的就是通過指針改變這個參考這個類:

#include <iostream> 
#include <memory> 
#include <map> 

using namespace std; 

struct B { 

    B(int x=0) { } 
    virtual void something() 
    { 
     std::cout << "B()"; 
    } 
}; 

struct A { 
     shared_ptr<B> b; 
     int a; 
     A(int a = 0, shared_ptr<B> b = shared_ptr<B>(new B())) : a(a), b(b) {} 
}; 

struct C : public B { 
    C(int x) { } 
    virtual void something() 
    { 
     std::cout << "C()"; 
    } 
}; 

int main() 
{ 
    shared_ptr<B> b = shared_ptr<B>(new C(0)); 
    // Polymorphic test 
    b->something(); 

    A a (0, b); 
    // map test 
    map<int, A> my_map; 
    my_map[0] = a; 

    return 0; 
}; 

如果您不能使用C++ 11,只是用肉眼指針更改智能指針和處理動態內存像往常一樣正常。或者甚至更好:使用Boost庫,如chris所述。

+0

'make_shared'對於初始化來說是一個更好的選擇,並且總是有'boost :: shared_ptr'預C++ 11 :) – chris

+0

哦,是的,我忘了提起boost庫抱歉。但我不知道make_shared。感謝您的小費。通常我使用智能指針的「重置」方法,因爲它更簡單和更短。 (也是「自動」) – Rak

+0

是不是可以使用參考? –