2014-01-25 4 views
0

В настоящее время я изучаю C++, и для этого я пишу простой конвертер изображений.Дизайн классов, содержащих разные данные

Я хотел бы иметь базовый класс изображения, который содержит различные фрагменты памяти изображения, например DXTn или BMP. Как правильно спроектировать мой класс, который может содержать эти разные типы данных? Есть ли лучший способ хранения памяти в (умном) указателе?

class Image 
{ 
    public: 
     void loadDXT() { } 
     void loadBMP() { } 

    private: 
     char* data1; 
     std::unique_ptr< char* > data2; 
} 

Или было бы лучше, чтобы получить более конкретный classfrom простого BaseClass:

class baseImage 
{ 
    public: 
     enum imgType { BMP , DXT }; 
     void load() = 0; 
} 

class BMPImage : public baseImage 
{ 
    //bmp specific stuff here 
} 

Это не является специфичным только для этого ImageCLASS, я вообще любопытно, как мне создать классы которые содержат разные данные.

спасибо.

+2

Идите со вторым - он добавляет слой абстракции, сохраняя отдельные предметы отдельно. –

+0

Определенно второй. При написании C++ вы действительно хотите использовать абстрактные базовые классы, поскольку они являются основой ООП. –

ответ

1

Я согласен с jwg виртуальный абстрактный интерфейс сделает вашу жизнь проще.

Например:

class BaseImage//base class 
{ 
public: 
    virtual void DoThingsRelatedToAllImages_1()=0; 
    virtual void DoThingsRelatedToAllImages_2()=0; 
    //...and so on and whatever else 
private: 
    int DataUsedForAllImageTypes; 
}; 

//this is our child class 
class Bmp: public BaseImage 
{ 
    private: 
    int DataUsedOnlyForBmpTypeImages; 
}; 
void Bmp::DoThingsRelatedToAllImages_1() 
{ 
    //Do Whatever this function should do for a bitmap 
} 
void Bmp::DoThingsRelatedToAllImages_2() 
{ 
    //Do Whatever this function should do for a bitmap 
} 

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

Например:

class BaseImage//base class 
{ 
public: 
    virtual void DoThingsRelatedToAllImages_1(); 
    virtual void DoThingsRelatedToAllImages_2(); 
    //...and so on and whatever else 
private: 
    int DataUsedForAllImageTypes; 
}; 

void BaseImage::DoThingsRelatedToAllImages_1() 
{ 
    //Do Whatever this function should do for a base image 
} 
void BaseImage::DoThingsRelatedToAllImages_2() 
{ 
    //Do Whatever this function should do for a base image 
} 

//this is our child class 
class Bmp: public BaseImage 
{ 
    private: 
    int DataUsedOnlyForBmpTypeImages; 
}; 
void Bmp::DoThingsRelatedToAllImages_1() 
{ 
    //Do Whatever this function should do for a bitmap 
} 
void Bmp::DoThingsRelatedToAllImages_2() 
{ 
    //Do Whatever this function should do for a bitmap 
} 

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

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

+0

Спасибо за ваш ответ! Я думаю, вы все правы, абстрактный базовый класс должен быть способом. Но как я могу справиться со всеми этими производными классами? Я не хочу перегружать все функции, которые принимают изображение в качестве параметра. Нужно ли мне создавать для этого класс менеджера? – nonsensation

+0

вы можете использовать Полиморфизм для достижения этого. http://en.wikipedia.org/wiki/Polymorphism_(computer_science) Идея заключается в том, что вы пишете функцию, чтобы принять базовый класс, и передаете ему производный класс. Это может работать, потому что все классы изображений имеют общий базовый класс и поэтому являются «изображениями» и могут рассматриваться как общий образ. Сейчас я плохо разбираюсь, но думаю, что это может помочь. Еще раз вы можете заглянуть в шаблоны, но мое понимание шаблонов сейчас отсутствует. –

0

Я бы сказал, что второй метод определенно то, что вам нужно. Вы в основном указываете интерфейс - что бы вы использовали абстрактный класс для C++. Базовый класс должен содержать все функции, которые, по вашему мнению, должны иметь каждое изображение, возможно, как чистые виртуальные функции, поскольку нет общего изображения, которое реализует их одинаково для любого изображения. (У вас могут быть такие вещи, как общие метаданные, которые имеют одну и ту же структуру для каждого типа изображения, и их можно решать с помощью методов в базовом классе.)

Затем каждый класс будет реализовывать виртуальные функции на основе собственных личных данных сохраненный таким образом, который имеет смысл для этого типа изображения. Если некоторые типы изображений имеют некоторые, но не все операции, вы можете иметь несколько уровней наследования, например, RasterImage наследует от Image и BMPImage и PNGImage наследует от RasterImage.

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

+0

Благодарим за отзыв, очень ценим! Заглядывая в другие исходники, в основном это то, как я изучил C++ до сих пор, к сожалению, для этой проблемы библиотека не была достаточно простой. При использовании базового абстрактного класса существует ли класс менеджера, который обрабатывает все необходимые вещи? Причина в том, что я пытаюсь избежать функций перегрузки для каждого производного класса: 'void process (Image & img); // manageerclass/baseclass? 'вместо:' void process (BMPImage & img); 'и' void process (PNGImage & img); ' – nonsensation

Смежные вопросы