簡體   English   中英

在C ++中為尖頭數據強制執行const?

[英]Enforce constness for pointed data in C++?

讓我們有一個帶有一些const和非const方法的Foo

struct Foo
{
    Foo ();
    ~Foo();

    void noSideEffect() const;
    void withSideEffect();

};

我也有一個Bar類,需要以某種方式引用Foo 更確切地說,對於這個問題可能過於精確,Bar實現了運算符|| &&為聯合和交叉,所以兩個Bar實例需要知道他們正在使用同一個Foo實例

我發現最簡單的解決方案是使用指向Foo對象的指針:

struct Bar
{

   Foo * p_foo;

   Bar (Foo& foo)
     : p_foo(&foo) {};

}

現在兩個bar實例可以一起播放,看看它們是否都處理相同的Foo。 我快樂了。

但現在我想有時使用帶有const Foo實例的Bar。 好吧,它可能很容易,我只需創建一個const Bar實例,對吧? 我們去:

const Bar createBarFromConstFoo(const Foo& foo)
{
   Foo* newfoo = const_cast<Foo*>(&foo);
   const Bar newbar (*newfoo);
   return newbar;
}

現在噩夢開始了(請參閱為什么C ++不對指針數據強制執行const? )。 我想我理解為什么 (標准是這樣說的),我的主要問題是如何最好地應對它。

除了這個小標准的東西,createBarFomConstFoo幾乎完成了我想要的東西,因為它返回了一個const Bar 有沒有辦法阻止const Bar使用我的(最初) const Foo (即只調用Foo的const方法)做一些討厭的事情,同時允許非const Bar執行所有操作?

也許沒有辦法做到這一點,這是一個對象設計問題,但我沒有看到一個簡單的替代方案。

編輯:對於downvoters,你能否解釋一下原因,我可以從你的言論中取得進展......

編輯2 :也許混淆真正的類恐懼Foo和Bar是一個壞主意,我只是想簡化一些事情。

所以Foo實際上是一種分子(實際上是一種蛋白質),它含有Atoms(許多是蛋白質)。 能夠選擇一些原子是創建Bar的原因,Bar是SelectionOfAtoms

有時候從所有氫和氧原子中選擇都是方便的,因此Bar實現了聯合和交叉。 我希望能夠提取這些原子,以便SelectionOfAtoms從所選原子實現createNewMolecule()方法。 因此,它需要一種方法來引用原始分子(也許某種副本會在這里做,但可能不符合下面的其他要求)。

但我最近覺得需要修改選擇的原子,同時保持其他原子不被修改。 通過SelectionOfAtoms(Bar)這么做是很方便的:它已經知道在哪里找到原子(使用指針)和這些原子的索引(內部實現細節),所以改變原子所需的一切幾乎已經在這里,除了我可以要么只在Molecule上使用Selection(非const),要么在const Molecule上工作,忘記修改它們或進入const_cast恐怖。

我敢肯定這是一個非常糟糕的設計,但它已經存在,它肯定會得到很多改進。

使用STL作為指導,將您的分子視為容器,並將您的選擇視為迭代器或迭代器范圍。

現在,在這個方案中,你有const和非const選擇/迭代器的單獨類型 ,這是有道理的,因為它們具有不同的語義。 使constness成為模板參數可能是一種虛假的經濟,除非選擇中的代碼比你建議的多得多。

現在,你從const或非const molecule ,你靜靜地知道你得到了一個const_selection或(非const) selection

Bar不是太復雜,你可以把它變成一個類模板。

template <typename FooType>
struct Bar
{

   FooType * p_foo;

   Bar (FooType& foo)
     : p_foo(&foo) {};

}

template <typename FooType>
Bar<FooType> makeBar(FooType& foo)
{
   return Bar<FooType>(foo);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM