С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/6: Рейтинг темы: голосов - 6, средняя оценка - 4.50
495 / 209 / 70
Регистрация: 27.05.2016
Сообщений: 557

Тип производного класса

25.08.2016, 15:45. Показов 1254. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Как можно узнать тип производного класса на этапе компиляции?
C++
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
#include <type_traits>
 
struct A {};
struct B : A {};
 
int main()
{
    A* pa = new B();
    static_assert(std::is_same<B, decltype(*pa)>::value, "*pa must be B type");
}
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
25.08.2016, 15:45
Ответы с готовыми решениями:

Как узнать тип производного класса в функции базового
Всем привет! Есть иерархия классов: class1 -&gt; class2-&gt;class3 class2-&gt;class4 class2-&gt;class5 Где...

Почему объект производного класса не видит префиксный оператор из базового класса?
Короче создал я базовый класс с перегруженным префиксным оператором ++. Потом чтоб его затюнинговать, сделал ему производный класс с...

Как сложить объект базового класса с объектом производного(наследуемого класса)
Как умножить объект базового класса с объектом производного(наследуемого класса): ozenka - объект базового класса, а ves- производного ...

6
829 / 253 / 34
Регистрация: 27.07.2016
Сообщений: 497
Записей в блоге: 1
25.08.2016, 15:52
Цитата Сообщение от notAll Посмотреть сообщение
Как можно узнать тип производного класса на этапе компиляции?
Никак, на то оно и сделано для этапа исполнения.
1
495 / 209 / 70
Регистрация: 27.05.2016
Сообщений: 557
25.08.2016, 16:06  [ТС]
Тогда такой вопрос: как мне сконструировать ValuePtrt с правильным производным типом, так как это делает shared_ptr?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <iostream>
#include <memory>
 
template <typename T>
class ValuePtr
{
    T* p_;
    template <typename U> friend class ValuePtr;
 
public:
    explicit ValuePtr(T* p = nullptr) : p_(p) {}
    ~ValuePtr() { delete p_; }
    T& operator * () const { return *p_; }
    T* operator -> () const { return p_; }
 
    void swap(ValuePtr& other) noexcept { std::swap(p_, other.p_); }
 
    ValuePtr(const ValuePtr& other)
            : p_(other.p_ ? new T(*other.p_) : nullptr) {}
 
    ValuePtr& operator = (const ValuePtr& other)
    {
        ValuePtr temp(other);
        swap(temp);
        return *this;
    }
 
    template <typename U>
    ValuePtr(const ValuePtr<U>& other)
            : p_(other.p_ ? new T(*other.p_) : nullptr) {}
 
    template <typename U>
    ValuePtr& operator = (const ValuePtr<U>& other)
    {
        ValuePtr temp(other);
        swap(temp);
        return *this;
    }
};
 
struct A
{
    std::string aname{"A"};
    virtual void print() const { puts(aname.c_str()); }
};
struct B : A
{
    std::string bname{"B"};
    void print() const override { puts(bname.c_str()); }
};
 
int main()
{
    ValuePtr<A> a1(new B);
    a1->print(); // B
 
    ValuePtr<A> a2(a1);
    a2->print(); // A
 
    std::shared_ptr<A> a3(new B);
    a3->print(); // B
 
    std::shared_ptr<A> a4(a3);
    a4->print(); // B
}
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
25.08.2016, 16:12
Цитата Сообщение от notAll Посмотреть сообщение
как мне сконструировать ValuePtrt с правильным производным типом, так как это делает
Нужен шаблонный конструктор + идиома type erasure.
2
2393 / 1914 / 763
Регистрация: 27.07.2012
Сообщений: 5,558
25.08.2016, 16:12
C++
1
2
    ValuePtr(const ValuePtr& other)
            : p_(other.p_ ? new T(*other.p_) : nullptr) {}
А зачем создавать новый объект? Надо просто скопировать указатель.
0
495 / 209 / 70
Регистрация: 27.05.2016
Сообщений: 557
25.08.2016, 17:45  [ТС]
Цитата Сообщение от John Prick Посмотреть сообщение
А зачем создавать новый объект?
Просто класс должен вести себя как значение, а не указатель.

Добавлено через 1 час 27 минут
DrOffset, а можно какой то небольшой пример кода? Пробовал разные варианты, но никак не могу понять как получить тип наследников. Я хоть на верном пути?:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
template <typename T>
class ValuePtr
{
    template <typename U> friend class ValuePtr;
 
    struct base_holder
    {
        virtual ~base_holder() {}
        virtual const std::type_info& type_info() const = 0;
        virtual T* get_pointer() const = 0;
    };
 
