Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
laucher
0 / 0 / 0
Регистрация: 31.10.2013
Сообщений: 20
#1

Обход инкапсуляции класса - C++

02.11.2013, 13:12. Просмотров 669. Ответов 17
Метки нет (Все метки)

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
 
using namespace std;
 
class My_class {
private:
    char* name;
public:
    My_class() {
        
            name = new char[100];
            cin>>name;
 
    }
    ~My_class() {
        if (name) {
            delete[] name;
        }
    }
    
    const char * getname() {
        return name;
    }
    void show() {
        cout<<name;
    }
};
 
int main() {
    My_class my;
    const char *    k = my.getname();
    char* n = (char* ) k; //  Здесь происходит смена типа с конст на не конст?
    *n = '1';//
    my.show();
    system("pause");
    return 0;
}
Консты я расставлял, так как думал, что это поможет защитить поле класса извне. Как видите, в мейне его изменить получается

Вопрос, как составить здесь грамотную защиту поля извне. Я думал о том, чтобы создавать локальную переменную в функции getname и возвращать её:
C++
1
2
3
4
5
    char * getname() {
        char * temp = new char[strlen(name) +1 ];
        strcpy(temp,name);
        return temp;
    }
Вопрос 1 : Не будет ли здесь утечек памяти? Ведь я выделяю память с помощью new, но у меня нет delete. Или она самоуничтожается при достижении конца функции?
Вопрос 2:
C++
1
2
3
const char *    k = my.getname();
    char* n = (char* ) k; //  Здесь происходит смена типа с конст на не конст?
    *n = '1';//
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.11.2013, 13:12
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Обход инкапсуляции класса (C++):

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

Об инкапсуляции данных в ООП - C++
Добрый день, почти сделал лабу, но нужно устранить замечание. Идея такая, Должен быть класс поставщик, от него делается два подкласса,...

Нарушение инкапсуляции или нет? - C++
В общем экспериментируя с крестами сделал такую штуку и не могу понять это нарушение инкапсуляции или нет? #include &lt;iostream&gt; class...

Понятия инкапсуляции, полиморфизма и наследования - C++
Всем привет. Прошу прояснить для себя 3 основных свойства парадигмы ООП инкапсуляцию, наследования и полиморфизм. Я напишу своё видение и...

Нарушение инкапсуляции или нет? - C++
Есть такой код: class Tune { private: vector&lt;int&gt; A; public: const vector&lt;int&gt;&amp; get_A() const { return A; } // &lt;- не...

Провете класс на предмет ошибок инкапсуляции - C++
Добрый день! Недавно начал изучение ООП C++ и вот настал момент, когда я создал свой первый класс и обьект. Хочу попросить проверить его на...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
lemegeton
2923 / 1352 / 135
Регистрация: 29.11.2010
Сообщений: 2,725
02.11.2013, 13:24 #2
Больше констов, хороших и разных.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <cstring>
 
class Person {
 public:
  Person(const char *name) 
    : name(strcpy(new char[strlen(name) + 1], name)) {}
  // первый конст означает константный указатель,
  // второй конст -- константное значение указателя
  const char * const getName() {
    return name;
  }
 private:
  char *name;
};
 
int main(int, char**) {
  Person john("john");
 
  // Так не выйдет
  //const char *name = john.getName();
  std::cout << john.getName() << std::endl;
  
  return 0;
}
Tulosba
:)
Эксперт С++
4393 / 3236 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
02.11.2013, 13:31 #3
Цитата Сообщение от laucher Посмотреть сообщение
Не будет ли здесь утечек памяти?
Если на new нет соответствующего delete, то утечки будут.
Цитата Сообщение от laucher Посмотреть сообщение
char* n = (char* ) k; // Здесь происходит смена типа с конст на не конст?
Происходит. Приведения в Си-стиле лучше заменить соответствующим _cast'ом
ValeryS
Модератор
6556 / 5022 / 464
Регистрация: 14.02.2011
Сообщений: 16,763
02.11.2013, 13:37 #4
Цитата Сообщение от laucher Посмотреть сообщение
Вопрос 1 : Не будет ли здесь утечек памяти? Ведь я выделяю память с помощью new, но у меня нет delete. Или она самоуничтожается при достижении конца функции?
будет
самоуничтожится указатель на эту память, а память останется
и в другом случае это привело бы к утечке, выделенная память есть а кто указывает на неё нету, значит достучатся не можем
но у тебя этот указатель отдается наружу
Цитата Сообщение от laucher Посмотреть сообщение
return temp;
значит пускай удаляет тот кому мы передали этот указатель
Но при таком подходе нарушается правило "кто выделил тот и удаляет",что может привести к трудноуловимым ошибкам
scenotaph
120 / 120 / 15
Регистрация: 29.03.2013
Сообщений: 237
02.11.2013, 13:47 #5
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <cstring>
 
class Person {
 public:
  Person(const char *name) 
    : name(strcpy(new char[strlen(name) + 1], name)) {}
  // первый конст означает константный указатель,
  // второй конст -- константное значение указателя
  const char * const getName() {
    return name;
  }
 private:
  char *name;
};
 
int main(int, char**) {
  Person john("john");
 
 
  const char *name = john.getName();
  char * n = (char*) name;
  *n = '1';
  std::cout << john.getName() << std::endl;
  
  return 0;
}
Вывод: 1ohn

OhMyGodSoLong
~ Эврика! ~
1243 / 992 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
02.11.2013, 13:55 #6
Цитата Сообщение от laucher Посмотреть сообщение
C++
1
    char*
