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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Преобразование умных указателей 
V
    Опции темы
volk666
Дата 1.6.2011, 18:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



class A {...}
class B : public A {...}

std::tr1::shared_ptr< A > a(new B());
std::tr1::weak_ptr< B > b;
b = a; // не компилируется
Как можно сделать преобразование от предка к потомку для умных указателей?
Нужно для списка классов, порожденных от A(возможно, абстрактного).
Заранее спасибо.
PM MAIL   Вверх
afiskon
Дата 1.6.2011, 22:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 31.3.2011
Где: Россия, Москва

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



Код

class A {
public:
    virtual void getName() {
        cout << "This is A!" << endl;
    }
};

class B: public A {
public:
    virtual void getName() {
        cout << "This is B!" << endl;
    }
};

// ............

    shared_ptr<A> aptr(new B);
    weak_ptr<B> bptr;

    bptr = static_pointer_cast<B>(aptr);
    bptr.lock()->getName();

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


Опытный
**


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

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



Цитата(volk666 @ 1.6.2011,  18:53)
class A {...}
class B : public A {...}

std::tr1::shared_ptr< A > a(new B());
std::tr1::weak_ptr< B > b;
b = a; // не компилируется
Как можно сделать преобразование от предка к потомку для умных указателей?
Нужно для списка классов, порожденных от A(возможно, абстрактного).
Заранее спасибо.

а ты ничего не напутал ? преобразование вниз по иерархии это совсем плохая практика. 

Ты и просто на указателя такую штука так просто не сделаешь
Код

class A {public: A(){}};
class B : public A {public: B(){}};

int main()
{
   A* a = new B();
   B* b;
   
   b = a;
}

Код

source.cpp: In function 'int main()':
source.cpp:14:8: error: invalid conversion from 'A*' to 'B*' [-fpermissive]

Build finished with errors


тут нужно либо пользоваться хардкорными кастами (типа static_cast, или какой то другой). Либо хм... а других способов и не припомню я.
PM MAIL   Вверх
afiskon
Дата 1.6.2011, 22:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 31.3.2011
Где: Россия, Москва

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



Цитата

а ты ничего не напутал ? преобразование вниз по иерархии это совсем плохая практика. 

Обычная практика, если не забывать делать деструкторы виртуальными.

Код

    B b;
    A* a = &b; // B является A
    //B* pb = a; // обратное _не_всегда_ верно...
    B* pb = static_cast<B*>(a); // но мы то с вами знаем!
    pb->getName();

ЗЫ. А еще в вашем коде память течет ;)

Добавлено через 4 минуты и 47 секунд
Цитата

тут нужно либо пользоваться хардкорными кастами (типа static_cast, или какой то другой)

А что, простите, "хардкорного" в static_cast?
PM MAIL WWW   Вверх
cupper
Дата 1.6.2011, 22:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(afiskon @ 1.6.2011,  22:19)
Цитата

а ты ничего не напутал ? преобразование вниз по иерархии это совсем плохая практика. 

Обычная практика, если не забывать делать деструкторы виртуальными.

А что, простите, "хардкорного" в static_cast?

http://alenacpp.blogspot.com/2005/08/c.html первый абзац абзац наиболее четко описывает то что я хотел сказать.

Раскройте мне секрет как связано преобразования вниз по иерархии и виртуальные деструкторы ?
PM MAIL   Вверх
volk666
Дата 2.6.2011, 00:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



afiskon, большое спасибо smile ! Как раз это и было нужно. Надо tr1 и boost получше изучить. Тема закрыта.
Цитата

а ты ничего не напутал ? преобразование вниз по иерархии это совсем плохая практика. 

Это смотря что делаешь. Есть список объектов базового класса, обрабатывается алгоритмом. В то же время каждый элемент этого списка - свойство других объектов, но уже как производный класс. У каждого элемента есть ID, по которому он находится, и его тип заранее известен ==> никаких ошибок не будет.


Это сообщение отредактировал(а) volk666 - 2.6.2011, 00:15
PM MAIL   Вверх
afiskon
Дата 2.6.2011, 13:42 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 31.3.2011
Где: Россия, Москва

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



cupper Это у вас такой хитрый троллинг? smile

Цитата

Лучшая практика по приведению типов: не делать этого. Потому что, если в программе потребовалось приведение типов, значит в этой программе с большой долей вероятности что-то неладно.

Я так могу про что угодно написать:
Цитата

Лучшая практика по использованию protected-методов: не делать этого. Потому что, если в программе потребовались protected-методы, значит в этой программе с большой долей вероятности что-то неладно.

или:
Цитата

Лучшая практика по использованию оператора new: не делать этого. Потому что, если в программе потребовался оператор new, значит в этой программе с большой долей вероятности что-то неладно.

