Joseph Garnier
Joseph Garnier

Reputation: 117

Constraint on constructor calling

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

Answers (2)

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

Martin H&#246;her
Martin H&#246;her

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

Related Questions