Ответы пользователя по тегу C++
  • Как реализовать downcast к шаблону?

    Wyrd
    @Wyrd
    Архитектор
    Кажется вы ищете паттерн Visitor https://ru.m.wikipedia.org/wiki/Посетитель_(шаблон...
    Ответ написан
    Комментировать
  • Boost.python и указатели

    Wyrd
    @Wyrd
    Архитектор
    Предположение: цепляется не та либа-переходник (имеется в виду что-то вроде boost_python-vc100-mt-gd-1_43.dll). Возможно, у вас ее имя без версии (можно так буст настроить)? возможно вы обновили буст а либу не пересобрали?

    Предположение 2 (сомнительное): С++ часть скомпилирована не под тот питон, которым запускают?
    Ответ написан
    2 комментария
  • Boost.python и указатели

    Wyrd
    @Wyrd
    Архитектор
    Честно говоря, никогда не пользовался этой штуковиной, но ради интереса решил попробовать.
    И… все заработало (с учетом мелких поправок кода для «компилябельности»).

    hello.cpp:
    #include <boost/python.hpp>
     
    using namespace boost;
    using namespace boost::python;
     
    struct Foo
    {
       virtual ~Foo() {}
       virtual void Print() = 0;
    };
     
    struct FooWrap : Foo, wrapper<Foo>
    {
        void Print()
        {
            this->get_override("Print")();
        }
    };
     
    void ProcessFoo(Foo *obj) { obj->Print(); }
     
    BOOST_PYTHON_MODULE(hello_ext)
    {
        class_<FooWrap, boost::noncopyable>("Foo")
            .def("Print", pure_virtual(&Foo::Print));
        def("ProcessFoo"&ProcessFoo);
    }


    hello.py:
    import hello_ext
     
    class NewFoo(hello_ext.Foo):
       def Print(self):
          print 'Print call'
     
    hello_ext.ProcessFoo( NewFoo() )


    Запуск:
    E:Temppython>"d:/Coding/Python 2.7/python.exe" hello.py
    Print call


    Тех. данные:
    boost 1.43
    MSVS 2010 SP1
    python 2.7
    компилировалось с помощью bjam
    Ответ написан
    2 комментария
  • RTTI vs Шаблонная магия?

    Wyrd
    @Wyrd
    Архитектор
    Вот вам еще вариант:
    pastebin.com/RZAY789w

    умеет:
    typedef std::unique_ptr< IObject > ptr;
     
    ptr p = CreateObject< Object3 >();
    assert( FastObjectCast< Object3 >( p.get() ) );
    assert( FastObjectCast< Object1 >( p.get() ) ); // Object3 inherits Object1
    assert( !FastObjectCast< INamedObject >( p.get() ) ); // p is unnamed Object3
     
    ptr q = CreateObject< Object3 >( "some name" );
    assert( FastObjectCast< Object3 >( q.get() ) );
    assert( FastObjectCast< Object1 >( q.get() ) ); // Object3 inherits Object1
    assert( FastObjectCast< INamedObject >( q.get() ) ); // p is named Object3
    INamedObject наследуется также реализует IObject
    FastObjectCast семантически эквивалентен dynamic_cast, но раз в 10 быстрее (dynamic_cast тоже можно использовать).

    p.s.
    Так нельзя делать:
    template<class T> T * As() { return (T*)this; }
    Нужно использовать static_cast, т.к. после каста указатель может поменять значение на пару байт (это происходит из-за множественного наследования, если оно есть в иерархии).
    Ответ написан
    Комментировать
  • Возможна ли инициализация const-строки не в конструкторе?

    Wyrd
    @Wyrd
    Архитектор
    >> Таким образом, происходит двойное присвоение, сначала str = new, затем memcpy(str,...).
    никакого двойного присваивания не происходит

    str = new unsigned char[size];

    только выделяет память и запоминает, где эта память выделена, сама память не инициализируется.

    копирование данных происходит внутри memcpy.

    справедливости ради, если у вас typeof( str ) == typeof( usigned const char * ), то вы не сможете вызвать memcpy без приведения типа, т.к. у вас указатель на неизменяемые данные.

    вам надо:

    class A
    {
    private:
    unsigned const char *str;
    A(): str( nullptr ) // можно и не инициализировать в принципе, если уверены,
    // что не будете читать его до инициализации
    {
    }
    init(… )
    {
    unsigned char *ptr = new unsigned char[size];
    memcpy( ptr,… );
    str = ptr; // сами данные вы тут не меняете, только указатель на данные
    }
    usigned const char *get() const{ return str; }
    };
    Ответ написан
    Комментировать
  • Возможна ли инициализация const-строки не в конструкторе?

    Wyrd
    @Wyrd
    Архитектор
    unsigned char* const — это константный указатель на изменяемый массив char

    вам нужен

    const unsigned char * — неконстантный указатель на неизменяемый массив char

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

    пруф: habrahabr.ru/post/100104/
    Ответ написан
    Комментировать