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

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

Восстановить пароль Регистрация
 
Fasterbru
5 / 5 / 2
Регистрация: 18.11.2014
Сообщений: 81
11.08.2016, 07:40     Библиотеки раскрывают инкапсуляцию #1
.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).

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

C++ Библиотеки
C++ Библиотеки
C++ Библиотеки
Программа на создание класса и инкапсуляцию C++
C++ Библиотеки (C++)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
zss
Модератор
Эксперт С++
 Аватар для zss
5950 / 5555 / 1787
Регистрация: 18.12.2011
Сообщений: 14,196
Завершенные тесты: 1
11.08.2016, 08:09     Библиотеки раскрывают инкапсуляцию #2
Что-то мне не понятна проблема.
Объявление string находится в пространстве имен std,
зачем его еще куда-то прятать?
А на исполняемый код это не должно влиять, т.к. компоновщик подключит только необходимые модули.
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
obivan
Падаван С++
 Аватар для obivan
174 / 160 / 42
Регистрация: 11.11.2014
Сообщений: 602
Завершенные тесты: 1
11.08.2016, 08:51     Библиотеки раскрывают инкапсуляцию #4
Fasterbru, ну так в неймспейс уносите класс а не объявление библиотек

C++
1
2
3
4
5
#include <iostream>
 
namespace myName {
    class MyClass {};
};
Fasterbru
5 / 5 / 2
Регистрация: 18.11.2014
Сообщений: 81
11.08.2016, 09:23  [ТС]     Библиотеки раскрывают инкапсуляцию #5
obivan, Это был частный пример на вопрос : зачем куда куда-то прятать string?
Мой вопрос: Как создать объект при использовании которого я не буду видеть его внутренности извне? Я же вижу либы, которые он использует. Я не хочу их видеть.
Например:
Я создал человека из мяса. При использовании человека, я вижу и могу создать кусок мяса(что мне не надо).
2 решения которые я привел выше, но они не подходят.
Ferrari F1
Заблокирован
298 / 284 / 62
Регистрация: 27.01.2015
Сообщений: 1,914
Записей в блоге: 1
Завершенные тесты: 1
11.08.2016, 09:32     Библиотеки раскрывают инкапсуляцию #6
Fasterbru, каждая библиотека подключится только по одному экзмепляру, т.к. используется препроцессорная обертка
Как использовать препроцессорную обертку
obivan
Падаван С++
 Аватар для obivan
174 / 160 / 42
Регистрация: 11.11.2014
Сообщений: 602
Завершенные тесты: 1
11.08.2016, 09:35     Библиотеки раскрывают инкапсуляцию #7
Fasterbru, если вы покажете мне язык программирования в котором вы не видите подклченные либы, я буду рад, если вам так мусолит глаза то оберните в
C++
1
2
3
4
5
6
#define LIBS
#ifdef LIBS
 
#include //...
 
#endif
этот блок в коде можно свернуть, просто не понятно чего вы хотите, или чтобы не было много файлов создайте одну общую h и подключайте только ее
Operok
125 / 123 / 33
Регистрация: 15.02.2015
Сообщений: 386
Завершенные тесты: 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 файлах используются бустовские смарт поинтеры, ребята не заморачивались
Убежденный
Системный программист
 Аватар для Убежденный
14210 / 6225 / 987
Регистрация: 02.05.2013
Сообщений: 10,377
Завершенные тесты: 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;
};
?

Да, работы придется немного больше выполнить, например, уже нельзя будет обойтись
дефолтовыми конструктором копирования и оператором присваивания, но это, как мне кажется,
совсем небольшая плата.
Fasterbru
5 / 5 / 2
Регистрация: 18.11.2014
Сообщений: 81
11.08.2016, 09:55  [ТС]     Библиотеки раскрывают инкапсуляцию #10
Ferrari F1, obivan, это я все понимаю. я про другое.
1)у меня есть интерфейс "человек"
2)я реализовал этот интерфейс
3)создал порождающий класс, который выдает объект (реализующий интерфейс "человек" из пк.2)
!!итог:я получаю от порождающего класса объект, реализующий интерфейс "человек" и не вижу его либы.
это задачу решает, но громоздко.
вопрос: как получить тот же результат, но компактнее?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.08.2016, 10:18     Библиотеки раскрывают инкапсуляцию
Еще ссылки по теме:

C++ Необходимо рассчитать выражение, используя ООП по максимуму, применить инкапсуляцию и тд
Как не нарушить инкапсуляцию? C++
Как включить библиотеки в исполняемый файл, чтобы не приходилось ставить библиотеки (Eclipse) C++

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

Или воспользуйтесь поиском по форуму:
Operok
125 / 123 / 33
Регистрация: 15.02.2015
Сообщений: 386
Завершенные тесты: 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(...)
{
   ...
}
Yandex
Объявления
11.08.2016, 10:18     Библиотеки раскрывают инкапсуляцию
Ответ Создать тему
Опции темы

Текущее время: 14:47. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru