鑑於這種人爲的例子:C++成員函數鏈接返回類型和派生類
struct point_2d {
point_2d& x(int n) {
x_ = n;
return *this;
}
point_2d& y(int n) {
y_ = n;
return *this;
}
int x_, y_;
};
struct point_3d : point_2d {
point_3d& z(int n) {
z_ = n;
return *this;
}
int z_;
};
int main() {
point_3d p;
p.x(0).y(0).z(0); // error: "point_2d" has no member named "z"
return 0;
}
的想法是使用「成員函數鏈」,以便能夠調用多個成員函數在一排。 (有很多這樣的例子,上面是我能想到的最短的一個,用於提出這個問題,我的實際問題是類似的,下面會有描述。)
問題是如果派生類增加它自己的鏈接成員函數,但是你首先調用一個基類的成員函數,你會得到一個基類引用,當然這對於調用派生類的成員函數來說是無效的。
有沒有什麼聰明的方法來解決這個問題,仍然保持成員函數鏈接的能力?
企業的實際問題
我實際問題是,我的基類是個例外,我的派生類是從基本異常派生的類。對於這些類也,我想使用成員函數鏈接:
class base_exception : public std::exception {
// ...
base_exception& set_something(int some_param) {
// ...
return *this;
}
};
class derived_exception : public base_exception {
// ...
};
int main() {
try {
// ...
if (disaster)
throw derived_exception(required_arg1, required_arg2)
.set_something(optional_param);
}
catch (derived_exception const &e) {
// terminate called after throwing an instance of 'base_exception'
}
}
的問題是,set_something()
回報base_exception
但catch
期望一個derived_exception
。當然,一個人類可以告訴,異常的實際類型是derived_exception
,但編譯器顯然不能說。
這就是我真正想要解決的問題,即如何讓基本異常類能夠在異常對象上設置可選參數,然後返回派生類型的實例。上面給出的point_2d
例子是(我相信)人們理解的同一個問題的一個更小和更簡單的版本,並且小問題的解決方案也將解決我的實際問題。
請注意,我沒有考慮做base_exception
模板,並在派生類傳似:
template<class Derived>
class base_exception {
// ...
Derived& set_something(int some_param) {
// ...
return *this;
}
};
我相信事實並解決問題,但它不是一個完美的解決方案,因爲如果其他類more_derived_exception
導出從derived_exception
,那麼我們又回到了同樣的問題。
的`base_exception <類派生>你有你的問題的最後是被稱爲奇異遞歸模板模式(CRTP)`想法。我認爲它不會爲您的情況提供解決方案,因爲您的異常層次結構中無法使用單個根基類。 – 2011-02-16 17:43:14
@艾米爾:是的,我說這不是一個完美的解決方案,爲什麼。 – 2011-02-16 17:54:44
我只是指出,爲了其他讀者的利益,你顯示的模式有一個特定的名稱。我還給出了另一個原因,爲什麼(不同於你的)解決方案不起作用。我不打算批評你。 :-) – 2011-02-16 19:46:17