утечки
std::string
lemegeton
2923 / 1352 / 135
Регистрация: 29.11.2010
Сообщений: 2,725
02.11.2013, 14:02 #7
Пардон, чет я попутался.

Снятие constant value модификатора (приведение к не-консту) ведет к UB -- компилятор сделает так, как захочет. В вашем случае, он хочет допустить такое поведение.
Tulosba
:)
Эксперт С++
4393 / 3236 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
02.11.2013, 16:04 #8
Цитата Сообщение от lemegeton Посмотреть сообщение
Снятие constant value модификатора (приведение к не-консту) ведет к UB
Тут, я думаю, возможны исключения:
1. Если запись не производить, а только снять const, то проблем быть не должно.
2. Если изначальное значение не константа:
C++
1
2
3
    int i = 42;
    const int* c = &i;
    *const_cast<int*>(c) = 100500;
, то тоже всё ОК.
laucher
0 / 0 / 0
Регистрация: 31.10.2013
Сообщений: 20
02.11.2013, 16:57  [ТС] #9
OhMyGodSoLong, Нужно именно char*
Спасибо отписавшимся
ап. Вопрос с грамотной инкапсуляцией остался
Tulosba
:)
Эксперт С++
4393 / 3236 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
02.11.2013, 17:00 #10
laucher, С++ не тот язык, где нельзя насрать в класс, если этого действительно очень хочется. Имеет смысл делать защиту только от случайного изменения данных. Другой защиты быть не может.
OhMyGodSoLong
~ Эврика! ~
1243 / 992 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
02.11.2013, 18:33 #11
Цитата Сообщение от laucher Посмотреть сообщение
Вопрос с грамотной инкапсуляцией остался
Pimpl.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// Person.h
struct PersonData;
 
class Person
{
public:
    Person(const char *name);
 
    const char* getName() const;
 
    // и весь остальной интерфейс
 
private:
    std::unique_ptr<PersonData> m_m;
};
 
 
// Person.cpp
#include "Person.h"
 
struct PersonData
{
    const char *name;
 
    PersonData(const char *name)
      : name(NULL)
    {
        this->name = strdup(name);
    }
    
    ~PersonData()
    {
        free(name);
    }
};
 
Person::Person(const char *name)
  : m_m(new PersonData(name))
{}
 
const char* Person::getName() const
{
    return m_m->name;
}
ct0r
Игогошка!
1770 / 672 / 42
Регистрация: 19.08.2012
Сообщений: 1,284
Завершенные тесты: 1
02.11.2013, 20:06 #12
Цитата Сообщение от lemegeton Посмотреть сообщение
C++
1
//const char *name = john.getName();
А зачем это запрещать?

OhMyGodSoLong, а зачем PersonData торчит наружу и почему можно не писать деструктор Person?
Tulosba
:)
Эксперт С++
4393 / 3236 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
02.11.2013, 20:39 #13
Цитата Сообщение от ct0r Посмотреть сообщение
почему можно не писать деструктор Person?
а зачем он нужен? Удалением PersonData заведует std::unique_ptr.
Цитата Сообщение от ct0r Посмотреть сообщение
а зачем PersonData торчит наружу
В каком смысле?
Dmitriy_M
1342 / 1223 / 112
Регистрация: 20.03.2009
Сообщений: 4,408
Записей в блоге: 11
02.11.2013, 20:53 #14
Цитата Сообщение от OhMyGodSoLong Посмотреть сообщение
Pimpl.
Тут он не поможет.
Цитата Сообщение от laucher Посмотреть сообщение
Вопрос с грамотной инкапсуляцией остался
Возвращать не указатель или ссылку, а объект.
ct0r
Игогошка!
1770 / 672 / 42
Регистрация: 19.08.2012
Сообщений: 1,284
Завершенные тесты: 1
02.11.2013, 21:11 #15
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от Tulosba Посмотреть сообщение
В каком смысле?
Ну в смысле зачем делать имя PersonData видимым извне, если можно обойтись PersonData как вложенным классом?

Цитата Сообщение от Tulosba Посмотреть сообщение
а зачем он нужен? Удалением PersonData заведует std::unique_ptr.
unique_ptr для удаления объекта через delete нужен полный тип. Поэтому по идее нам нужно явно написать деструктор в файле реализации, иначе компилятор не сможет сгенерить деструктор из места, где PersonData не определена.

Добавлено через 9 минут
laucher, все нормально с инкапсуляцией. Зачем мешать другому разработчику, если он явно дополнительными телодвижениями указывает, что он знает, что и зачем делает?
Цитата Сообщение от Dmitriy_M Посмотреть сообщение
Возвращать не указатель или ссылку, а объект.
Это того не стоит.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.11.2013, 21:11
Привет! Вот еще темы с ответами:

Задания о наследовании, инкапсуляции и полиморфизма на C#/ нужно как можно быстро - C++
Создать класс библиографических описаний книг CBookCard. В классе должны быть закрытые поля: автор, заглавие, издательство, год издания,...

Разница между понятиями "Обход в прямом направлении" и "Итерационный прямой обход" - C++
Ребятаа, обьясните чем различается: Обход в прямом направлении и Итерационный прямой обход Добавлено через 10 минут НароооД,...

обход - C++
Король шахматной доски решил выяснить боеспособность своей армии. Посыльный объехал все клетки поля и сделал записи обо всех войсках,...

Обратный обход - C++
У меня есть реализация дерева и его прямой и симметричный обход. Как можно реализовать обратный обход? #include &quot;stdafx.h&quot; #include...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
02.11.2013, 21:11
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru