разыменование это вызывает ошибку сегментации

У меня есть следующие функции

LinearScheme::LinearScheme() {
cout << " empty constructor" << endl;
}void LinearScheme::init(
int tableId,
std::string &basePath,
std::vector<size_t> &colElemSizes,
TupleDescMap &tupleDescMap,
size_t defaultMaxFragmentSize,
int numCols,
BoundBases &bounds,
std::vector<int> &colsPartitioned )
{
// This linear scheme ignores bounds
// it could be improved to use colsPartitioned for ordering (TODO)
cout << "init Linear Scheme " << endl;

*this = LinearScheme(); //SEGFAULTS HERE

cout << "after cons here?" << endl;
// init private fields
this->tableId_ = tableId;
this->basePath_ = basePath;
this->colElemSizes_ = colElemSizes;
this->numCols_ = numCols;
this->tupleDescMap_ = tupleDescMap;
this->numFragments_ = 0;
this->defaultMaxFragmentSize_ = defaultMaxFragmentSize;

// fragmentSizesFilename_ init
fragmentSizesFilename_  = basePath_ + boost::lexical_cast <string>(tableId_)
+ "_cs";
struct stat st;
// open existing file if exists. Create new otherwise.
if (stat(fragmentSizesFilename_.c_str(), &st) == 0) // file existed
openExisting();
else
createNew();
}

Причина, по которой я инициализирую в init а не конструктор, потому что LinearScheme расширяет PartitionScheme (суперкласс с виртуальными методами) класс и другой класс делают это, где конструктор используется рекурсивно.

у меня есть QuadTree класс, который делает ту же инициализацию, потому что каждый QuadTree Конструктор применяется рекурсивно. *this = QuadTree(bounds, maxSize) строка в функции инициализации QuadTree класс работает просто отлично.

однако эта строка в другом подклассе (LinearScheme) *this = LinearScheme() вызвать ошибку сегмента.

Есть идеи, почему это может произойти?

РЕДАКТИРОВАТЬ
Также замена строки:

*this = LinearScheme()

с этим:

*this;

или удаление его в целом избавляет от неисправности сега … почему?

-1

Решение

«… в другом подклассе (LinearScheme) *this = LinearScheme()«

«Конструктор LinearScheme пуст: LinearScheme::LinearScheme()«

если * это подкласс LinearMethod, конструктор LinearMethod уже должен был быть вызван, и эта строка бесполезна. Кроме того, он вызывает оператор присваивания — правильно ли он определен?

Лучше полагаться на встроенный механизм конструирования объектов. Если вы хотите избежать повторения кода, используйте C ++ 11 делегирующие конструкторы особенность. Он был специально разработан для устранения методов «init».

Хотя, «если существует бесконечно рекурсивный цикл (например, конструктор C1 делегирует другому конструктору C2, а C2 также делегирует C1), поведение не определено».

Так что это зависит от вас, чтобы избежать бесконечной рекурсии. В вашем QuadTree вы можете рассмотреть возможность создания nullptr указатели QuadTreeNode в конструкторе.

2

Другие решения

Похоже, неправильно factory method / builder / deferred construction использование. Для многих из этих шаблонов создания объектов функция, которая создает ваши объекты, должна быть статическим методом, потому что еще не существует экземпляра для манипулирования. В других вы потенциально можете манипулировать уже созданным экземпляром. В любом случае, если вы на самом деле создаете объект типа класса внутри функции, вы должны использовать new и в конечном итоге вернуть его.

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

Пример фабричного образца:

LinearScheme* LinearScheme::create(...all_your_args....) {

/* construct the thing we are building only if it
*  pass any arguments into him that he can handle directly if you'd like
*/
LinearScheme *out = new LinearScheme(...);

/* do whatever else you have to do */
....
return out;
}

или это helper виды, которые вы, кажется, хотите

/* this time let's just do 'init' on your object */
void LinearScheme::init(....args....) {
/* possibly check if init has been done already */
if ( this->init ) return;

/* proceed to do your initialization stuff
* but don't construct the 'this' instance since it should already exist
*/

this->init = true; //so we don't init again if you don't need multiple init's
}

В качестве альтернативы вы можете рассмотреть методы конструктора делегата в C ++ 11 alex.

Однако ни один из них действительно не кажется мне актуальной проблемой.

Это не работает, потому что либо у вас, вероятно, даже нет действительного *this к почтению. Это может быть связано с вашим использованием или с тем, что не удалось создать потенциально из-за бесконечной рекурсии.

Вот ссылка на шаблон википедии: http://en.wikipedia.org/wiki/Factory_method_pattern

Учитывая то, что вы сказали о необходимости передавать дюжину аргументов как родительским классам, так и вашей рекурсивной конструкции, вы можете рассмотреть одно предложение — создать небольшую конфигурационную структуру, которую вы передаете по ссылке, а не по всем дискретным параметрам. Таким образом, вам не нужно постоянно корректировать каждую сигнатуру при каждом добавлении / удалении другого параметра.

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

5

По вопросам рекламы [email protected]