Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

динамическое преобразование типов

11
19 июня 2008 года
oxotnik333
2.9K / / 03.08.2007
Код:
[COLOR=black][SIZE=2]typedef[/SIZE][SIZE=2] map<string, string>Values;[/SIZE][/COLOR]
[COLOR=black][SIZE=2]typedef[/SIZE][SIZE=2] map<string, [/SIZE][SIZE=2]void[/SIZE][SIZE=2]*>Sections;[/SIZE][/COLOR]
 
[SIZE=2][COLOR=#ffffff][COLOR=black]Sections *m_Sections;[/COLOR][/COLOR][/SIZE]
[COLOR=#ffffff][SIZE=2][COLOR=black]Values *m_Values;[/COLOR][/SIZE]
 
[SIZE=2][COLOR=#000000]m_Sections = new Sections;[/COLOR][/SIZE]
[COLOR=#000000]....[/COLOR]
[SIZE=2][COLOR=#000000]if (a<0)[/COLOR][/SIZE]
[SIZE=2][COLOR=#000000]m_Values = new Values;[/COLOR][/SIZE]
[SIZE=2][COLOR=#000000]else[/COLOR][/SIZE]
[SIZE=2][SIZE=2][COLOR=black]m_Values = [/COLOR][/SIZE][SIZE=2][COLOR=black]dynamic_cast[/COLOR][/SIZE][SIZE=2][COLOR=black]<Values*>((*m_Sections)[key]); // error [/COLOR][/SIZE][/SIZE]
[/COLOR]


error C2681: 'void *' : invalid expression type for dynamic_cast

Как правильно преобразовать динамически?
87
19 июня 2008 года
Kogrom
2.7K / / 02.02.2008
Два уточняющих вопроса:
1. а где тут базовый и производный классы?
2. Почему нельзя просто указать что-то типа
((*m_Values)[key]) = *((*m_Sections)[key]);
3
19 июня 2008 года
Green
4.8K / / 20.01.2000
Цитата: oxotnik333

Как правильно преобразовать динамически?


В данном случае - динамически никак, да и не за чем.
Отказывайся от void* в своих программах. Это дурной тон и плохой стиль для C++.
dynamic_cast тоже нужно избегать. Это тоже плохой стиль.
Всё можно сделать намного красивее и правильнее без этих уродств.

11
19 июня 2008 года
oxotnik333
2.9K / / 03.08.2007
Цитата: Green
В данном случае - динамически никак, да и не за чем.
Отказывайся от void* в своих программах. Это дурной тон и плохой стиль для C++.
dynamic_cast тоже нужно избегать. Это тоже плохой стиль.
Всё можно сделать намного красивее и правильнее без этих уродств.



Мне в (*m_Sections)[key] необходимо хранить как Values* так и char*
а затем при чтении массива преобразовывать к соотв. типу.

Код:
for (iIter_Sections = m_Sections->begin(); iIter_Sections != m_Sections->end(); iIter_Sections ++)
{
  cout<<"param name: <"<<iIter_Sections->first.c_str()<<">"<<'\n';
  Values *m_Values = dynamic_cast<Values*>(iIter_Sections->second);
  if (!m_Values)
       cout<<"param value: "<<(char*)iIter_Sections->second<<'\n';
  else
  {
    Values *m_Values = (Values*)iIter_Sections->second;
    for(iIter_Values = m_Values->begin(); iIter_Values != m_Values->end(); iIter_Values++)
      {
         cout<<"sybparam name: <"<<iIter_Values->first.c_str()<<">"<<'\n';
         cout<<"sybparam value: "<<iIter_Values->second.c_str()<<""<<'\n';
      }
   }
}
А как красивей сделать?
255
19 июня 2008 года
Dart Bobr
1.4K / / 09.04.2004
Можна через reinterpret_cast, но это небезопасно.
Насколько я могу судить - почему не сделать класс-контейнер, который хранит Values* и char*, и что-бы его поведение управлялось его внутренней логикой?
11
19 июня 2008 года
oxotnik333
2.9K / / 03.08.2007
Цитата: Dart Bobr
Можна через reinterpret_cast, но это небезопасно.




пробовал... только если (*m_Sections)[kye] = (char*) = пустая строка
тогда static_cast или reinterpret_cast выдают что это тип Values* соответсвенно m_Values->begin() == AV

5
19 июня 2008 года
hardcase
4.5K / / 09.08.2005
Цитата: Dart Bobr
почему не сделать класс-контейнер, который хранит Values* и char*, и что-бы его поведение управлялось его внутренней логикой?

А ещё лучше сделать один базовый класс-контейнер и два наследника: один для Values* и второй для char*.

255
19 июня 2008 года
Dart Bobr
1.4K / / 09.04.2004
Цитата: hardcase
А ещё лучше сделать один базовый класс-контейнер и два наследника: один для Values* и второй для char*.



Не уверен, что это лучше.
Если реализовать через единый класс-контейнер, то не нужно будет вообще конвертировать типы. А я думаю, что это предпочтительней реализации с наследованиями.

5
19 июня 2008 года
hardcase
4.5K / / 09.08.2005
Цитата: Dart Bobr
Не уверен, что это лучше.
Если реализовать через единый класс-контейнер, то не нужно будет вообще конвертировать типы. А я думаю, что это предпочтительней реализации с наследованиями.

Единый контейнер для разнотипных объектов - это получается вариация на тему злобного Variant-типа.

255
19 июня 2008 года
Dart Bobr
1.4K / / 09.04.2004
Цитата: hardcase
Единый контейнер для разнотипных объектов - это получается вариация на тему злобного Variant-типа.



Не обязательно. Я имею ввиду что-то вроди:

Код:
class container
{
  ...
private:
  Values* m_val;
  char * m_str;
public:
  char* c_str()
  {
     return m_str;
  };
  Values* c_val()
  {
     return m_val;
  };
  ...
}

То-есть, примерно так, как это в стль делается :)
11
19 июня 2008 года
oxotnik333
2.9K / / 03.08.2007
собственно говоря решил в лоб...
Код:
class SomeClass
{
public:
enum Type{StringType, ArrayType};
SomeClass(string str)
{
s = str;
type = StringType;
}
SomeClass(Values *v)
{
val = v;
type = ArrayType;
}
Type GetType (void){return type;}
Values * GetArray(void){return val;}
Values * GetString(void){return s;}
private:
string s;
Values *val;
Type type;
}
 
соответственно вызов:
if (pSomeClass->GetType() == pSomeClass->StringType)
string str = pSomeClass->GetString();
else....


мож и не красиво, но работает
87
19 июня 2008 года
Kogrom
2.7K / / 02.02.2008
Возможно, тут ошибка:
Values * GetString(void){return s;}
11
19 июня 2008 года
oxotnik333
2.9K / / 03.08.2007
Цитата: Kogrom
Возможно, тут ошибка:
Values * GetString(void){return s;}



в браузере писал... в реальности он несколько больше (сам класс) и естественно без ошибок, т.к. работает как надо

87
28 июня 2008 года
Kogrom
2.7K / / 02.02.2008
Попытался ради упражнения решить задачу так, как советовали более опытные форумчане на первой странице (что за тип Values я не знаю, поэтому использовал int):

Код:
struct BaseClass
{
    virtual string GetStr() = 0;
};

struct MyString : public BaseClass
{
    string str;
    string GetStr(){return str;}
    MyString(string s):str(s){}
};

struct MyInt : public BaseClass
{
    int iVar;
    string GetStr(){throw iVar; return "";}
    MyInt(int i):iVar(i){}
};

int main()
{
    vector<BaseClass*> sections;

    MyString sFirst("first"), sSecond("second");
    MyInt iFirst(1), iSecond(2);

    sections.push_back(&sFirst);
    sections.push_back(&iFirst);
    sections.push_back(&sSecond);
    sections.push_back(&iSecond);

    for(int i = 0; i < sections.size(); i++)
    {
        try{ cout << sections->GetStr() << endl;}
        catch(int gg){ cout << "it's not string, but int: " << gg << endl; }
    }
}

Не буду говорить что этот метод лучше, но он позволяет не хранить по 2 переменные в каждом экземляре классов. Ну и морочиться с enum не надо.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог