On 8/21/19 11:12 PM, stdcerr wrote:
> On Tuesday, August 20, 2019 at 5:07:52 PM UTC-7, Sam wrote:
>> stdcerr writes:
>>
>>
>>> Right, this is how I learnt about the initialization list. So I've
>>> refactured my code but It still does not compile, it now looks like this:
>>>
>>> #include <QString>
>>> #include <QSettings>
>>>
>>> class foo {
>>> Q_OBJECT
>>> public:
>>> foo(const QSettings *set=0, const QString s="") :
>>> name(s),settings(set){}
...
>>> foo.cpp: In function ‘int main()’:
>>> foo.cpp:31:44: error: cannot convert ‘foo’ to ‘foo*’ in initialization
>>> foo *inst = foo(sttngs, QString("quux"));
>>> ^
>>> Makefile:471: recipe for target 'foo.o' failed
>>> make: *** [foo.o] Error 1
>
> I'm not sure why the compiler doesn't like is, why can't the instance of foo not be a pointer? ...
An instance of foo has class type. An class type is, by definition, not
a pointer type. You could have defined an implicit conversion from an
object of type foo to a pointer to a foo object, but that's almost
certainly not what you wanted.
> ... To get past this, I changed it to look like:
> foo inst = foo(sttngs, QString("quux"));
Note: the line above is equivalent to
foo inst(sttngs, QString("quux"));
> inst.qux();...
>>> Why does it still say "invalid conversion from ‘const QSettings*’ to
>>> ‘QSettings*’"
>>
>> Because your parameter to the constructor is a 'const QSettings *', and your
>> const class member is a pointer to a non-const QSettings.
>>
>> These are two different things: the pointer, and what it points to. Either
>> one, or both, can be const.
>>
>> So, either your parameter to the constructor should be
>>
>> QSettings *set=nullptr
>>
>> or your class member should be
>>
>> const QSettings * const settings;
>>
>> Which is a const class member named "settings" which is a pointer to a const
>> QSettings object.
Let me review your options:
const QSettings * const settings;
Declares settings to be a pointer, which cannot be changed, to a
QSettings object that cannot be changed through that pointer.
QSettings * const settings;
Declares settings to be a pointer, which cannot be changed, to a
QSettings object that can be changed through that pointer.
const QSettings * settings;
Declares settings to be a pointer, which can be changed, to a QSettings
object that cannot be changed through that pointer.
QSettings * settings;
Declares settings to be a pointer, which can be changed, to a QSettings
object that can be changed through that pointer.
So, which of these declarations is most appropriate for your
application? Your code never changes the value of settings once it has
been initialized, so declaring settings itself const makes sense.
However:
...
> foo.cpp: In member function ‘void foo::qux()’:
> foo.cpp:18:30: error: passing ‘const QSettings’ as ‘this’ argument discards qualifiers [-fpermissive]
> settings->beginGroup(name);
<
https://doc.qt.io/qt-5/qsettings.html#beginGroup> does not include the
'const' keyword in the declaration for beginGroup(), which is easy to
understand, since it describes the behavior as "Appends prefix to the
current group.", an action that requires modification of the QSettings
object.
Therefore, since you call settings->beginGroup(), it does NOT make sense
to declare "settings" as a pointer that cannot be used to modify the
object it points at. What you want is
QSetting * const settings;
> Does this mean beginGroup() and endGroup() cannot be invoked on a const QSettings pointer ?
Yes.