我有只包含資料的結構,一個最小的例子是
struct A{
int a;
};
struct B{
int a;
int b;
};
使用這兩個結構后,我現在意識到 A 始終應該是 B 的子集。因此,我想將兩個結構耦合在一起,因此 A 的任何變化都會反映在 B 中。
最明顯的方法是使用繼承,所以只需
struct B: public A{
int b;
};
但是,我不希望任何意外的物件切片,所以我也希望 B 不可見子型別 A。基本上,我不希望用戶知道 B 擴展了 A,它應該作為實作細節隱藏。
我知道標準是“優先組合而不是繼承”,但這會使訪問 B 的欄位就像“B.inner.a”,出于各種原因我并不真正想要。就像我之前所說的,我希望 B 是 A 的超集的知識成為實作細節。
到目前為止,我所知道的關于 C 繼承的唯一事情是它可以是公共的、受保護的或私有的,但這些修飾符在這里都沒有幫助我。有任何語言功能或標準做法可以幫助我嗎?
uj5u.com熱心網友回復:
如果目標是防止物件切片,則顯式洗掉適當的建構式和賦值運算子就足夠了。
struct B;
struct A{
int a=0;
A();
A(const B &)=delete;
A &operator=(const B &)=delete;
};
struct B : A {
int b=0;
};
B b1, b2;
A a1, a2;
void foo()
{
b1=b2; // Ok.
a1=a2; // Ok.
a1=b1; // Error.
B b3{b2}; // Ok.
A a3{a2}; // Ok.
A b4{b1}; // Error
}
唯一的缺點是失去了方便的聚合初始化,這需要使用顯式建構式進行補救。
uj5u.com熱心網友回復:
您可以使用私有繼承,然后A::a公開:
struct B : private A {
using A::a;
int b;
};
(添加了適當的建構式,因為B{1, 2}沒有它將不再作業)
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/519736.html
標籤:C 遗产子类型化
上一篇:解決缺少列舉繼承的問題
下一篇:關于繼承的問題-“型別不是基類”
