[英]How to call a non-const method from a const method?
我的類中有一個 const 方法,它不能更改為非常量。 在這種方法中,我需要調用一個非常量方法,但編譯器不允許我這樣做。
有什么辦法可以解決嗎? 這是我的代碼的簡化示例:
int SomeClass::someMethod() const {
QColor saveColor = color();
setColor(QColor(255,255,255)); // Calling non-const method
// ....
setColor(saveColor); // restore color
return 1;
}
你可以在this
指針上使用const_cast
,
int SomeClass::someMethod() const {
const_cast<SomeClass*>( this )->setColor(...);// Calling non-const method
//whatever
}
但是如果你對一個最初聲明為const
的對象這樣做,你會遇到未定義的行為。
所以這:
SomeClass object;
object.someMethod();
沒關系,但是這個:
const SomeClass object;
object.someMethod();
產生未定義的行為。
真正的解決方案是您的const
函數首先不應該是const
。
如果您需要更改const
方法內的某些內部狀態,您還可以聲明受影響的狀態mutable
:
class Foo {
public:
void doStuff() const { bar = 5; }
private:
mutable int bar;
};
這適用於您將互斥鎖之類的東西作為類成員的情況。 獲取和釋放互斥鎖不會影響客戶端可見的狀態,但在const
方法中在技術上是禁止的。 解決方案是將互斥鎖標記為mutable
。 您的情況看起來很相似,但我認為您的課程需要進行一些重構才能使此解決方案適用。
此外,您可能想閱讀此答案以了解如何使用 RAII 使此臨時狀態更改異常安全。
做const
正確性的挑戰之一是你不能半途而廢。 要么全有,要么全無。 如果你嘗試半途而廢,你最終會陷入困境,就像你在這里一樣。 你最終會得到一個不錯的const
-correct 類,它被一些瘋狂的舊的、典型的遺留(或由一個舊的脾氣暴躁的人編寫)代碼使用,這些代碼不是const
正確的,它只是不起作用。 你會想知道const
正確性是否值得所有的麻煩。
I need to call a non-const method [from a const method]
你不能——不能直接。 你也不應該。 但是,還有一種替代方法......
顯然,你不能調用非const
從方法const
方法。 否則,當應用於成員函數時, const
將毫無意義。
const
成員函數可以更改標記為mutable
成員變量,但您已經指出這在您的情況下是不可能的。
您可以嘗試通過執行SomeClass* me = const_cast<SomeClass*>(this);
類的操作來擺脫const
性SomeClass* me = const_cast<SomeClass*>(this);
但是 A) 這通常會導致 UB,或 2) 它違反了const
正確性的整個想法。
如果您真正想要完成的事情支持這一點,您可以做的一件事是創建一個非const
代理對象,並使用它執行非const
-y 的事情。 以機智:
#include <iostream>
#include <string>
using namespace std;
class Gizmo
{
public:
Gizmo() : n_(42) {};
void Foo() const;
void Bar() { cout << "Bar() : " << n_ << "\n"; }
void SetN(int n) { n_ = n; };
int GetN() const { return n_; }
private:
int n_;
};
void Gizmo::Foo() const
{
// we want to do non-const'y things, so create a proxy...
Gizmo proxy(*this);
int save_n = proxy.GetN();
proxy.SetN(save_n + 1);
proxy.Bar();
proxy.SetN(save_n);
}
int main()
{
Gizmo gizmo;
gizmo.Foo();
}
如何從 const 方法調用非常量方法?
你不應該。 如果您使用const_cast
拋棄this
的常量性,您可能會遇到未定義的行為。 const_cast
的使用會使編譯器閉嘴,但這不是解決方案。 如果你需要這樣做,那么這意味着 const 函數首先不應該是const
。 使它成為非常量。
或者,您應該做一些其他事情,這不需要您從const
函數調用非常量函數。 比如,不要調用setColor
函數? 比如,將 const 函數拆分為多個函數(如果可以的話)? 或者是其他東西?
在您的特定情況下,如果setColor
僅設置一些成員變量,例如m_color
,那么您可以將其聲明為mutable
:
mutable QColor m_color;
然后在您的 const 函數中設置它,而不調用setColor
函數,也不執行const_cast
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.