C ++: Использование указателей в качестве закрытых переменных-членов без нарушения инкапсуляции? - PullRequest
0 голосов
/ 29 ноября 2018

У меня есть класс Film, который содержит целочисленный указатель Chapitres и количество элементов этого массива Count_chapitres.

 class film : public video
{
private:
    int* Chapitres;
    unsigned int Count_chapitres;
public:
    film();
    film(int* Chapitres, unsigned int Count_Chapitres, int Duree, string Name, string Filename);
    virtual ~film();
    void setChapitres (int * Chapitres, unsigned int Count_Chapitres);
    int * getChapitres() const;
    unsigned int getCountChapitres() const;
    void printOut (ostream & Display) const;

};

Очевидная проблема заключается в том, что выдача указателя нарушит инкапсуляцию.

1) Я попытался установить выход get для const int *, в котором просто приведение результата обратно с использованием const_cast вернуло меру назад.Так как указатель Зла позволил внешнему изменению данных фильма внешне:

film* file2 = new film(Chaps, 3, 5, "hany", "daher");

    file2->printOut(cout);
    int * Evil = const_cast<int *>(file2->getChapitres());
    *(Evil +1)=9;
    file2->printOut(cout);

2) Кроме того, даже несмотря на то, что в качестве аргументов для моего конструктора / установщика я указал const int *, он по-прежнему принимает объекты int * в качестве аргументов в основном процессе создания.ключевое слово const существенно избыточно.

Решение, очевидно, не заключается в указателях на постоянные значения.Есть идеи, как поступить?

1 Ответ

0 голосов
/ 29 ноября 2018

Вы должны понимать, что инкапсуляция - это защита, как в «защитном переключателе оружия», а не в «сильной криптографии».Вам не следует беспокоиться о возможности того, что пользователи класса будут делать const_cast с возвращенным const pointer, больше, чем вы должны беспокоиться о том, что они наберут что-то вроде #define private public перед включением вашего класса заголовка.

В C ++ есть неограниченные возможностиза умышленное нарушение вашей инкапсуляции, как с внешним поведением, так и без него.Вместо этого инкапсуляция пытается защитить пользователей класса от невинных ошибок.

В вашем конкретном случае вам необходимо сопоставить вашу функцию получения и вернуть const int*.Кроме того, поскольку у вас уже есть тривиальные геттеры и сеттеры, вы можете покончить с ними и просто объявить своих участников публичными с одинаковым уровнем инкапсуляции.

...