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

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

Войти
Регистрация
Восстановить пароль
 
Fasterbru
5 / 5 / 2
Регистрация: 18.11.2014
Сообщений: 81
#1

Библиотеки раскрывают инкапсуляцию - C++

11.08.2016, 07:40. Просмотров 233. Ответов 10
Метки нет (Все метки)

.h:
C++
1
2
3
4
5
6
7
8
9
10
#include <string>
 
class A
{
public:
    A();
    ~A();
private:
    std::string str;
};
При использовании класса A добавляется библиотека string, которая используется только внутри класса. Извне она только засоряет область видимости. Как можно от этого избавиться?

1)Можно использовать порождающие шаблоны, но много всего приходится делать(интерфейс A, A_impl, порождающий класс).
2)Можно добавить библиотеку в namespace и это сработает, но не с либами, которые должны быть в глобальной области(например string).

Долго не могу понять что делать. Большой ком наслаивается к конечному модулю.
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.08.2016, 07:40
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Библиотеки раскрывают инкапсуляцию (C++):

Как не нарушить инкапсуляцию? - C++
Попал в такой парадокс... Есть класс &quot;А&quot; Есть класс &quot;Б&quot; Есть класс &quot;В, который наследник класса А&quot;. У класса А есть три...

Программа на создание класса и инкапсуляцию - C++
Здравствуйте. Подскажите, пожалуйста идею для решения задачи на создание класса и инкапсуляцию. Задача в файле. Просто не могу все...

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

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

про библиотеки в VS C++ (какие библиотеки нужны для функций 'cout' и 'cin') - C++
какие библиотеки нужны для функций 'cout' и 'cin' ???

Как включить библиотеки в исполняемый файл, чтобы не приходилось ставить библиотеки (Eclipse) - C++
Как включить библиотеки в конечный EXE как это сделано в bilder, чтобы не приходилось ставить библиотеки.

10
zss
Модератор
Эксперт С++
6486 / 6049 / 1987
Регистрация: 18.12.2011
Сообщений: 15,691
Завершенные тесты: 1
11.08.2016, 08:09 #2
Что-то мне не понятна проблема.
Объявление string находится в пространстве имен std,
зачем его еще куда-то прятать?
А на исполняемый код это не должно влиять, т.к. компоновщик подключит только необходимые модули.
0
Fasterbru
5 / 5 / 2
Регистрация: 18.11.2014
Сообщений: 81
11.08.2016, 08:44  [ТС] #3
zss, Если я захочу завернуть класс А и все что с ним связанно в namespace, то я не смогу сделать это из-за string
Пример
classB.h:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
namespace bImpl
{
#include "classA.h"
#include ....
#include ....
}
 
class B
{
public:
    B(){}
    ~B(){}
    void func(){};
private:
    bImpl::A el;
};
т.к. в classA.h есть string
0
obivan
Падаван С++
404 / 224 / 58
Регистрация: 11.11.2014
Сообщений: 783
Завершенные тесты: 2
11.08.2016, 08:51 #4
Fasterbru, ну так в неймспейс уносите класс а не объявление библиотек

C++
1
2
3
4
5
#include <iostream>
 
namespace myName {
    class MyClass {};
};
0
Fasterbru
5 / 5 / 2
Регистрация: 18.11.2014
Сообщений: 81
11.08.2016, 09:23  [ТС] #5
obivan, Это был частный пример на вопрос : зачем куда куда-то прятать string?
Мой вопрос: Как создать объект при использовании которого я не буду видеть его внутренности извне? Я же вижу либы, которые он использует. Я не хочу их видеть.
Например:
Я создал человека из мяса. При использовании человека, я вижу и могу создать кусок мяса(что мне не надо).
2 решения которые я привел выше, но они не подходят.
0
Ferrari F1
604 / 497 / 100
Регистрация: 27.01.2015
Сообщений: 2,914
Записей в блоге: 1
Завершенные тесты: 1
11.08.2016, 09:32 #6
Fasterbru, каждая библиотека подключится только по одному экзмепляру, т.к. используется препроцессорная обертка
Как использовать препроцессорную обертку
0
obivan
Падаван С++
404 / 224 / 58
Регистрация: 11.11.2014
Сообщений: 783
Завершенные тесты: 2
11.08.2016, 09:35 #7
Fasterbru, если вы покажете мне язык программирования в котором вы не видите подклченные либы, я буду рад, если вам так мусолит глаза то оберните в
C++
1
2
3
4
5
6
#define LIBS
#ifdef LIBS
 
#include //...
 
#endif
этот блок в коде можно свернуть, просто не понятно чего вы хотите, или чтобы не было много файлов создайте одну общую h и подключайте только ее
0
Operok
161 / 159 / 44
Регистрация: 15.02.2015
Сообщений: 454
Завершенные тесты: 2
11.08.2016, 09:51 #8
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
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
/*my_class.h*/
#include <memory>
 
