Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> возвратить из функции void? 
V
    Опции темы
tilin
Дата 27.10.2009, 23:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 23.9.2008

Репутация: нет
Всего: нет



Цитата(Lazin @ 27.10.2009,  20:54)
можно использовать паттерн - visitor

А в этом случае не придется для каждого типа добавлять новый оператор в IVisitor? Если да, то не подходит.

Это сообщение отредактировал(а) tilin - 27.10.2009, 23:25
PM MAIL   Вверх
Lazin
Дата 28.10.2009, 00:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Цитата(tilin @  27.10.2009,  23:25 Найти цитируемый пост)
А в этом случае не придется для каждого типа добавлять новый оператор в IVisitor? Если да, то не подходит.

если они однотипные, то их можно сгенирировать с помощью шаблона

если ты будешь использовать variant, то у тебя в коде будет что-то вроде - 

Код

Variant v = p->Get();
if(v.isInteger())
 ...
else if(v.isString())
 ... //итд

visitor - это то-же самое, только принятие решения, о том, как обрабатывать значение ложится на компилятор (перегрузка ф-ии) и в любом случае, тебе придется написать код для разных типов(либо использовать шаблон, для нескольких похожих типов)
PM MAIL Skype GTalk   Вверх
tilin
Дата 28.10.2009, 00:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 23.9.2008

Репутация: нет
Всего: нет



Цитата(Lazin @ 28.10.2009,  00:01)
это то-же самое, только принятие решения, о том, как обрабатывать значение ложится на компилятор (перегрузка ф-ии) и в любом случае, тебе придется написать код для разных типов(либо использовать шаблон, для нескольких похожих типов)

Типы могут быть любые. Вариант у меня выглядит вот так:

Код

class Variant
{
private:
    class IType
    {
    public:
        virtual ~IType()
        {
        }
    };
    typedef auto_ptr<IType> pIType;
    template <class T>
    class Type : public IType
    {
    public:
        T object;
        Type(T const& t)
        : object(t)
        {
        }
    };
    pIType itype;
public:
    template <class T>
    Variant& operator = (T const& t)
    {
        typedef Type<T> cType;
        itype = auto_ptr<cType>(new cType(t));
        return *this;
    }

    template <class T>
    operator T ()
    {
        typedef Type<T> cType;
        cType& type = dynamic_cast<cType&>(*itype);
        return type.object;
    }
};



В классе есть 
Код
Variant result;


В коде значение получается например так: 
Код
SomeClass* res = Object->Get();


PM MAIL   Вверх
Lazin
Дата 28.10.2009, 06:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Цитата(tilin @  28.10.2009,  00:11 Найти цитируемый пост)
В коде значение получается например так

и как-же ты с ними работаешь потом, если не секрет?
PM MAIL Skype GTalk   Вверх
tilin
Дата 28.10.2009, 08:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 23.9.2008

Репутация: нет
Всего: нет



Цитата(Lazin @ 28.10.2009,  06:20)
и как-же ты с ними работаешь потом, если не секрет?

Вопрос не совсем понял, но например в варианте с int так:

Код

vector<IBase*> v;
v.push_back(new A<int>);
int i = v[0]->Get();

int vvp = i * 200;
cout << vvp << endl;


PM MAIL   Вверх
Lazin
Дата 28.10.2009, 09:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Цитата(tilin @  28.10.2009,  08:52 Найти цитируемый пост)
Код

vector<IBase*> v;
v.push_back(new A<int>);
int i = v[0]->Get();
int vvp = i * 200;
cout << vvp << endl;


во первых, здесь нужно явное приведение типа (static_cast), во вторых, если в v[0] не int - оператор приведения типа бросит исключение, мне интересно, что ты будешь делать, если у тебя в одном контейнере значения разных типов, как в твоем первом примере?

Код

vector<IBase*> v;
v.push_back(new A<int>());
v.push_back(new A<double>());
...
v.push_back(new A<Foo>());
...
for(vector<IBase*>::iterator i = v.begin(); i != v.end(); ++i)
{
    undefined_type value = static_cast<undefined_type>((*i)->Get()); //????
}

