Reputation: 117
I've designed a class InputField
having a constructor with 2 parameters : explicit InputField(InputFieldIndex uiIndex, QString sName) noexcept;
I store this class in a QVector
, so, unfortunately, I have to add a default-contructor. In term of software design, that's not good for me (because I have a constraint on uiIndex
).
Is there a way to only allow to QT (QVector
in my case) to call the default constructor? A macro or a preprocessor instruction?
Upvotes: 2
Views: 316
Reputation: 98435
There's no need for QVector
to call the default constructor; std::vector
doesn't, after all - not unless you use one of its methods that need that constructor. All you need is to disable default-construction in QVector
:
#define QVECTOR_NON_DEFAULT_CONSTRUCTIBLE(Type) \
template <> QVector<Type>::QVector(int) = delete; \
template <> void QVector<Type>::resize(int newSize) { \
Q_ASSERT(newSize <= size()); \
detach(); \
} \
template <> void QVector<Type>::defaultConstruct(Type*, Type*) { Q_ASSERT(false); }
Then, put the macro in the same place you'd put Q_DECLARE_METATYPE
: right where the type is declared:
class InputField {
...
};
QVECTOR_NON_DEFAULT_CONSTRUCTIBLE(InputField)
Then you can use QVector<InputField>
with same limitations as std::vector
would have.
Upvotes: 1
Reputation: 735
You can try to make QVector<InputField>
a friend class.
Consider the following toy example:
class Foo {
// Grant QVector<Foo> access to this class' internals
friend class QVector<Foo>;
public:
explicit Foo(int a, bool b) {
// Empty
}
private:
Foo() {
// Callable by this class and QVector<Foo>.
}
};
With this, it is possible to store instances of Foo
in a QVector<Foo>
:
QVector<Foo> myList;
myList << Foo(1, true) << Foo(2, false);
However, the following would e.g. fail:
Foo foo;
Upvotes: 5