2

See below code, I am confused why do we need getter and 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);


    }

I am asking why do we need getter and setter if Constructor can set the value and print the value? Why the idea of getter and setter?

3 Answers3

1

You're right that getters and setters are typically pretty bad ideas which indicate that your class's abstraction is broken/nonexistent. But the reason you've highlighted isn't really it.

You need to think carefully about exactly what each class is supposed to do. The objective is that each class should do one and exactly one thing, and then they should be combinable. This allows you to make new features and maintain your existing code much more easily.

For instance, your car class is not very good, because it doesn't allow me to have cars where I don't want to randomly print the contents. This is really two classes- a Car class, and a RandomlyPrintingContentsCar.

But then again, the Car class is not really a class at all. There's nothing that it really does. It's just a convenient aggregation of two fields. And with a bunch of crappy C strings and buffer overflows, even describing it as convenient is being too generous.

Classes are useful because they can have abstract interfaces that allow you to hide the states of their data members. This pretty much directly excludes just offering getters and setters for everything because then nothing is hidden. Not offering a getter (or much more commonly, a setter) is an extremely powerful tool and one of the main points of using a class.

Puppy
  • 144,682
  • 38
  • 256
  • 465
0

It is true that constructors can set the value of the class's variables. However, this can only happen once per object's lifetime since the constructor is only called when the object is instantiated. What if the user wants to change the value of the variable later on in the program? That's what the setter is for. The setter allows the variables in a class to be altered. You would also want a getter to access the variable at any point during the program's runtime.

As for destructors, those are usually reserved for garbage collection and shouldn't be used for getting and setting variables.

Devin L.
  • 437
  • 2
  • 12
-1
  1. Your get_data is not letting the user get the data but rather it is setting the data of the object. Better naming would be getName(), setName(char *n) and getPrice() and setPrice(int p).
  2. consider overloading your constructor and now you want to make some changes to your code like price can not be negative or name can not be null.
  3. Better coding style will be:

    class car { char name[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. Now if price has got more validations, all will be added to just one function setPrice and not in each constructor differently. Same for name as well.

  5. Your set_data writes only to cout. what if later you want output to a file? So better to have getPrice() and use it in main to write to cout.