PM MAIL Skype GTalk   Вверх
tilin
Дата 28.10.2009, 09:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 23.9.2008

Репутация: нет
Всего: нет



Вот пример - код рабочий.

Код

#include <memory>
#include <vector>
#include <iostream>

using namespace std;


class Variant
{
private:
    class IType
    {
    public:
        virtual ~IType()
        {
        }
    };
    typedef auto_ptr<IType> pIType;
    template <class T>
    class Type : public IType
    {
    public:
        T object;
        Type(T const& t)
        : object(t)
        {
        }
    };
    pIType itype;
public:
    template <class T>
    Variant& operator = (T const& t)
    {
        typedef Type<T> cType;
        itype = auto_ptr<cType>(new cType(t));
        return *this;
    }

    template <class T>
    operator T ()
    {
        typedef Type<T> cType;
        cType& type = dynamic_cast<cType&>(*itype);
        return type.object;
    }
};

class IBase
{
public:
  virtual Variant Get() = 0;
};

template <class T>
class A : public IBase
{
public:
  Variant value;
  A(){}
  A(T t)
  {
     value = t;
  }

  Variant Get()
  {
    return value;
  }
};

int _tmain(int argc, _TCHAR* argv[])
{
    vector<IBase*> v;
    
    v.push_back(new A<int>(100));
    v.push_back(new A<float>(8.9f));

    int i = v[0]->Get();
    float f = v[1]->Get();


    cout << i << endl;
    cout << f << endl;
    return 0;
}



PM MAIL   Вверх
Lazin
Дата 28.10.2009, 10:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Цитата(tilin @  28.10.2009,  09:42 Найти цитируемый пост)
Вот пример - код рабочий.

и бесполезный smile 

приходи, когда попробуешь написать реальный код, использующий этот класс, вопросы сразу возникнут, я гарантирую это smile 
PM MAIL Skype GTalk   Вверх
tilin
Дата 28.10.2009, 10:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 23.9.2008

Репутация: нет
Всего: нет



Цитата(Lazin @ 28.10.2009,  10:04)
и бесполезный smile 

приходи, когда попробуешь написать реальный код, использующий этот класс, вопросы сразу возникнут, я гарантирую это smile

Вообще заморочки с Вариантом требовались для вполне реального кода, в продолжение поста Получение типа параметра функции. А нужно это все для того чтобы на автомате создавать объекты хранящие вызов функции вместе с параметрами и возвращаемым значением. Вот для получения возвращаемого значения из объекта хранящего вызов и потребовалось представить его Вариантом. Потому что такие объекты наследуются от абстрактного интерфейса и помещаются в вектор. Все прекрасно работает.
PM MAIL   Вверх
Lazin
Дата 28.10.2009, 10:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Цитата(tilin @  28.10.2009,  10:25 Найти цитируемый пост)
Все прекрасно работает

пока ты знаешь тип возвращаемого значения
просто у тебя нет способа узнать тип значение, хранящегося в Variant-e, я уже несколько постов пытаюсь на это намекнуть smile 
Цитата(tilin @  28.10.2009,  10:25 Найти цитируемый пост)
Вообще заморочки с Вариантом требовались для вполне реального кода, в продолжение поста Получение типа параметра функции.

вообще, лень вникать, sry
просто, если у тебя не возникает необходимости определять тип значения, хранящегося в Variant-е, значит вероятно, тебе вообще не нужен Variant, ты просто усложнил архитектуру приложения smile 
PM MAIL Skype GTalk   Вверх
tilin
Дата 28.10.2009, 10:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 23.9.2008

Репутация: нет
Всего: нет