namespace my
{
    namespace detail
    {
        class MyClassImpl;
    }
    class MyClass
    {
    public:
        MyClass();
        MyClass(MyClass&&);
        MyClass& operator=(MyClass&&);
        ~MyClass();
        //...
    private:
        MyClass(const MyClass&) = delete;
        MyClass& operator=(const MyClass) = delete;
        std::unique_ptr<MyClassImpl> pimpl;
    };
}
 
/*my_class.cpp*/
 
#include "my_class.h"
//инклюдим что хотим, в том числе и реализация класса my::detail::MyClassImpl
 
using namespace my;
 
MyClass::MyClass() : pimpl(std::make_unique<detail::MyClassImpl>())
{
}
MyClass::MyClass(MyClass&&) = default;
MyClass& MyClass::operator=(MyClass&&) = default;
MyClass::~MyClass() = default;
 
//остальная реализация
Добавлено через 5 минут
ps: если не нравится #include <memory>, то можно всё реализовать через сырые указатели на MyClassImpl, но к чему такие заморочки, тем более если в область видимости попадают заголовочные файлы стандартной библиотеки? Например, необходимо было использовать c++ либу для MySQL, а там в header файлах используются бустовские смарт поинтеры, ребята не заморачивались
2
Убежденный
Ушел с форума
Эксперт С++
15691 / 7201 / 1138
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
Завершенные тесты: 1
11.08.2016, 09:52 #9
+1 к сообщению выше.
Тоже не понимаю, чем не устраивает идиома pimpl?
В простейшем виде:
C++
1
2
3
4
5
6
7
8
9
10
// #include <string> уже не нужен.
 
class A
{
public:
    A();
    ~A();
private:
    void * m_pImpl;
};
?

Да, работы придется немного больше выполнить, например, уже нельзя будет обойтись
дефолтовыми конструктором копирования и оператором присваивания, но это, как мне кажется,
совсем небольшая плата.
1
Fasterbru
5 / 5 / 2
Регистрация: 18.11.2014
Сообщений: 81
11.08.2016, 09:55  [ТС] #10
Ferrari F1, obivan, это я все понимаю. я про другое.
1)у меня есть интерфейс "человек"
2)я реализовал этот интерфейс
3)создал порождающий класс, который выдает объект (реализующий интерфейс "человек" из пк.2)
!!итог:я получаю от порождающего класса объект, реализующий интерфейс "человек" и не вижу его либы.
это задачу решает, но громоздко.
вопрос: как получить тот же результат, но компактнее?
0
Operok
161 / 159 / 44
Регистрация: 15.02.2015
Сообщений: 454
Завершенные тесты: 2
11.08.2016, 10:18 #11
С помощью include guard некоторых заголовочных файлов можно от конечного пользователя скрывать некоторые методы класса в зависимости от используемых им библиотек/header'ов или вообще платформы:
C++
1
2
3
4
5
6
7
8
class MyWindow //некий кросплатформенный класс окошка
{
...
#ifdef _WINDEF_
    HWND GetNativeHandle() const;
#endif
...
}
Добавлено через 16 минут
Цитата Сообщение от Fasterbru Посмотреть сообщение
1)у меня есть интерфейс "человек"
2)я реализовал этот интерфейс
3)создал порождающий класс, который выдает объект (реализующий интерфейс "человек" из пк.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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/*IHuman.cpp*/
class IHuman
{
public:
    virtual ~IHuman() = default;
    virtual void SomeMethod() = 0;
    //остальные виртуальные методы
protected:
    IHuman() = default;
};
 
/*Human.h*/
#include "IHuman.h"
 
class Human : public IHuman
{
public:
    Human(...);
    virtual ~Human();
    virtual void SomeMethod() override;
    //остальная реализация
};
 
/*Human.cpp*/
/*тут реализация class Human*/
 
/*HumanFactory.h*/
#include "IHuman.h"
#include <memory>
 
class HumanFactory
{
public:
    static std::unique_ptr<IHuman> MakeHuman(...);
...
};
 
/*HumanFactory.cpp*/
#include "HumanFactory.h"
#include "Human.h"
std::unique_ptr<IHuman> HumanFactory::MakeHuman(...)
{
   ...
}
1
11.08.2016, 10:18
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.08.2016, 10:18
Привет! Вот еще темы с ответами:

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

Как JPG формат раскрывают в Java приложениях - Java
Как JPG формат раскрывают в Java приложениях или Как AVI формат раскрывают в Java приложениях

Про инкапсуляцию (и Property) - C#
Никак не могу понять вот чего... Вот у нас классы class Student1 { public int mark; public string name; }

Программа на инкапсуляцию (нужен сам вывод) - Java SE
Ha выставке собак составляется анкета, содержащая сведения о породе (боксера терьер, такса, пудель, доберман, овчарка), возрасте, высоте...


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

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