2012-05-17 150 views
2

這裏常數函數的代碼,我有調用從另一個類對象

class A 
{ 
public: 
    void Func1() const; 
}; 

class B 
{ 
public: 
    A* a; 
    void Func2() const 
    { 
     // do something with 'a' 
    } 
}; 

void A::Func1() const 
{ 
    B b; 
    b.a = this; 
    b.Func2(); 
} 

現在很明顯這是給我一個錯誤的路線,因爲我想從常量轉換成非const。

b.a = this; 

有沒有什麼方法來調用Func2無需進行轉換的this走常量性。由於Func2是一個const函數,所以它不會更改this

+0

當你有一個const函數時,你不能改變與該對象有關的任何東西。要麼稱它爲const * A a,要麼從函數中移除const。 – Martol1ni

回答

1

如果class B總是要與*a作爲const對象來工作,然後像其他人說,所有它需要的是申報簡單地改變

public: const A* a 

在這一點上,我應該提到B::Func2的恆定性是一個紅色的鯡魚,因爲它與B::a的恆定性完全沒有關係。那B::Func2const意味着它不允許更改值a;然而,它允許取消a並mutate生成的對象。

現在,如果class B相對於這兩個const和非const操作*a那麼你一流的設計需要改變。如果您將class B更改爲使用上述的const A* a,並添加另一個封裝所有變異操作的class D : public B會好得多。另外,a應該隱藏在財產製定者的後面;這可以讓你做的事情一樣

class B { 
    const A* a; 
public: 
    void setA(const A* a) { this->a = a; } 
    void Func2() const {} 
}; 

class D : public B { 
    A* a; 
public: 
    using B::setA; 
    void setA(A* a) { 
     this->a = a; 
     static_cast<B*>(this)->setA(const_cast<const A*>(a)); 
    } 
    void Func3() { /* do something to D::a */ } 
}; 

有了這個計劃既BD保持獨立,要訪問適當類型指針的對象。如果setAB上或D上用const A*參數調用,則只設置B::a。如果在D上調用了setA且帶有A*,則B::aD::a都已正確設置。這已成爲可能,因爲通過抽象setter後面的成員,您可以將setter重載到參數的常量上。

+0

謝謝,這解決了問題:) – user1353535

3

您必須聲明A*爲const:

class A 
{ 
public: 
    void Func1() const; 
}; 

class B 
{ 
public: 
    const A* a; 
    void Func2() const 
    { 
     // do something with 'a' 
    } 
}; 

void A::Func1() const 
{ 
    B b; 
    b.a = this; 
    b.Func2(); 
} 

A::Func1this指針是常量。

+0

這就解決了這個問題,但是我不能把'a'作爲const,因爲B有其他可以修改'a'的函數。我知道它與我的設計有關,可以建議一個更好的設計。 – user1353535

1

Func2可能不會更改this,但b.a不是const,您可以隨意在之後進行更改。沒有正確的方法來做到這一點,雖然存在解決方法,例如mutableconst_cast

這是錯誤設計的標誌。

1

是,使A *常數:

class B { 
public: 
    const A *a 

... 
};