2015-06-24 93 views
2

例如,如果我定義了一個點對象(2,3),然後使用默認的構造函數來聲明另一個會導致點對象(2,3)的點。然後,如果我要創建另一個點對象(5,6),則默認構造函數將更改爲生成點對象(5,6)。這裏是我的嘗試:如何定義一個創建前一個對象的默認構造函數

point.h

#ifndef POINT_H 
#define POINT_H 

int point::previousX = 0; 
int point::previousY = 0; 

int defualtX = previousX; 
int defualtY = previousY; 

struct point{ 
    point(int newX = defualtX, int newY = defualtY) 
    : x(previousX = newX), y(previousY = newY){;}; 
    ~point(void){;}; 
    static int previousX; 
    static int previousY; 
    int x, y; 
}; 

#endif//POINT_H 

有這碼一個明顯的問題。在「先前」和「不確定」變量之前沒有定義類別點;因此,previousX和previousY的定義將不起作用。我可以在類定義下面移動「defualt」和「previous」變量,但是這個point構造函數不起作用。

+0

將'int point :: previousX = 0;'和'int point :: previousY = 0;'移入單獨的翻譯單元或在類聲明中初始化它們。 –

+1

可怕的解決方案,與這種方法找到錯誤運氣好。 – Slava

+0

聽起來有點像XY-問題,爲什麼你想這樣做? – WorldSEnder

回答

2

在「previous」和「default」變量之前沒有定義類別點;因此,previousXpreviousY定義將無法正常工作

它不會反正工作,因爲你放置定義成一個頭文件。這是不正確的:定義必須放置在cpp文件中,以避免鏈接過程中出現雙重定義的錯誤。

將定義移入cpp文件將修復第一個編譯問題,但第二個問題仍然存在:您不能使用defaultXdefaultY變量作爲代碼中顯示的默認參數值,因爲即使您可以複製previousXpreviousY分成defaultXdefaultY,這將是一次性副本;所有對point構造函數的調用都將使用零值,並在初始化時複製到defaultXdefaultY

您可以通過添加兩個構造解決這個 - 不帶任何參數,並用一個參數,像這樣:

​​

Demo.

注:我會強烈建議不要使用的解決方案它依靠static變量的值進行初始化,因爲它依賴於構造函數的執行順序,並且在併發系統中突然崩潰。

+0

如果不使用靜態成員,你建議我做什麼? – dylan

+0

@dylan通過一些其他的非靜態方法提供對代碼中最後一點的訪問,這些代碼調用沒有參數的構造函數。這最初會使你的系統複雜化,但結果會更可讀。 – dasblinkenlight

+0

@dylan你可以使用獨立功能,不是嗎? (請參閱下面的答案),儘管我也推薦反對它 – WorldSEnder

0

爲什麼不把剛纔的值傳遞給構造函數?

#ifndef POINT_H 
#define POINT_H 

class Point 
{ 
public: 
Point(int newX, int newY) 
{ 
    x = newX; 
    y = newY; 
} 
int getX() {return x;} 
int getY() {return y;} 
~Point(){}; 
private: 
int x, y; 
}; 

#endif//POINT_H 

喜歡的東西Point oldP(3,3)Point newP(old.getX(),old.getY())

+0

,因爲那樣你總是必須能夠訪問'old',這對於許多項目來說當然不成立,儘管OP試圖實現的並不一定是可取的 – WorldSEnder

0

你可以推遲默認初始化成自由站立功能是這樣的:

namespace _detail { 
    int getDefaultX(); 
    int getDefaultY(); 
} 

struct point{ 
    static int previousX; 
    static int previousY; 

    point(int newX = _detail::getDefaultX(), 
      int newY = _detail::getDefaultY()); 
    ~point(); 
    int x, y; 
}; 

// in the .cpp file: 


point::point(int newX, int newY) 
    : x(previousX = newX), y(previousY = newY){;} 
point::~point() {} 

namespace _detail { 
    int getDefaultX() { 
    return point::previousX; 
    } 
    int getDefaultY() { 
    return point::previousY; 
    } 
} 
int point::previousX = 0; 
int point::previousY = 0; 
+0

現在,如果您在創建任何其他點之前使用defualt構造函數,您將得到一個隨機點而不是(0,0)。這是正確的嗎? – dylan

+0

哦,是的,忘了初始化'point :: previousX'和'point :: previousY',修正了 – WorldSEnder

0

剛剛宣佈以正確的順序:

struct point{ 
    point(int newX = previousX, int newY = previousY) 
    : x(previousX = newX), y(previousY = newY){} 

    void print() const { std::cout << x << ", " << y << std::endl; } 

    static int previousX; 
    static int previousY; 
    int x, y; 
}; 

Live Demo

相關問題