2010-03-19 21 views
2

我最近重構的代碼是這樣的(MyClassMyClassR)。重載函數調用一個參數,但我想我已經通過了兩個

#include <iostream> 

class SomeMember 
{ 
public: 
    double m_value; 

    SomeMember() : m_value(0) {} 
    SomeMember(int a) : m_value(a) {} 
    SomeMember(int a, int b) 
    : m_value(static_cast<double>(a)/3.14159 + 
      static_cast<double>(b)/2.71828) 
    {} 
}; 


class MyClass 
{ 
public: 
SomeMember m_first, m_second, m_third; 

MyClass(const bool isUp, const int x, const int y) 
{ 
    if (isUp) 
    { 
    m_first = SomeMember(x); 
    m_second = SomeMember(y); 
    m_third = SomeMember(x, y); 
    } 
    else 
    { 
    m_first = SomeMember(y); 
    m_second = SomeMember(x); 
    m_third = SomeMember(y, x); 
    } 
} 
}; 


class MyClassR 
{ 
public: 
SomeMember m_first, m_second, m_third; 

MyClassR(const bool isUp, const int x, const int y) 
: m_first(isUp ? x : y) 
, m_second(isUp ? y : x) 
, m_third(isUp ? x, y : y, x) 
{ 
} 
}; 


int main() 
{ 
    MyClass a(true, 1, 2); 
    MyClassR b(true, 1, 2); 

    using namespace std; 
    cout.precision(10); 
    cout 
     << "a:" << endl 
     << "\tfirst: " << a.m_first.m_value 
     << "\tsecond: " << a.m_second.m_value 
     << "\tthird: " << a.m_third.m_value << endl; 

    cout 
     << "b:" << endl 
     << "\tfirst: " << b.m_first.m_value 
     << "\tsecond: " << b.m_second.m_value 
     << "\tthird: " << b.m_third.m_value << endl; 

    return 0; 
} 
  • 什麼是錯誤,
  • 爲什麼它編譯(用VC6 以及VC9警告級別4測試:無投訴)和
  • 是什麼做的正確方法?

我(假設)我已經有了所有這些答案,但我認爲這是分享的有趣和有趣的問題。

更新
擴展代碼,因此它的 「複製粘貼& &執行」 -able。 VC9也沒給我投訴,所以這裏VC6不是問題。
爲了完整起見,輸出爲:

a: 
     first: 1  second: 2  third: 1.054069532 
b: 
     first: 1  second: 2  third: 1.004499999 
+0

我看不到任何錯誤原因。它絕對精細並編譯,按預期執行 – mukeshkumar

+0

人工,修辭問題。建議關閉它。 – Suma

+0

@Suma由於簡化,代碼是人造的。這個問題真的發生了...... – foraidt

回答

8

我不知道究竟你所期望的,但讓我們開始...

  • 首先,溝VC6。 嚴重。使用它是一個巨大的問題,因爲它只是不符合標準,並排除了很多選項。正確使用就像玩俄羅斯輪盤賭一樣。

  • 你的構造函數m_third不會做你認爲它的作用。你不能寫這樣的條件表達式:「幾個參數」在C++中不是有效的表達式,條件運算符對錶達式有效。

  • 該代碼編譯,因爲它仍然正確,它只是沒有做你想做的。而不是使用「幾個參數」的,它會評估序列點運算符(,),它只是需要表達的最後價值,所以你的條件實際上等同於:isUp ? y : x

  • 正確的方法是使用2個條件句:m_third(isUp ? x : y, isUp ? y : x)

  • SomeMember第三個構造函數是錯誤的,該值可能會溢出,產生負值 - 我高度懷疑,這就是你想要的。

+0

(1)不幸的是,VC6不是我的選擇。(2)SomeMember類只是提供一些編譯的代碼。我想到溢出問題,並使m_value長而不是int,所以我認爲,任何2個整數都適合在那裏,不是嗎? – foraidt

+7

請風暴進入強迫你使用VC6的人居住的房間,並向他們扔椅子。爲了我。您可以選擇爲其他SO成員添加其他椅子。我建議確保椅子的腿部對準頭部以達到最大的疼痛。 – GManNickG

+1

有人可能會拋出一些括號或東西,以清楚發生什麼事情發生在哪裏?我*認爲*我明白代碼做了什麼,並閱讀這個答案我*仍然*認爲我明白代碼的作用,但我顯然是錯誤的。 –

2
m_third(isUp ? x, y : y, x) 

這看起來不對的。第一個x是一個沒有意義的表達,因爲它沒有副作用並且結果沒有被使用,所以:的兩邊具有相同的值和副作用,所以?:可以被消除,因爲?也沒有副作用。

m_third(y, x) 

但是,現在它不會做什麼原始代碼...這是錯誤嗎?

+0

在對已刪除答案的評論中,你說明了「一個逗號表達式不是一個有效表達式的最終子表達式」。爲什麼不是這樣? –

+0

@dribeas:他們的語法規則!條件表達式的最後一位必須是賦值表達式,這比_expression_更具限制性。這意味着第二種方式結束條件表達式後的逗號必須被解釋爲其他內容的一部分。在這種情況下,_expression-list_是成員初始值設定項。您可以在逗號表達式周圍放置括號將其轉換爲主表達式,這將成爲條件表達式的有效最後部分。 –

+0

是的,這是錯誤。原始代碼('MyClass')根據'isUp'標誌調用'SomeMember(x,y)'或'SomeMember(y,x)'。重構代碼('MyClassR')的目的是做同樣的事情,但事實並非如此。 – foraidt

0

什麼是錯誤 這樣做的正確方法是什麼?

我猜你的意圖是要表明某種與三元複合逗號操作的天真使用的?,也許有一些聰明的和意外的運營商優先隱藏的疑難雜症,但我認爲的代碼是完全人造的。如果這是關鍵,那麼比我說的「正確的做法」是不要使用C++或在使用C++之前先學習它。是的,它有很多可能看起來像「怪癖」的構造,並且你可以創建許多編譯器接受的奇怪代碼。通過使用C++,我會說你被認爲知道這些工具。

爲什麼不編譯

因爲它不包含任何錯誤,這是一個正確的C++代碼,無歧義。

相關問題