2011-10-21 42 views
1

我剛開始自己​​的Windows API封裝,並且在重寫包含C++特性的結構時遇到了陌生的主題。使數據成員無處不在,但只讀

我把這個:

typedef struct _RECT { 
    LONG left; 
    LONG top; 
    LONG right; 
    LONG bottom; 
} RECT, *PRECT; 

#define RECT_POS 1 
#define RECT_SIZE 2 

typedef struct WrapperRect // RECT 
{ 
    WrapperRect(); // all 0 
    WrapperRect (const double, const double, const double, const double, bool = RECT_POS); // initalize with tl pos and either br pos or size 

    bool set (const double, const double, const double, const double, bool = RECT_POS); // set tl pos and either br pos or size 
    bool pos (const double, const double); // set tl pos 
    bool size (const double, const double); // set size 

    WrapperRect & operator= (const WrapperRect &); // assign another rect 
    bool operator== (const WrapperRect &); // check for equality (pos+size) 
    bool operator!= (const WrapperRect &); // check for inequality (pos+size) 
    bool operator> (const WrapperRect &); // check for tl pos greater 
    bool operator< (const WrapperRect &); // check for tl pos less 
    bool operator>= (const WrapperRect &); // check for tl pos greater equal 
    bool operator<= (const WrapperRect &); // check for tl pos less equal 
    WrapperRect & operator+ (const POINT &); // move down/right 
    WrapperRect & operator- (const POINT &); // move up/left 
    WrapperRect & operator+= (const POINT &); // move down/right 
    WrapperRect & operator-= (const POINT &); // move up/left 

    double l, left, x; // left 
    double r, right; // right 
    double t, top, y; // top 
    double b, bottom; // bottom 

    double w, width; // width 
    double h, height; // height 
} Rect, rect; // allow more convenient names 

我唯一的問題是,如果用戶說

Rect myRect; 
myRect.right = 50; 

它將設置在右側,但無法更改右側或寬度的別名。

我不想成員是私有的或者是因爲我想

cout << myRect.x; 

語法,而不是惱人

cout << myRect.getX(); 

語法。
有什麼辦法可以達到這個目的,還是我必須使用get函數?我真的沒有想到,當我寫這個,我已經添加了一些返回值(>。>),並將運算符+等中的雙改爲一個點。在接受之前,我開始嘗試各種可能性。

回答

1

暴露數據成員是非常糟糕的做法。在課堂中同時存在多份完全相同的信息也是非常糟糕的做法。它既低效又容易出錯。

你一定需要使用存取函數。

這就是說,你不需要getX(); - 只要x()就可以了。

如果你真的就避免函數語法設置,這樣的事情會確定我想:

struct Rect 
{ 
private: 
    double l, r, t, b; 

public: 
    const double &x, &y; 

    Rect() : x(r), y(t) {} 

    ...etc. 
}; 

然後,你可以在一個安全的方式使用r.x雖然你還是有點暴露你的執行。

+0

在定義語句出現一個愚蠢的錯誤後,我終於得到它的編譯,它工作得很好,謝謝。不要擔心這裏的不良做法;我只是將它用於我自己的小程序開發。 – chris

+0

值得一提的是,暴露的const引用可以用const_cast讀寫。 – jvstech

+0

同樣值得注意的是,它們應該是'const volatile'。如果沒有volatile,你的編譯器可能會在一些其他的寫入操作之前移動「讀取x」,否則邏輯上它會以相反的順序出現。 – Daniel

0

您應該使用get函數。你不需要你聲稱你想要的語法。

例如,假設您稍後更改函數以將x和它們的y值一起編碼爲一些複雜的結構。你將如何讓myRect.x工作呢?

說取回x的價值是很少見的。所以你不想計算它,除非你必須。你將如何讓myRect.x工作呢?

說在將來的某個時刻,您需要計算已訪問x的次數。你將如何讓myRec.x工作呢?

使用獲取函數,以便您不強制只想獲取x的值的代碼瞭解它如何存儲在類中。

0

你可以使用一個常量指針。 const double * xPtr;然後在構造函數中初始化它:xPtr = &x這會創建一個指向x的指針,該指針不能用於修改x。你肯定需要一個setter函數,但是要改變它自己的值x

正如已經指出的那樣,這是不好的做法,你最好使用帶有私有成員,存取類等

const指針類型參考這裏:

http://www.codeguru.com/cpp/cpp/cpp_mfc/general/article.php/c6967

0

這可能不會贏得我很多編碼的榮譽「,但我實際上並不認爲它是這樣的直接訪問成員的不良風格,當你創建非常像ac結構,主要負責存儲數據和不負責任爲更高智力水平。所以回答你的問題是使用工會

struct rect 
{ 
    union 
    { 
     double width; 
     double w; 
    }; 

    union 
    { 
     double height; 
     double h; 
    }; 
} 

當你做到這一點,然後訪問H和訪問的高度實際上是在內存訪問相同的位置。

相關問題