Здравствуйте, Окунь, Вы писали:
О>Как-то столкнулся с проблемой. О>Есть два класса:
О>class A О>{ О> A(int); О> A(float); О>};
О>Можно ли написать конструктор класса B, чтобы для элементов массива B::а он не пытался вызвать конструктор по умолчанию, а вызывал бы, например, А(int); ?
class B {
char aaa_buffer[100 * sizeof(A)];
A *aaa;
B() {
aaa = (A *) aaa_buffer;
A *p = aaa;
for(int i = 0; i < 100; i++, p++) new (p) A(some_int_parameter);
}
};
О>Можно ли написать конструктор класса B, чтобы для элементов массива B::а он не пытался вызвать конструктор по умолчанию, а вызывал бы, например, А(int); ?
Нет, нельзя. Массив всегда инициализирует свои элементы вызовом конструктора по умолчанию.
Проблему можно обойти, если воспользоваться, например, std::vector:
#include <vector>
class A
{
public:
A(int) {}
A(float) {}
};
class B
{
std::vector<A> aaa;
public:
B() : aaa(100, A(1)) {}
};
Здравствуйте, Окунь, Вы писали:
О>Как-то столкнулся с проблемой. О>Есть два класса:
О>class A О>{ О> A(int); О> A(float); О>};
О>class B О>{ О> B(); О> A aaa[100]; О>};
О>Можно ли написать конструктор класса B, чтобы для элементов массива B::а он не пытался вызвать конструктор по умолчанию, а вызывал бы, например, А(int); ?
О>B::B() О>: //a ??? О>{ О>}
Ну прямо таки нельзя?
struct A
{
A(int i) : i_(i) {}
int i_;
};
template<int I>
struct B : A
{
B() : A(I) {}
};
B<55> arr[100]; // Создали массив А, в конструктор передаётся 55
Это частное решение. В принципе можно попробовать как-то обобщить.
Можно ли написать конструктор класса B, чтобы для элементов массива B::а он не пытался вызвать конструктор по умолчанию, а вызывал бы, например, А(int); ?
Здравствуйте, Roman Odaisky, Вы писали:
RO>Здравствуйте, sch, Вы писали:
sch>>[/c] RO>Опасно, даже очень.
RO>1) alignment RO>2) деструкторы придется вызывать ручками
RO>Или я не прав?
Прав, ну тогда
type arr[100];
for (unsigned int i = 100; i--;)
{
arr[i].~type();
new (&arr[i]) type(100);
}
Здравствуйте, Окунь, Вы писали:
О>Как-то столкнулся с проблемой. О>Есть два класса:
О>class A О>{ О> A(int); О> A(float); О>};
О>class B О>{ О> B(); О> A aaa[100]; О>};
О>Можно ли написать конструктор класса B, чтобы для элементов массива B::а он не пытался вызвать конструктор по умолчанию, а вызывал бы, например, А(int); ?
О>B::B() О>: //a ??? О>{ О>}
Super Solution (сочетает приемущества статического массива и возможности вызвать произвольный конструктор для объектов за счёт явного разделения фазы создания хранилища и инициализации):
template<typename Type, size_t Size>
class SuperArray
{
private:
boost::aligned_storage<Size * sizeof(Type), boost::alignment_of<Type>::value> arr_;
public:
template<typename P1>
SuperArray(P1 p1)
{
for (size_t i = 0; i < Size; ++i)
new (&((reinterpret_cast<Type*>(arr_.address()))[i])) Type(p1);
}
template<typename P1, typename P2>
SuperArray(P1 p1, P2 p2)
{
for (size_t i = 0; i < Size; ++i)
new (&((reinterpret_cast<Type*>(arr_.address()))[i])) Type(p1, p2);
}
// ... И т.д. Желательно заюзать BOOST_PP
~SuperArray()
{
for (size_t i = 0; i < Size; ++i)
((reinterpret_cast<Type*>(arr_.address()))[i]).Type::~Type();
}
Type& operator [] (size_t i)
{
return ((reinterpret_cast<Type*>(arr_.address()))[i]);
}
const Type& operator [] (size_t i) const
{
return ((reinterpret_cast<Type*>(arr_.address()))[i]);
}
};
Использование:
struct A
{
A(int i) : i_(i) {}
A(int i, bool b) : i_(i), b_(b) {}
bool b_;
int i_;
static void* operator new (size_t, A* p)
{
return p;
}
static void operator delete (void* p, A*)
{
}
};
SuperArray<A, 100> arr1(15);
SuperArray<A, 100> arr2(59, true);
Пока только до конца не понял, достаточно ли хранить как:
R>Super Solution (сочетает приемущества статического массива и возможности вызвать произвольный конструктор для объектов за счёт явного разделения фазы создания хранилища и инициализации):
Ну намутил!.. Это все один большой грязный хак. Автору надо хорошенько задуматься над выбором структуры данных, авось и велосипеды, комбинированные с граблями, не понадобятся. Кстати, тому конструктору, у которого один аргумент, не помешало бы explicit.
R>Пока только до конца не понял, достаточно ли хранить как: R>