2010-04-26 58 views
1

假設我有一個類A。我想將它指向一個小類B,這是一種智能指針,約束條件是B*自動轉換爲A*,這樣我就不需要重寫已經使用了A*的代碼。自動將A *轉換爲B *

因此,我要要修改B這樣下編譯...

struct A { 
    void foo() {} 
}; 

template <class K> 
struct B { 
    B(K* k) : _k(k) {} 
    //operator K*() {return _k;} 
    //K* operator->() {return _k;} 
private: 
    K* _k; 
}; 

void doSomething(A*) {} 

void test() { 
    A a; 
    A* pointer_to_a (&a); 
    B<A> b (pointer_to_a); 
    //b->foo();    // I don't need those two... 
    //doSomething(b); 

    B<A>* pointer_to_b (&b); 

    // Following represents existing code I don't want to change... 
    pointer_to_b->foo();  // 'foo' : is not a member of 'B<K>' 
    doSomething(pointer_to_b); // 'doSomething' : cannot convert parameter 1 from 'B<K> *' to 'A *' 
} 

注意BA繼承不是一個選項(的A實例在工廠創造出我的控制)。 ..

這可能嗎?

謝謝。

+2

你有沒有考慮現有的智能指針實現,如'auto_ptr'或'shared_ptr'? – Amber 2010-04-26 17:10:20

+0

轉換爲'A *'不是我想從'B'中唯一承擔的責任:它必須特別從其他類繼承。而且我將不得不使用'A *'來改變代碼,是嗎? – 2010-04-26 17:17:45

+0

那麼,您的運營商爲什麼註釋掉? – AnT 2010-04-26 17:18:40

回答

3

pointer_to_b的類型是指針到B,這是一種您不能修改的類型;它由編譯器實現。你可以做(​​ pointer_to_b) - > foo(),它會做正確的事情(假設你有重載操作符 - >())。但是,如果將pointer_to_be傳遞給其他代碼,則不會讓其他代碼做正確的事情。

另外讓我補充一點,你可以重寫B上的運算符&以返回一個A *,這可能會解決你的問題,這取決於具體的用例。

+0

我不想更新所有現有的代碼...... :( – 2010-04-26 17:19:09

+0

我的建議並不要求您更新所有的代碼,如果運營商和B可以返回A * – 2010-04-27 17:29:14

2

功能get()怎麼樣在boost::shared_ptr

pointer_to_b->get()->foo();  
doSomething(pointer_to_b->get()); 
+0

我仍然需要改變現有的代碼... – 2010-04-26 17:21:53

+0

是的,但是恕我直言,它將被清除 – 2010-04-26 17:31:35

0

您已在struct B看註釋掉像他們應該讓它做你想做的運營商......他們爲什麼註釋掉:

template <class K> 
struct B { 
    B(K* k) : _k(k) {} 
    K* get() { return _k;} 
private: 
    K* _k; 
}; 

然後,你可以按如下方式使用它?它們沒有註釋時不起作用,如果不能,你能發佈錯誤嗎?

+0

添加這些運算符允許我註釋到的兩個轉換,因爲我不需要它們註釋這些運算符不會改變出現在最後兩行。 – 2010-04-26 17:28:09

0

如果我記得shared_ptr解決問題的方法,我認爲你的答案是你永遠不會傳遞shared_ptr*,你會傳遞一個shared_ptr對象。這樣operator->的工作原理是因爲它在對象上被調用,而不是指向對象的指針。我建議你通過B<A>而不是B<A>*。誰在乎封裝類是否是一個指針,只要它代表一個指向A的指針就不重要。

0

b。在繼承是一種選擇,該編譯(2008 VS至少):

struct A { 
    void foo() {} 
}; 

template <typename T> 
struct B : T 
{ 
    B(const T& t) : T(t) 
    {} 
}; 

void doSomething(A*) {} 

void test() { 
    A a; 
    B<A> b (a); 

    B<A>* pointer_to_b (&b); 

    // Following represents existing code I don't want to change... 
    pointer_to_b->foo();  
    doSomething(pointer_to_b); 
} 
0

這應該從我的角度來看工作

struct A { 
    void foo() {} 
}; 

template <class K> 
struct B { 
    B(K* k) : _k(k) {} 
    operator K*() {return _k;} 
    K* operator->() {return _k;} 
private: 
    K* _k; 
}; 

void doSomething(A*) {} 

void test() { 
    A a; 
    A* pointer_to_a (&a); 
    B<A> pointer_to_b (pointer_to_a); 

    // Following represents existing code NOT CHANGED 
    pointer_to_b->foo();  
    doSomething(pointer_to_b); 

} 
相關問題