Как я могу получить полиморфное поведение в конструкторе C++?

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

Это сделано более хитрым все еще тем, что сам объект сессии сериализируется - так как у Django нет способа знать, какие данные точно Вы хотите хранить, это просто сериализирует словарь данных сессии в строку (использующий стандартный модуль "рассола" Python) и материалы это в Вашу базу данных.

, Если у Вас есть сеансовый ключ (который будет отправлен браузером пользователя как значение cookie "sessionid"), самый легкий способ достигнуть данные состоит в том, чтобы просто запросить таблицу Session для сессии с тем ключом, который возвращает объект Сессии. Можно тогда назвать тот объект "get_decoded ()" метод для получения словаря данных сессии. Если Вы не используете Django, можно посмотреть на исходный код (django/contrib/sessions/models.py), чтобы видеть, как данные сессии десериализовываются.

, Если у Вас есть идентификатор пользователя, однако, необходимо будет циклично выполниться через все объекты Сессии, десериализовывая каждого и ища того, который имеет ключ, названный "_auth_user_id", и для которого значение того ключа является идентификатором пользователя.

5
задан BCS 21 September 2009 в 07:14
поделиться

4 ответа

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

Вам следует переосмыслить свой дизайн - например, передать константу в качестве аргумента конструктору.

class B
{
public:
    explicit B(int i)
    {
        something(i);
    }
};

См. часто задаваемые вопросы по C ++ для получения дополнительной информации. Если вы действительно хотите вызывать виртуальные функции во время построения, прочтите это .

7
ответ дан 14 December 2019 в 08:55
поделиться

Это не сработает, поскольку производный класс еще не существует, когда выполняется конструктор базового класса:

class Base
{
public:
    Base()
    {
        // Will call Base::I and not Derived::I because
        // Derived does not yet exist.
        something(I());
    }

    virtual ~Base() = 0
    {
    }

    virtual int I() const = 0;
};

class Derived : public Base
{
public:
    Derived()
     : Base()
    {
    }

    virtual ~Derived()
    {
    }

    virtual int I() const
    {
        return 42;
    }
};

Вместо этого вы можете добавить аргументы в конструктор базового класса:

class Base
{
public:
    explicit Base(int i)
    {
        something(i);
    }

    virtual ~Base() = 0
    {
    }
};

class Derived : public Base
{
public:
    Derived()
     : Base(42)
    {
    }

    virtual ~Derived()
    {
    }
};

Или если вы действительно любите ООП, вы также можете создать пару дополнительных классов:

class Base
{
public:
    class BaseConstructorArgs
    {
    public:
        virtual ~BaseConstructorArgs() = 0
        {
        }

        virtual int I() const = 0;
    };

    explicit Base(const BaseConstructorArgs& args)
    {
        something(args.I());
    }

    virtual ~Base() = 0
    {
    }
};

class Derived : public Base
{
public:
    class DerivedConstructorArgs : public BaseConstructorArgs
    {
    public:
        virtual ~DerivedConstructorArgs()
        {
        }

        virtual int I() const
        {
            return 42;
        }
    };

    Derived()
     : Base(DerivedConstructorArgs())
    {
    }

    virtual ~Derived()
    {
    }
};
0
ответ дан 14 December 2019 в 08:55
поделиться

Вам нужна двухфазная конструкция . Воспользуйтесь средством универсального программиста: добавьте еще один уровень косвенности.

0
ответ дан 14 December 2019 в 08:55
поделиться

Возможно, использовать статический фабричный метод для каждого производного типа? Это обычный способ создания экзотических объектов (читай: объектов с очень специфическими требованиями к инициализации) в .NET, который я оценил.

0
ответ дан 14 December 2019 в 08:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: