Best way to initialize QList?
-
The application output:
@
QWidget::setLayout: Attempting to set QLayout "" on mainView "", which already has a layout
QWidget::setLayout: Attempting to set QLayout "" on QWmessageBox "", which already has a layout
QWidget::setLayout: Attempting to set QLayout "" on QWmessageBox "", which already has a layout
QWidget::setLayout: Attempting to set QLayout "" on QWwindow "", which already has a layout
SLOT: NBhistoryInterface::addHistoryEntry(const QUrl &url) STATUS: Called
SLOT: NBhistoryInterface::addHistoryItem(QString title, QString url) STATUS: Called
The program has unexpectedly finished.
@...And part of the Apple crash report:
@
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000010VM Regions Near 0x10:
-->
__TEXT 0000000100000000-000000010002e000 [ 184K] r-x/rwx SM=COW /Users/USER/Desktop/*/NovaBrowser_v2.app/Contents/MacOS/NovaBrowser_v2Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 <BUNDLEIDENTIFIER> 0x00000001000178d4 QList<QString>::prepend(QString const&) + 20 (qlist.h:546)
1 <BUNDLEIDENTIFIER> 0x0000000100016cde NBhistoryInterface::addHistoryItem(QString, QString) + 158 (nbhistory.cpp:21)
@I am certainly no expert but the following lines of the error report:
@
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000010
@
look like there is some issue with a memory address. Is this the case? -
Ok I added your whole class to y new widget app, I don't use webkit much so I just used the class as is (without webkit) and created an object of it myself.
First problem: I don't know if that is like it should be but seems your class misses an abstract method from its base class and also an implementation for your still abstract method:
@
bool historyContains(const QString &url) const = 0; // abstract method
void addHistoryEntry(const QString &url); // pure virtual method from base, class, not present in your NBhistoryInterface
@
without those 2 addition I could not create an object of your class of course.. just wondering if that intended with webkit, seems like an error to me?After I fixed that I could compile and use your class like this in my example:
@
NBhistoryInterface hi;
hi.addHistoryEntry(QStringLiteral("test"), QUrl("http://www.test.com"));
@
no errors or crash, output was:
@
SLOT: NBhistoryInterface::addHistoryEntry(const QUrl &url) STATUS: Called
SLOT: NBhistoryInterface::addHistoryItem(QString title, QString url) STATUS: Called
SLOT: NBhistoryInterface::addHistoryItem(QString title, QString url) STATUS: Completed
SLOT: NBhistoryInterface::addHistoryEntry(const QUrl &url) STATUS: Completed
@Edit. from your post I don't know how you can compile your class but it seems the framework is trying to call
@
NBhistoryInterface::addHistoryEntry(const QUrl &url)
@
which you don't have in your class (see my error report above), so that should be an compiler error and no runtime crash at all!? -
Yeah Im not sure why my class is allowed to compile. How exactly did you fix the class? Could you post your improved class code please? I am not sure why the compiler doesn't error out when it tries to call addHistoryEntry(const QUrl &url). Possibly a glitch in the compiler?
-
Lol glitch in the compiler, next time it is a glitch in the matrix... Just kidding
More likely because you never create an object of your class yourself, that is why you won't get a compiler error. But the WebKit or wherever your class is being used has to create an object somehow and I guess there is where your app might crash, maybe.
Best way to fix the methods, just do as I did in my test and create an object of your NBhistoryInterface and compile, you will then see what I mean, hopefully. -
fix the methods how? Should I overload my addHistoryEntry() with the Qt default one? Im not sure whats wrong with historyContains().
-
Sorry I assumed you have some basic c++ or general object oriented programming knowledge and know what to do!?
I can't give you a complete tutorial on how do program c++, but this is the short version for your problem: if you implement an interface or abstract class you have to implement all pure virtual functions (functions without any body, also called abstract methods), so you can create objects of that class.
The Qt documentation usually tells you what those methods are or you let the compiler tell you if you create an object of the class it will give you the error(s).
You want to implement the interface QWebHistoryInterface, if you look at the "doc":http://qt-project.org/doc/qt-5/qwebhistoryinterface.html you'll see:bq. It contains two pure virtual methods that are called by the WebKit engine: addHistoryEntry() is used to add urls that have been visited to the interface, while historyContains() is used to query whether the given url has been visited by the user.
so you need to override and implement at least those two functions with this exact parameters (you have a function addHistoryEntry, but the parameters don't match so it's not an override of the base function)
@
virtual void addHistoryEntry(const QString & url) = 0
virtual bool historyContains(const QString & url) const = 0
@
In your code you are missing those 2 methods, if I am not mistaken.If you use a c++11 compiler you can make your life a little bit easier by using the new keyword "override", to be sure you are overriding the methods of the base class and not creating new ones by accident (like you did), example:
@
void addHistoryEntry(const QString & url) override {
// your code
}
@
see that "override" keyword after the method definition? if the base class does not contain a method with that exact definition you will get a compiler error, without the need to create an object of your class.Hope that helps.
-
Sorry for the late response, Ive been busy with AP testing :/
I do have some basic knowledge of c++, but I have been getting pretty confused on some of the basics such as virtual functions, etc. I thought that if I hoped right into Qt and c++ I would learn better then just reading tutorials, guess I was kinda wrong haha :) I have started watching/reading some tutorials on the internet, and I've ordered several books from the library. They should be coming in soon!
Ok back to the question at hand. I just added
@
void addHistoryEntry(const QString & url) = 0
bool historyContains(const QString & url) const = 0
@
to the 'virtual' section of my .h file. The program still crashes after compilation and I'm a little confused: you said virtual functions were functions without bodies, but later on you talked about putting the 'override' keyword in what I'm assuming is the method implementation in the .cpp file (forgive me if I misunderstood). I'm assuming 'override' tells the compiler to skip over this definition and use another one (like the one I created)? Again I'm probably wrong. I am using the compiler built into Qt Creator, does that support 'override'?Thanks for all your help! I am really interested in programming and c++, but as a high schooler I don't have much time to study it and there aren't any computer classes at my school so I've been teaching myself. I know I'm probably asking some pretty amateur questions, but I am really trying my best to learn.
Thanks for your help! -
While reading the QList docs again I found this:
"QList does not support inserting, prepending, appending or replacing with references to its own values. Doing so will cause your application to abort with an error message."
I'm not sure what it means by "references to its own values", but I'm assuming that means references to values already in the QList. Is that correct?
-
Xander84,
I have changed up the NBhistory.cpp file. Whenever I try and run it, it generates an error "expected function body after function declarator"
Im not sure what that means. My most recent code is on GitHub. Heres the link (its the NBhistory.cpp/.h file):
"Your text to link here...":https://github.com/NovaBrowser/NovaBrowser -
Hey (this is Xander84, my other account is corrupted or something I can't use it atm, that's why I wasn't answering sooner, sorry).
-
"I’m assuming ‘override’ tells the compiler to skip over this definition and use another one (like the one I created)?"
override tells the compiler that it has to keep the "contract" with the method of the base class. So I'would say it is exactly the opposite of what you said. :D
the override keyword is optional and does nothing really, all it is used for is helping the developer overriding the correct method and not (what you said) creating new ones by accident. If you have ever done some Java there is a @Override annotation with the same effect:
@
@Override void foo() { } // java
// similar to c++11 override keyword
void foo() override { } // c++11
@ -
the virtual keyword "just" indicates that a method can be overridden by child classes, without declaring a method "virtual" you cannot override it in c++ (unlike other programming langues, e.g. Java is everything virtual unless you define it "final")
-
about your QList question, in believe in Qt you cannot save references in any of the container classes. e.g.
@
QList<QString&> invalidList;
@
that is meant by list of references, since you can't do that I don't know how you would add a reference to its own member if you only use plain objects (copies) or pointers... -
on your GitHub page you are still missing the implementation of historyContains in your nbhistory.cpp file? I see the definition in the header only, that is a syntax error in c++. Maybe not that obvious to you why? your are defining a non-virtual abstract method, which is impossible to implement by any child classes, so it's a syntax error. The virtual keyword you used is only for the next method:
@
virtual
void addHistoryEntry(const QString & url) = 0;
bool historyContains(const QString &url) const = 0;
// format as
virtual void addHistoryEntry(const QString & url) = 0;
bool historyContains(const QString &url) const = 0;
@
virtual is not like the visibility modifier (public, private, etc), there is no following ":".
anyway you don't need a a virtual there, unless you want to override the method in a child class later (I guess you don't have any), so just remove it. You should know what virtual means by now since I briefly explained it above, if not just search for it on the net.
Also "= 0" after a method definition means the method is abstract (has no implementation body at all), so you should remove that too, you cannot have abstract methods if you want to create objects of that class.
That said, just do it like this:
@
void addHistoryEntry(const QString & url) override;
bool historyContains(const QString &url) const override;
@
and provide implementations for both methods in your cpp file. :)
if you don't have c++11 remove the override keyword there, tip to compile your project with c++11 support you onyl need to tell Qt to use it, most modern compilers should be able to support it. in your qmake project file add:
@
CONFIG += c++11
@
that only tells qmake to use the compiler flags (not necessary for all compilers), but with this config it works on all supported compiler by Qt.
(sorry for the long text again)
-
-
Ok so I have since converted NBhistoryManager into a subclass of QObject. This way I don't have to deal with overridden functions and all that jazz. I am still having trouble with the program crashing when it calls QList.prepend(). The implementation of the m_historyTitle has not been changed.