2017-08-12 33 views
1

看下面的代碼,我很困惑爲什麼我們需要getter和setter?爲什麼我們需要getter和setter如果構造函數和析構函數可以獲取並顯示(打印)數據?

#include<iostream> 
    #include<cstring> 
    using namespace std; 
    class car 
    { 
     char name[30]; 
     int price; 
    public: 
     void get_data(char* n,int p) 
     { 
      strcpy(name,n); 
      price=p; 

     } 
     void set_data() 
     { 
      cout<<"Name: "<<name<<endl; 
      cout<<"Price:"<<price<<endl; 
     } 
     ///Lets add the idea of constructor 
     car() 
     { 
      cout<<"constructor has been called"<<endl; 
     } 
     car(char *n, int p) 
     { 
      cout<<"2nd constructor has been called"<<endl; 
      strcpy(name,n); 
      price=p; 
     } 
     ~car() 
     { 
      cout<<"Name: "<<name<<endl; 
      cout<<"Price:"<<price<<endl; 
     } 

    }; 
    int main() 
    { 
     car A("BMW",1000); 

     car B("Audi",2000); 


    } 

我在問爲什麼我們需要getter和setter如果構造函數可以設置值並打印值? 爲什麼有getter和setter的想法?

+0

目前正在形成解釋getter/setter函數重要性的答案。請保留 – shockawave123

+0

爲什麼我們可以說二進制時需要一種語言? –

回答

0

確實,構造函數可以設置類的變量的值。但是,這隻能在每個對象的生命週期中發生一次,因爲只有在實例化對象時才調用構造器。如果用戶想在程序中稍後更改變量的值,該怎麼辦?這是制定者的目的。 setter允許更改類中的變量。您還希望getter在程序運行期間的任何時候訪問該變量。

至於析構函數,通常保留用於垃圾回收,不應該用於獲取和設置變量。

-1
  1. 您的get_data不讓用戶獲取數據,而是設置對象的數據。更好的命名是getName(),setName(char * n)和getPrice()和setPrice(int p)。
  2. 考慮重載您的構造函數,現在您想對代碼進行一些更改,如價格不能爲負值或名稱不能爲空。
  3. 更好的編碼風格將是:

    級車 { 焦炭名[30]。 int price; public: void setName(char * n) { if(n == NULL)n =「」; strcpy(name,n);現在

    } 
        void setPrice(int p) 
        { 
          if(p <0) p = 0; 
          price = p; 
        } 
        int getPrice() 
        { 
          return price; 
        } 
        char * getName() 
        { 
           return name; 
        } 
    
        ///Lets add the idea of constructor with default values 
        car() 
        { 
         cout<<"constructor has been called"<<endl; 
         setPrice(0); 
         setName(""): 
    
        } 
        car(char *n, int p) 
        { 
         cout<<"2nd constructor has been called"<<endl; 
         setName(n); 
         setPrice(p); 
        } 
        ~car() 
        { 
         cout<<"Name: "<<name<<endl; 
         cout<<"Price:"<<price<<endl; 
        } 
    
    }; 
    
  4. 如果價格已經得到了更多的驗證,所有將被添加到剛剛一個功能setPrice而不是在每個構造不同。同樣的名稱也是如此。

  5. 您的set_data只寫入cout。如果以後你想輸出到文件呢?所以最好有getPrice()並在main中使用它來寫入cout。
1

你說得對,getters和setters通常是非常糟糕的想法,表明你的類的抽象被破壞/不存在。但你強調的原因並不是真的。

你需要仔細考慮每個班級應該做什麼。目標是每個班級都應該完成一件事,然後他們應該可以組合。這使您可以更輕鬆地製作新功能並維護現有代碼。

例如,您的汽車類不是很好,因爲它不允許我有汽車,我不想隨機打印內容。這真的是兩個類 - 一個Car類和一個RandomlyPrintingContentsCar。

但是再一次,Car類並不是真正的類。沒有什麼,它真的確實。這只是兩個領域的方便聚合。而且隨着一堆蹩腳的C字符串和緩衝區溢出,即使將其描述爲方便也過於慷慨。

類很有用,因爲它們可以有抽象接口,允許您隱藏其數據成員的狀態。這幾乎直接排除了爲所有東西提供getter和setter,因爲沒有任何東西是隱藏的。不提供getter(或者更常見的是setter)是一個非常強大的工具,也是使用類的一個要點。

相關問題