Нет, код который получает результат тип знает конечно. Как этот код выбирает объекты из контейнера - это другой вопрос. Но факт, что все объекты в контейнере должны иметь один тип, отсюда и наследование интерфейса, а из наличие в интерфейсе одного виртуального Get() на все наследуемые типы требует, чтобы Get() возвращал Вариант, который неявно преобразовывается к требуемому типу.
PM MAIL   Вверх
mes
Дата 28.10.2009, 11:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(Lazin @  28.10.2009,  09:32 Найти цитируемый пост)
просто, если у тебя не возникает необходимости определять тип значения, хранящегося в Variant-е, значит вероятно, тебе вообще не нужен Variant, ты просто усложнил архитектуру приложения smile 

 smile 
Цитата(tilin @  28.10.2009,  09:43 Найти цитируемый пост)
Но факт, что все объекты в контейнере должны иметь один тип, отсюда и наследование интерфейса, а

если тип объекта известен и помощь компилятора не требуется, то хранить объект можно и как void *

Цитата(tilin @  28.10.2009,  09:43 Найти цитируемый пост)
Как этот код выбирает объекты из контейнера - это другой вопрос. 

как раз от такого как происходит взаимодействие с элементом контейнера и зависит какой интерфейс должен поддерживать объект.


как я понимаю у Вас тип зависит от индекса, тогда

  если контейнер условно находится в библиотеке которая ничего не знает о типах, и предоставляет просто место для хранения, то тут как раз хранение по void* и каждый клиент имеет интерфейс по получению "готовых" объектов. 

  если же нужно хранить разношерстные элементы как одну структуру и все типы статически известные, то посмотрите например библиотечку boost::fusion в частности :
http://www.boost.org/doc/libs/1_40_0/libs/...ner/vector.html

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








--------------------
PM MAIL WWW   Вверх
tilin
Дата 28.10.2009, 12:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 23.9.2008

Репутация: нет
Всего: нет



Цитата(mes @  28.10.2009,  11:59 Найти цитируемый пост)
как я понимаю у Вас тип зависит от индекса


Абсолютно не зависит. Объекты в массив добавляются в произвольной последовательности.

Цитата(mes @  28.10.2009,  11:59 Найти цитируемый пост)
если контейнер условно находится в библиотеке которая ничего не знает о типах, и предоставляет просто место для хранения, то тут как раз хранение по void* и каждый клиент имеет интерфейс по получению "готовых" объектов. 


В первом варианте Get() возвращал именно void*, потом клиент делал static_cast до нужного типа. Но мне хотелось, чтобы вместо 
Код
int i = (*static_cast<int*>(v[0]->Get()));

было
Код
int i = v[0]->Get();

Конечно использовать динамическое приведение типов вместо статического не есть Гут. И я еще подумаю, какой из них выбрать.
PM MAIL   Вверх
mes
Дата 28.10.2009, 12:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(tilin @  28.10.2009,  11:26 Найти цитируемый пост)
Абсолютно не зависит. Объекты в массив добавляются в произвольной последовательности.

так тип объекта с чем то связан или программист сам должен помнить под какой индекс что он добавил ?!

Цитата(tilin @  28.10.2009,  11:26 Найти цитируемый пост)
В первом варианте Get() возвращал именно void*, потом клиент делал static_cast до нужного типа. Но мне хотелось, чтобы вместо 

имхо, приведенной в этом топике информации недостаточно для совета.


--------------------
PM MAIL WWW   Вверх
tilin
Дата 28.10.2009, 13:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 23.9.2008

Репутация: нет
Всего: нет



Общая задача выглядит так:

Требовалось реализовать объект, хранящий указатель на объект некого класса, указатель на метод класса, параметры вызова и возвращаемое значение. Такие объекты формируются вместе с параметрами, помещаются в список вместе с метаданными. Список преобразовывается. Некоторые элементы перемещаются в начало, некоторые в конец и т.д. Затем по определенным условиям вызывается метод Call объектов. Возвращаемое значение сохраняется в объекте. Затем по метаданным ищется объект в списке и код получает результат вызова (точно зная его тип конечно).
PM MAIL   Вверх
Страницы: (3) Все 1 [2] 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0647 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.