1. ПОЧЕМУ?
2. Даже если new в теории небезопасен (забыл сказать delete - и память потекла), это не значит, что его никогда-никогда не нужно использовать. Например, любая фабрика использует new. Не использовать теперь фабрики? Другой вопрос, что с умными указателями программа будет надежнее.

Цитата

как связано преобразования вниз по иерархии и виртуальные деструкторы ?

Пожалуйста:

Код

A* createSomething(/* args */) {
  B* pb = new B;
  return pb;
}

A* pa = createSomething(/* args */);
/// ....
delete pa; // если деструктор не виртуальный, вызовет ~A, когда нужно ~B!


Тут идет преобразование вниз (а вообще низ и верх иерархии - вещи относительные, родителей обычно рисуют сверху), но если у нас имеет место наслодование A -> B -> C, то мы можем создать C, вернуть его, как A, потом кастнуть в B и вызвать не тот деструктор ~B, когда нужен ~C. 

А вообще советую вам почитать Майерса, у него вопросы, что вы задаете, очень хорошо освещены.

Это сообщение отредактировал(а) afiskon - 2.6.2011, 13:48
PM MAIL WWW   Вверх
cupper
Дата 2.6.2011, 21:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(afiskon @ 2.6.2011,  13:42)
А вообще советую вам почитать Майерса, у него вопросы, что вы задаете, очень хорошо освещены.

А сами то читали :?

Цитата

Правило 27: Не злоупотребляйте приведением типов

Правила C++ разработаны так, чтобы неправильно работать с типами было 
невозможно. Теоретически, если ваша программа компилируется без ошибок, 
значит, она не пытается выполнить никаких небезопасных или бессмысленных 
операций с объектами. Это ценная гарантия. Не надо от нее отказываться.
К сожалению, приведения обходят систему типов. И это может привести
к различным проблемам, некоторые из которых распознать легко, а некоторые -
чрезвычайно трудно. Если вы пришли к C++ из мира С, Java или С#, примите
эток сведению, поскольку в указанных языках в приведениях типов чаще 
возникает необходимость, и они менее опасны, чем в C++. Но C++ - это не С. Это не
Java Это не С#. В этом языке приведение - это средство, к которому нужно 
относиться с должным почтением.


сейчас начнете, что есть ситуации когда нужно... и бла бла бла, тогда возвращайся к посту на блог Алены, и
Цитата

Потому что, если в программе потребовалось приведение типов, значит в этой программе с большой долей вероятности что-то неладно.


Жаль нет Страуструпа в электронке под рукой, еще бы и на него сослался. Боюсь что бестолку.

И кстати, указатели это зло, зловещее зло smile страшен тот код где работа идет только с голыми указателями. Это как бриться скальпелем пьяным на намыленном полу. Код должен быть прост и не вызывать вопросов.

Это сообщение отредактировал(а) cupper - 2.6.2011, 21:54
PM MAIL   Вверх
boostcoder
Дата 2.6.2011, 22:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

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



Цитата(cupper @  2.6.2011,  21:28 Найти цитируемый пост)
Потому что, если в программе потребовалось приведение типов, значит в этой программе с большой долей вероятности что-то неладно.

полагаю, динамический полиморфизм Вам не известен. smile

Добавлено через 2 минуты и 34 секунды
вообще-то, afiskon истину глаголит.

а работать с сырыми указателями, или со смартами - это не ошибка или нарушение правил - это выбор smile 
PM WWW   Вверх
afiskon
Дата 2.6.2011, 22:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 31.3.2011
Где: Россия, Москва

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



cupper, одно дело избегать (Майерс) и не использовать (Алёна C++ в вашей интерпретации). Я согласен с тем, что использование указателей по возможности нужно сводить к минимуму. Меньше шансов выстрелить себе в ногу. Но с 
Цитата

преобразование вниз по иерархии это совсем плохая практика. 

или
Код

И кстати, указатели это зло, зловещее зло

согласиться не могу. Если вы так не любите указатели, пишите на Haskell, там их вообще нет. Ни одного. В принципе.
PM MAIL WWW   Вверх
cupper
Дата 3.6.2011, 11:42 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Я ей богу не понимаю почему вы плюшки ООП приписываете к кастам. Я бы мог щас расписать принципы ооп, накой хер нужны динамические полиморфизмы и виртуальные деструкторы... но вы и так должны это знать. Единственно чего я не понимаю - причем тут касты и все это. Каст это всего лишь преобразования типа но не стандартное (которое умеет делать сам компилятор, например от потомка к предку) а то ответственность за которое полностью и бесповоротно несет сам программист. А это лишний повод для ошибки.

