Поскольку другие сказали SQL, 2008 идет с типом Filestream, который позволяет Вам хранить имя файла или идентификатор как указатель в дб и автоматически хранит изображение в Вашей файловой системе, которая является замечательным сценарием.
, Если бы Вы находитесь на более старой базе данных, тогда я сказал бы, что при хранении ее как данных блоба, тогда Вы действительно не собираетесь вытаскивать что-либо из базы данных в способе искать функции, таким образом, вероятно, лучше сохранить адрес в файловой системе и сохранить изображение тот путь.
Тот способ, которым Вы также оставляете свободное место в своей файловой системе, поскольку Вы только собираетесь сохранить точную сумму пространства или даже уплотненного пространства в файловой системе.
кроме того, Вы могли решить сохранить с некоторой структурой или элементами, которые позволяют Вам просматривать необработанные изображения в своей файловой системе без любых хитов дб, или передавать файлы оптом другой системе, жесткому диску, S3 или другому сценарию - обновление местоположения в Вашей программе, но сохранять структуру, снова без большой части хита, пытающегося вывести изображения из Вашего дб при попытке увеличить устройство хранения данных.
, Вероятно, это также позволило бы Вам бросать некоторый кэширующийся элемент, на основе обычно URL изображения хита в Ваш веб-механизм/программу, таким образом, Вы сохраняете себя там также.
Если я вас правильно понимаю, это может сделать то, что вы хотите:
template<typename T>
class CVector { ... };
template<typename T>
class CVector<T*> : public CVector< SomeWrapperClass<T> > {
public:
// for all constructors:
CVector(...) : CVector< SomeWrapperClass<T> >(...) {
}
};
Он добавляет дополнительный уровень наследования, чтобы обмануть CVector
, превратив его в CVector
. Это также может быть полезно в случае, если вам нужно добавить дополнительные методы для обеспечения полной совместимости между ожидаемым интерфейсом для T *
и предоставленным интерфейсом для SomeWrapperClass
.
Это прекрасно работает в C ++ ...
#include <iostream>
template <class T>
class CVector
{
public:
void test() { std::cout << "Not wrapped!\n"; }
};
template <class T>
class CVector<T*>
{
public:
void test() { std::cout << "Wrapped!\n"; }
};
int main()
{
CVector<int> i;
CVector<double> d;
CVector<int*> pi;
CVector<double*> pd;
i.test();
d.test();
pi.test();
pd.test();
}
Я не думаю, что вы можете специализировать класс, используя описанный вами синтаксис ... Я не знаю, как это могло бы работать. Что вы можете сделать, так это специализировать класс для указателей и заново реализовать его внутренности, используя класс-оболочку вокруг необработанных указателей. Не уверен, что это поможет, но эта статья описывает специализированные шаблоны для указателей.
Библиотека свойств типа Boost может помочь вам в этом. Обратите внимание на свойство типа is_pointer .
#include <boost/type_traits.hpp>
#include <iostream>
#include <vector>
using namespace std;
template <class T>
class CVector {
public:
void addValue(const T& t) {
values_.push_back(t);
}
void print() {
typedef boost::integral_constant<bool,
::boost::is_pointer<T>::value> truth_type;
for (unsigned int i = 0; i < values_.size(); i++)
doPrint(values_[i], truth_type());
}
private:
void doPrint(const T& t, const boost::false_type&) {
cout << "Not pointer. Value:" << t << endl;
}
void doPrint(const T& t, const boost::true_type&) {
cout << "Pointer. Value: " << *t << endl;
}
std::vector<T> values_;
};
int main() {
CVector<int> integers;
integers.addValue(3);
integers.addValue(5);
integers.print();
CVector<int*> pointers;
int three = 3;
int five = 5;
pointers.addValue(&three);
pointers.addValue(&five);
pointers.print();
}
Я не думаю, что шаблоны настолько гибкие.
Подход с использованием грубой силы - это специализация для всех типов указателей ... что решает проблему использования шаблонов.
Можно ли использовать другой класс CVector, который будет использоваться только для векторов указателей?