2016-08-04 2 views
0

Я знаю о Virtual Class, что они не могут быть инстанцированными, Теперь у меня есть вопрос о том случае, об этом, предположу, что у нас есть чисто абстрактный класс, как показано ниже:Как использовать абстрактный класс в другом классе (или любом классе)?

class Color{ 
public: 
    Color(); 
    virtual string getName()=0; 
    ~Color(); 
}; 

и 2 класса унаследованной формы она:

class Blue:public Color 
{ 
public: 
    Blue(); 
    ~Blue(); 
    string getName(); 
}; 

class Red:public Color{ 
public: 
    Red(); 
    ~Red(); 
    string getName(); 
}; 

и третий класс хочет использовать Color класс в качестве параметра конструктора и члена данных:

class Foo{ 
public: 
    Foo(); 
    Foo(Color&); 
    ~Foo(); 
    void draw(Color&); 
private: 
    Color* co; 
}; 

и его реализация:

Foo::Foo():co(new Color()){ 
} 

Foo::Foo(Color &c):co(new Color(c)){ 
} 

Теперь, я знаю об этой части new Color() и new Color(c) является неправильным в этом случае, но я хочу использовать только тип Color к пройденному в Foo и непосредственно не используя Blue или Red как параметр.

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

tnx для вашего ответа.

+0

Инициализировать 'co' как нулевой указатель в конструкторе по умолчанию? –

+0

@Joachim Pileborg Нет, я не использовал. – mehdi

ответ

1

Для конструктора, который принимает цвет &, вы можете сохранить ссылку или указатель на переданный в цвете, если вы можете быть уверены, что его будет продолжать существует или умный указатель может быть подходящим для вашего использования, если вы хотите сохранить указатель на ранее существующий цвет и убедитесь, что он не был удален слишком рано. Или, если вы хотите, чтобы ваш класс сохранил свою собственную копию цвета, вы можете использовать шаблон клонирования. Конструктор копирования для цвета должен возвращать цвет (а не производный от него класс), что невозможно, так как цвет является абстрактным. Clone будет виртуальной функцией в цвете, возвращающей указатель цвета. В производных классах он реализуется для возврата нового экземпляра производного типа.

class Color 
{ 
    public: 
    virtual Color* Clone() const = 0; 
}; 

class Red : public Color 
{ 
    public: 
    virtual Red* Clone() const 
    { 
     return new Red(*this); // updated to use copy constructor 
    } 
}; 

Foo::Foo(const Color& c) : co(c.Clone()) 
{} 

Для конструктора по умолчанию Foo вам нужно выбрать, будет ли его OK для цвета Foo в * элемент будет пустым, если она затем проходит в nullptr как это было предложено. Если нет, вы можете выбрать цвет по умолчанию для инициализации цвета *. Примечание. Foo по-прежнему сохраняет цвет * не красный *. Можно указать класс цвета по умолчанию с ЬурейиМ или с помощью заявления, чтобы убедиться, что вы определяете по умолчанию только один раз: -

using DefaultColour = Red; 
Foo::Foo() : co(new DefaultColour()) {} 

Или просто не дает Foo конструкции по умолчанию - настаивают на том, что цвет обеспечивается

+0

tnx очень для вашего превосходного exapalation, я новичок в C++, и вы сказали об умном указателе, можете ли вы рассказать мне, как я его использую, если вам нравится, и вы сказали о стандартном цветовом классе с typedef или использованием инструкции, как это сделать? Класс DefaultColour? – mehdi

+1

относительно цвета по умолчанию - это оператор using в приведенном выше примере. (typdef был бы более старым способом сделать то же самое). Это псевдоним для вашего класса, в данном случае я говорю, что по умолчанию красный, я могу тогда ссылаться на DefaultColour везде, где он мне нужен, но если я решим изменить значение по умолчанию на «Синий», нужно изменить только одну строку (линия с использованием). Это также помогает сделать код самодокументированным в том случае, когда вы используете DefaultColor, он показывает, что вы используете его, потому что его по умолчанию, а не что-то особенное, это красный или синий. – ROX

+1

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

1

Инициализировать указатель члена в nullptr:

Foo::Foo() : co(nullptr) {} 
Foo::Foo(Color &c) : co(nullptr) {} 
+1

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