Если в задаче появляется необходимость привести указатель предка к указателя на потомка для того что бы вызвать функции потомка, получается что у вас потомки совсем таки разные получаются. И смысл унаследовать их от родителя как бы и теряется. Так как они не дополняют а изменяют базовый класс. У Майерса про ето как раз очень хорошо написано, не помню в какой именно книже, толи советы по С++? толи по STL. 

PS. исправил ошибки.

Это сообщение отредактировал(а) cupper - 3.6.2011, 13:45
PM MAIL   Вверх
afiskon
Дата 3.6.2011, 11:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 31.3.2011
Где: Россия, Москва

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



Трудно в чем-то убедить человека, когда он этого не хочет smile
PM MAIL WWW   Вверх
boostcoder
Дата 3.6.2011, 11:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

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



Цитата(cupper @  3.6.2011,  11:42 Найти цитируемый пост)
Если в задаче появляется необходимость привести указатель на базовый класс к указателя на предка для того что бы вызвать функции потомка, получается что у вас потомки совсем таки разные получаются. И смысл унаследовать их от родителя как бы и теряется.

пичалька smile

Добавлено через 2 минуты и 10 секунд
хотел было привести пример стандартной ситуации когда это нужно(возможно это единственный способ при динамическом полиморфизме), но не стану...
как уже сказал afiskon:
Цитата(afiskon @  3.6.2011,  11:43 Найти цитируемый пост)
Трудно в чем-то убедить человека, когда он этого не хочет


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


Опытный
**


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

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



Цитата(boostcoder @ 3.6.2011,  11:45)
хотел было привести пример стандартной ситуации когда это нужно

Пример в студию !
PM MAIL   Вверх
boostcoder
Дата 3.6.2011, 14:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

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



Код

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

struct base {
   virtual void method() = 0;
};

struct derived1: base {
   virtual ~derived1() {}
   virtual void method() { std::cout << "derived1" << std::endl; }
};

struct derived2: base {
   virtual ~derived2() {}
   virtual void method() { std::cout << "derived2" << std::endl; }
};

typedef std::shared_ptr<base> base_ptr;
typedef std::vector<base_ptr> impls_list;

int main() {
   impls_list list;
   list.push_back(base_ptr(new derived1)); // каст!
   list.push_back(base_ptr(new derived2)); // и еще один!
   
   list[0]->method();
   list[1]->method();
}

http://liveworkspace.org/code/bf5e12a26406...b9cf0c8731596c8

покажи способ сделать это не используя каст по иерархии ;)
на примере динамического полиморфизма.

зы
хотя я предпочитаю статический.
PM WWW   Вверх
azesmcar
Дата 3.6.2011, 14:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


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

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



boostcoder

а где тут приведение указателя на базовый тип к указателю на потомка?
PM   Вверх
boostcoder
Дата 3.6.2011, 14:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

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



azesmcar, та нет. я хотел показать что без каста такое невозможно.
PM WWW   Вверх
azesmcar
Дата 3.6.2011, 14:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


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

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



Цитата(cupper @  2.6.2011,  21:28 Найти цитируемый пост)
И кстати, указатели это зло, зловещее зло 

 smile  smile 
как страшно жить smile

Добавлено через 31 секунду
Цитата(boostcoder @  3.6.2011,  14:36 Найти цитируемый пост)
azesmcar, та нет. я хотел показать что без каста такое невозможно. 

так ведь речь шла про downcast, а не про upcast smile 
PM   Вверх
boostcoder
Дата 3.6.2011, 14:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

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



Цитата(azesmcar @  3.6.2011,  14:36 Найти цитируемый пост)
так ведь речь шла про downcast, а не про upcast

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

Добавлено через 3 минуты и 44 секунды
Цитата(azesmcar @  3.6.2011,  14:33 Найти цитируемый пост)
а где тут приведение указателя на базовый тип к указателю на потомка? 

речь об этом?:
Код

struct base {};
struct derived: base {};

int main() {
   base* b = new derived;
   derived* d = b;
}

http://liveworkspace.org/code/15f2508fa76c...b707a3e1dda6f12

а что тут незаконного? или я что-то упустил?
PM WWW   Вверх
mes
Дата 3.6.2011, 15:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(boostcoder @  3.6.2011,  13:40 Найти цитируемый пост)
меня зантересовало утверждение о зле кастов, и о том, что касты свидетельство ошибки проектирования

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

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

Добавлено через 51 секунду
естественно в данном случае идет об _опасных_ кастах.. какие именно входят в этот список, надеюсь уточнять не надо smile



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


uploading...
****


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

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



Цитата(boostcoder @  3.6.2011,  14:40 Найти цитируемый пост)
а что тут незаконного? 

http://codepad.org/C9s9zRmk
PM   Вверх
boostcoder
Дата 3.6.2011, 15:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

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



