2016-04-04 45 views
1

在Python3中,我有一個類Resistor與方法series(self, other),返回一個新的Resistor實例與阻力等於自我和其他系列電阻。將Python翻譯爲C++,從成員函數返回新實例是否正確?

class Resistor(object): 
# a class to model a resistor 
    def __init__(self, res=0) : 
     # default is "typical" value 
     self.resistance = res 
     return 
    def series(self, other) : 
    # Returns a Resistor object with resistance equal to self + other 
     sum = self.resistance + other.resistance 
     return Resistor(sum) 

由於變量是對象的引用,所以這個工作原理似乎是Python中的一個習慣用法。類比是Python字符串連接,其中操作newstr = str1 + str2產生新的字符串對象newstr

如果我字面翻譯爲C++,這個工程:

class Resistor 
{ 
    public: 
    // data members 
    double resistance; 

    // member functions 
    Resistor(double res = 1000.0); 
    Resistor series(Resistor other); 
}; 

Resistor::Resistor(double res) 
{ 
    resistance = res; 
} 

Resistor Resistor::series(Resistor other) 
{ 
    Resistor r = Resistor(resistance + other.resistance); 
    return r; 
} 

最後我的問題......我是安全的這個直譯?當局部變量r超出範圍時,新的Resistor實例會發生什麼?我是否創建了內存泄漏?我應該使用指針(我從C中知道是詭計多端)?

在此先感謝

+0

快速提示。使用'sum'會陰影內置的總和。你應該改變那些不會衝突的東西。 – idjaw

+0

好點,謝謝。 –

回答

2

您不會創建內存泄漏,因爲Resistor::series函數將在返回時創建Resistor對象的副本,並將銷燬現有對象(除非您的情況最有可能發生的編譯器優化)。

如果這個類很大/足夠複雜,那麼在每次調用時拷貝肯定是低效的。然而,你的班級唯一有一個double字段(取決於拱形)可能與指針大小相同。所以(即使複製優化不會啓動)切換到指針可能不會給你任何東西,除了潛在的內存泄漏。恰恰相反,哈? :)

但是,如果類實際上更大,那麼你應該考慮使用指針。在大對象周圍進行復制(最終會發生)並不是你想要的。但是到底發生了什麼?這是一個非常微妙的問題,你不會得到直接的答案。你可以嘗試不同的方式,並做一些測試來確保。

附註:通過值將參數傳遞給函數也會複製它。但不像前一種情況,這次編譯器不是允許優化它,除非它是暫時的。因此請考慮傳遞參考文獻:

Resistor series(Resistor &other); 
+0

我同意旁註,如果我開發該類以更好地表示真實世界的電阻(容差,額定功率,色帶等)(即更復雜),那麼只發送參考/指針來回。我對C++中的指針和引用不夠滿意 - 也許Python讓我陷入了虛假的安全感。 –

+0

@LouisB。是的,Python在場景中做了很多整潔的東西。最重要的是適當的記憶管理。但你現在也有一些很好的功能,比如現代C++。共享指針等等。不幸的是,難度仍然高於Python。 – freakish

1

這沒什麼錯。此外,如果您有興趣將此代碼真正轉換爲C++風格,而不僅僅是實現直接翻譯,請考慮定義operator+()而不是series()方法。您的方法返回r。局部變量r在變量超出範圍並被銷燬之前被複制到調用方返回值的任何位置。

C++編譯器允許在這裏消除多餘的副本,實際上大多數副本 - 在調用方的上下文中基本上構造r作爲此方法的實際返回值。但你不必擔心這一點。

+0

Re:operator +()...是的,那就是我要去的地方。在Python中,我有'def __add __(self,other):'但我想縮小問題的範圍。謝謝。 –

+0

我建議不要在'Resistor'類中重載'operator +'。電阻器不是數學對象,可以串聯或並聯「添加」,每個產生不同的結果。因此,「運營商+」令人困惑。 –

+0

@ el.pescado好點,但在電子產品中,+爲系列保留,而兩個管道||或者兩個斜槓//用於並行。在Python3中很容易做到這一點,因爲我需要做的只是過載(更像是劫持)地板分割操作員//。 –