    //template <typename TE>
    struct holder : base_holder
    {
        T* t_;
        holder(T* t) : t_(t) {}
 
        const std::type_info &type_info() const override
        {
            return typeid(t_);
        }
 
        ~holder() { delete t_; }
 
        T* get_pointer() const override { return t_;}
    };
 
    base_holder* held_;
 
public:
    template <typename U>
    explicit ValuePtr(U* p = nullptr) : held_(new holder(p)) {}
    
 
    template <typename U>
    ValuePtr(const ValuePtr<U>& other) :  held_(new holder(new HowGetDerivedType(*other))) {}
 
    ~ValuePtr() { delete held_; }
 
    T& operator * () const { return *held_->get_pointer(); }
    T* operator -> () const { return held_->get_pointer(); }
 
};
 
 
struct A
{
    std::string aname{"A"};
    virtual void print() const { puts(aname.c_str()); }
};
 
struct B : A
{
    std::string bname{"B"};
    void print() const override { puts(bname.c_str()); }
};
 
int main()
{
    ValuePtr<A> a1(new B);
    a1->print();
 
    ValuePtr<A> a2(a1);
    a2->print();
}
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
25.08.2016, 21:14
Лучший ответ Сообщение было отмечено notAll как решение

Решение

Цитата Сообщение от notAll Посмотреть сообщение
а можно какой то небольшой пример кода?
В простейшем случае код может выглядеть так:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
template <typename T>
class ValuePtr
{
    struct HolderBase
    {
    public:
        explicit HolderBase(T * ptr)
            : m_ptr(ptr)
        { }
 
        virtual ~HolderBase()
        { }
 
        virtual HolderBase * clone() const = 0;
 
        T * get() const
        {
            return m_ptr;
        }
 
    private:
        T * m_ptr;
    };
//    template <typename U>
//    friend class ValuePtr;
 
    template <typename U>
    struct Holder : public HolderBase
    {
        explicit Holder(U * ptr)
            : HolderBase(ptr)
        { }
        Holder(Holder const & ptr)
            : HolderBase(ptr.get() ? new U(*ptr.get()) : nullptr)
        { }
        ~Holder()
        {
            delete get();
        }
 
        Holder * clone() const
        {
            return new Holder(*this);
        }
 
        U * get() const
        {
            return static_cast<U *>(HolderBase::get());
        }
    };
 
public:
    template <typename U>
    explicit ValuePtr(U * p = nullptr)
        : m_holder(new Holder<U>(p))
    { }
 
    T & operator * () const
    {
        return *m_holder->get();
    }
    T * operator ->() const
    {
        return m_holder->get();
    }
 
    void swap(ValuePtr & other) noexcept
    {
        std::swap(m_holder, other.m_holder);
    }
 
    ValuePtr(const ValuePtr & other)
        : m_holder(other.m_holder->clone())
    { }
 
    ValuePtr& operator=(const ValuePtr& other)
    {
        ValuePtr temp(other);
        swap(temp);
        return *this;
    }
 
//    template <typename U>
//    ValuePtr(const ValuePtr<U> & other)
//        : m_holder(other.m_holder->clone())
//    { }
 
//    template <typename U>
//    ValuePtr & operator= (const ValuePtr<U> & other)
//    {
//        ValuePtr temp(other);
//        swap(temp);
//        return *this;
//    }
private:
    std::unique_ptr<HolderBase> m_holder;
};
http://rextester.com/LONEUQ75111
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
25.08.2016, 21:14
Помогаю со студенческими работами здесь

Вызов метода производного класса через обращение к методу базового класса
Добрый день. Изучаю основы ООП, наткнулся на проблему. Если создавать классы внутри main.cpp, то всё нормально. Если же создавать в...

Указатель на объект базового класса и адрес объекта производного класса
Пример кода: class Class1 { public: Class1(int x) { j = new int; *j = x; } ~Class1() {delete j;}

Вызвать конструктор производного класса без конструктора базового класса
Здравствуйте! У меня есть базовый класс треугольник и производный класс равносторонний треугольник.В конструкторе треугольника вводятся...

Создание указателя типа базового класса на экземпляр производного класса
Добрый день! Иногда видел коды, где создавался указатель типа базового класса на объект класса - наследника, для чего это может применяться?

Возможно ли указатель производного класса инициализировать объектом базового класса?
имеется связка наследуемых классов A-&gt;B а от B наследуются одновременно еще два класса B-&gt;C и B-&gt;D class A { public: ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути
Programma_Boinc 01.01.2026
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути Сочетание глобально распределённой вычислительной мощности и инновационных. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru