2010-06-03 3 views
1

предположим, что я хочу, чтобы мои пользователи использовали только один класс, скажем, SpecialData. Теперь этот класс данных будет иметь много методов, и в зависимости от типа данных методы делают разные вещи, внутренне, но возвращают внешне похожие результаты. Поэтому мое желание иметь один «открытый» класс и другие «частные», дочерние классы, которые изменят поведение методов и т. Д.Создайте экземпляр из статического метода

Было бы удивительно проще для некоторых типов данных, которые необходимо построить чтобы сделать что-то вроде этого:

SpecialData& sm = SpecialData::new_supermatrix(); 

и new_supermatrix() возвращает экземпляр суперматричного, который наследуется от большинства поведения SpecialData.

мой заголовок:

static SpecialData& new_supermatrix(); 

мой каст:

SpecialData& SpecialData::new_supermatrix()(){ 
    return SuperMatrix(MATRIX_DEFAULT_MAGNITUDE,1000,1239,FLOAT32,etc...); 
} 

Проблема заключается в том, я получаю эту ошибку, которая, вероятно, логично в силу обстоятельств:

недействительным инициализации неконстантной ссылки типа «SpecialData &» из временного типа «SpecialData»

Итак, любые идеи?

+0

Вам нужно узнать, как работает стек. –

+0

действительно, спасибо всем за ответы. Я думаю, что я буду придерживаться пространства имен на фабрике. – Manux

ответ

3

Ну, у вас есть три варианта:

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

b) Вы хотите создать несколько экземпляров. Тогда вы есть вернуть указатель вместо ссылки и создавать объекты с новыми (т.е. return new SuperMatrix(...).

с) В качестве альтернативы вариант б, вы также можете вернуть только объект, т.е.

SpecialData SpecialData::new_supermatrix()(){ 
return SuperMatrix(MATRIX_DEFAULT_MAGNITUDE,1000,1239,FLOAT32,etc...); 
} 

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

Независимо от того, что вы собираетесь с этим делать, эти решения являются взаимоисключающими, как технически, так и логически. ;)

0

Необходимо использовать оператора new. Создание, которое вы получаете на return SuperMatrix(MATRIX_DEFAULT_MAGNITUDE,1000,1239,FLOAT32,etc...);, выделяет объект в стеке, который очищается, когда функция возвращается (что она делает в той же строке). Использование new заставляет его выделяться в куче.

2

Простой ответ - вы не можете использовать такие ссылки. Ваша функция new_supermatrix возвращает безымянное временное значение, которое вы пытаетесь связать с неконстантной ссылкой. C++ позволяет только такие значения привязываться к ссылкам const. Если вы хотите написать такие функции, вам нужно заставить их вернуть указатель на динамически выделенный объект или приклеить с возвратом значение, но назначить возвращаемое значение другому значению в вызывающем коде.

1

Этот код имеет несколько проблем. Прежде всего, вы, вероятно, захотите использовать указатели здесь вместо ссылок. Возвращение ссылки на объект, созданный в стеке, как и в вашем new_supermatrix, приведет к сбою почти сразу. Он должен быть выделен new и передан как указатель, если это то, что вы хотите, но я не совсем уверен, что вы пытаетесь сделать. Но так или иначе, это то, что вызывает вашу ошибку, вы возвращаете ссылку на временную переменную.

0

В вашем методе, вы можете использовать static:

SpecialData& SpecialData::new_supermatrix()(){ 
    static SuperMatrix supermatrix(MATRIX_DEFAULT_MAGNITUDE,1000,1239,FLOAT32,etc...); 
    return supermatrix; 
} 
0

Вы не должны возвращать ссылку на временный/локальный объект.

Это и многие другие распространенные ошибки, которые следует избегать, объясняются в книге Мейерса, Эффективный C++.

0

Вы возвращаете ссылку на временный объект, который представляет собой плохую новость, так как после выхода вашего метода объект больше не существует.

Читайте также: creational design patterns. Тот, который наиболее близок к тому, что вы хотите сделать, - это шаблон Factory Method.

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