Абстрактный класс

128
13 мая 2021, 08:30

У меня есть некий абстрактный класс, назовем его Abs:

class Abs
{
protected:
    std::string str;
public:
    Abs(std::string str) : str(str) {}
    virtual void print() const = 0;
};

И от него наследуется какой-то класс Test:

class Test : public Abs
{
public:
    Test(std::string str) : Abs(str) {}
    void print() const override
    {
        std::cout << " str: " << str << std::endl;
    }
};

Также я имею класс DoubleTest, что хранит два объекта класса Test:

class DoubleTest
{
private:
    Test a;
    Test b;
public:
    DoubleTest() : a("test1"), b("test2")
    {
    }
    void print() const
    {
        a.print();
        b.print();
    }
};

Теперь я создаю указатель на тип абстрактного класса Abs:

Abs * ptr;

И могу выделить память под его наследника - Test.
Но я хочу чтобы была возможность выделить память и под тип DoubleTest. Понимаю, что для этого DoubleTest должен быть наследником класса Abs, но не понимаю как это реализовать.

Вопрос: Как сделать так, чтобы под указатель ptr можно было выделить память типа DoubleTest? Т.е., как его нужно правильно унаследовать, чтобы при этом он хранил два Test'a?

Глубоко извиняюсь за глупый вопрос. Большое спасибо!

Answer 1
class Abs
{
protected:
    std::string str;
public:
    Abs(std::string str) : str(str) {}
    virtual void print() const = 0;
};    
class Test : public Abs
{
public:
    Test(std::string str) : Abs(str) {}
    void print() const override
    {
        std::cout << " str: " << str << std::endl;
    }
};

Теперь вам нужно, чтобы DoubleTest содержал два экземпляра класса Test. Наследуя этот класс, вы получаете класс с одним жкземпляром Test. Добавьте туда еще один экземпляр и все...

class DoubleTest : public Test
{
private:    
    Test b;
public:
    DoubleTest() : Test("test1"), b("test2"){}
    void print() const override
    {
        Test::print(); //вывод базового
        b.print();      //вывод включаемого
    }
};    
int main() {    
    Abs* ptr = new DoubleTest;
    ptr->print(); 
    //...
    return 0;
}
Answer 2

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

# include <string>
# include <iostream>
class VeryAbs{
public:
virtual void print() const = 0;
};
class Abs:public VeryAbs
{
public:
    Abs(std::string str) : str(str) {}
    virtual void print() const = 0;
protected:
    std::string str;
};
class Test : public Abs
{
public:
    Test(std::string str) : Abs(str) {}
    void print() const override
    {
        std::cout << " str: " << str << std::endl;
    }
};
class DoubleTest:public VeryAbs
{
public:
    DoubleTest() : a("test1"), b("test2")
    {
    }
    virtual void print() const
    {
        a.print();
        b.print();
    }
private:
    Test a;
    Test b;    
};
int main(){
VeryAbs * dt = new  DoubleTest();
dt->print();
}
READ ALSO
Nemiver: при отладке rand() вылезает ошибка

Nemiver: при отладке rand() вылезает ошибка

При отладке функции rand() вылезает ошибка: Не удалось найти файл /build/glibc-LK5gWL/glibc-223/stdlib/random

98
Верстка Flex элементов при скролле по оси X

Верстка Flex элементов при скролле по оси X

Есть вот такой кодПри уменьшении ширины добавил скролл по оси x но элементы текст перепрыгивает на вторую строчку

156
Делаю django ЧПУ с помощью slug но выдает ошибку

Делаю django ЧПУ с помощью slug но выдает ошибку

Я хочу чтобы url выводилося названия статьи типо programs/kak-vzlomat-jopu или как то такИ еще настораживает то что как рагумент берет slug : 13 а это вообще...

160
Есть ли аналог GetKeyDown , но с touch

Есть ли аналог GetKeyDown , но с touch

Есть ли аналог GetKeyDown , но с тачамиУже пару часов роюсь в инете ,но так и не смог найти

301