Цитата(mes @  3.6.2011,  15:01 Найти цитируемый пост)
каст действительно во многих случаях является ошибкой программирования, 
но в основном в тех, когда (по неопытности) программист предпочитает каст, взамен более удобному и безопасному инструменту для той задачи..
но.. каст нужная вещь, и очень часто примененная  с умом с позволяет добиться нужного поведения наиболее коротким способом.. 

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

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

Добавлено через 6 минут и 19 секунд
Цитата(azesmcar @  3.6.2011,  15:03 Найти цитируемый пост)
http://codepad.org/C9s9zRmk 

хм..
ладно, компилятор недоволен. но на практике это к чему привести может в том случае, что подобный каст используется только в приведенном примере?:
Код

#include <iostream>

struct base { virtual void method() = 0; };
struct derived: base {
   virtual void method() {
      std::cout << "derived::method()" << std::endl;
   }
};

int main() {
   base* b = new derived;
   derived* d = b;
   
   b->method();
   d->method();
}

http://liveworkspace.org/code/aaeea40f6406...fc4d55be44c2c25

зы
на практике никогда такого не делал. честное слово.
PM WWW   Вверх
azesmcar
Дата 3.6.2011, 15:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


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

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



Цитата(boostcoder @  3.6.2011,  15:05 Найти цитируемый пост)
с таким же успехом можно сказать и о наследовании. и о программировании в целом.

Нет, почему же.
Необходимость делать downcast должна настораживать программиста, а например необходимость использования оператора if - нет, впрочем как и использование наследования.

Цитата(boostcoder @  3.6.2011,  15:05 Найти цитируемый пост)
и естественно, предполагается, что прогер наделен моцгом. иначе не каст станет серьезной ошибкой, а сам факт существования такого прогера smile

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

Цитата(boostcoder @  3.6.2011,  15:05 Найти цитируемый пост)
ладно, компилятор недоволен. но на практике это к чему привести может в том случае, что подобный каст используется только в приведенном примере?:

Где тут cast? Я вообще понятия не имею как этот пример компилируется (если компилируется) и как компилятор должен повести себя в такой ситуации.
Код

#include <iostream>

struct base { virtual void method(); };
struct derived: base {
   virtual void method() {
      std::cout << "derived::method()" << std::endl;
   }
};

int main() {
   base* b = new base; // <----
   derived* d = b;
   
   b->method();
   d->method();
}

PM   Вверх
mes
Дата 3.6.2011, 17:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(boostcoder @  3.6.2011,  14:05 Найти цитируемый пост)
с таким же успехом можно сказать и о наследовании. и о программировании в целом.

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

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




Это сообщение отредактировал(а) mes - 3.6.2011, 17:14


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


Опытный
**


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

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



когда я писал пост http://forum.vingrad.ru/index.php?showtopi...t&p=2356159

этот же online компилятор выдавал мне приведенный error. Сейчас он компилирует код. О_о
Код

#include <iostream>
#include <string>

class A {public: A(){}};

class B : public A {
 public: B(){}
 std::string s;
};

class C : public A{
public:
 C(){}
 int a; 
};

int main()
{
   A* a = new B();
   
   B* b;
   C* c;
   
   b = a;
   c = a;
   
   b->s = "O_o";
   c->a = 10;
}

http://liveworkspace.org/code/a449910606cf...37cf3deb0d590f6

Девид Блейн, отдыхает.


Это сообщение отредактировал(а) cupper - 3.6.2011, 18:11
PM MAIL   Вверх
boostcoder
Дата 3.6.2011, 17:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

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



Цитата(cupper @  3.6.2011,  17:44 Найти цитируемый пост)
class base {};
class derived: base {};

значит, все же, struct отличается от class в с++

Добавлено через 7 минут и 30 секунд
Код

#include <iostream>

class base {
public:
   virtual void method() = 0;
};
class derived: public base {
public:
   virtual void method() {
      std::cout << "derived::method()" << std::endl;
   }
};

int main() {
   base* b = new derived;
   derived* d = b;
   
   b->method();
   d->method();
}

http://liveworkspace.org/code/8f1f86dea05b...807f74b33a42c98

все таки разницы никакой smile 
PM WWW   Вверх
boostcoder
Дата 3.6.2011, 18:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

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



Цитата(cupper @  3.6.2011,  17:44 Найти цитируемый пост)
когда я писал пост http://forum.vingrad.ru/index.php?showtopi...t&p=2356159

этот же online компилятор выдавал мне приведенный error. Сейчас он компилирует код. О_о

это моя вина. я кое-что проверял вчера днем, и добавил в опции "-fpermissive". исправил. сорри smile 
теперь нужно все тесты проверять заново..

Добавлено @ 18:29
мля.. нехорошо получилось..

Это сообщение отредактировал(а) boostcoder - 3.6.2011, 18:29
PM WWW   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

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

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

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

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


 




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


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

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