Calling Memberfunctions out of a QMap - c++

I have a class TypeData and want to store objects of that type in a QMap then I want to get a specific object out of the map and call a memberfunction of this object.
But when I try to do that i get the following error message:
error C2662: 'TypeData::write': cannot convert 'this' pointer from 'const TypeData' to 'TypeData &'
here are the relevant code snippets:
QMap<QString, TypeData> typeDataList;
typeDataList.insert(currentID, temp);
typeDataList.value(currentID).write();
Can anyone tell what I', doing wrong here? And how I could fix this?

QMap::value returns a const T, i.e. a both a copy of the element in the map, and a non-modifyable one. Your write() method is probably not const, thus calling write() on the const T is not allowed. If value returned just T, it would work, but any changes write() does to the temporary object would be lost right away. (As the copy is destroyed right after).
So you can either make write() const if it doesn't modify the TypeData.
That's preferable, if possible.
Alternatively you can do:
typeDataList[currentID].write() // modifies the object in the map but also will insert a TypeData() if there is no entry for key currentID yet.
or, more verbose but without inserting a new element if none is found:
QMap<QString,TypeData>::Iterator it = typeDataList.find(currentID);
if ( it != typeDataList.constEnd() ) {
it->write();
} else {
// no typedata found for currentID
}

Related

Get object from pointer C++

I have a vector of objects (DimensionItem) and I want to push another item to the vector. I only have a pointer to the object I wish to push. How can I get the object from the pointer.
(New to pointers, very possible I'm am fundamentally misunderstanding something)
DimensionItem *selected_Item = dynamic_cast<DimensionItem*>(g_items[i]); //g_items is a list of items taken from my scene
vector<DimensionItem> DimItems;
DimItems.push_back(selected_Item);
The error message is:
no matching function for call to 'std::vector::push_back(DimensionItem*&)'
You probably want:
DimensionItem& selected_Item = dynamic_cast<DimensionItem&>(*g_items[i]); // Throws if g_items[i] is not DimensionItem.
vector<DimensionItem> DimItems;
DimItems.push_back(selected_Item); // Stores a copy of selected_Item.
dynamic_cast<DimensionItem*>(g_items[i]) returns a null pointer if g_items[i] is not a DimensionItem, so the code would need to check the pointer for null before dereferencing it.
Whereas dynamic_cast<DimensionItem&>(*g_items[i]) throws an exception in that case.

Method returning std::vector<std::unique_ptr<Object>>

As a continuation of a: Thread, I came across a problem with
writing a method of a class which returns:
std::vector<std::unique_ptr<Object>>
I get compiler errors when such a return type is written. There is some problem with delete operand or something ...
Generally, I've wanted to write a method which initializes vector and returns it.
Could anyone help me how to write it?
EDIT:
I Get:
attempting to reference a deleted function h:\pliki programów (x86)\microsoft visual studio 12.0\vc\include\xmemory0
Here I have the following code snippet. Can I create such a method like this?
std::vector<std::unique_ptr<Object>> Class::TestMethod(int param)
{
std::vector<std::unique_ptr<Object>> array;
auto day = std::make_unique<Object>();
array.push_back(day);
return array;
}
Your error is actually coming from:
array.push_back(day);
This tries to put a copy of day in the vector, which is not permitted since it is unique.
Instead you could write array.push_back( std::move(day) ); however the following would be better, replacing auto day...:
array.emplace_back();
The copy constructor of std::unique_ptr is deleted. That causes a problem in the line:
array.push_back(day);
Use
array.push_back(std::move(day));

tellg() for const reference object. "Copying" fstream object

I'm writing a class for working with text files. I would like to "copy" ifstream-object properties. The code below shows how I'm doing it. I have a problem with a function w.m_fin.tellg():
error C2662: 'std::basic_istream<_Elem,_Traits>::tellg' : cannot convert 'this' pointer from 'const std::ifstream' to 'std::basic_istream<_Elem,_Traits> &'
I want to set a file position in the destination object as in the source.
If I make the argument non-const [ Word(Word& w) ] all is OK. But I don't want to make it non-const. What should I do in order to solve this problem?
Thank you
class Word
{
private:
std::ifstream m_fin;
std::string m_in_filename;
public:
Word(const Word& w): m_in_filename( w.m_in_filename )
{
m_fin(m_in_filename);
m_fin.copyfmt( w.m_fin );
m_fin.clear( w.m_fin.rdstate() );
m_fin.seekg( w.m_fin.tellg() );//here I get an error
}
}
Since btellg (by potentially setting fail status) changes the state of the stream (as does seek and any form of read or write operation of course), you can't do that on a const object. However, I expect you could, if you wanted to solve it that way, declare m_fin as mutable, which means the compiler allows it to be changed even for const object.

C++ - Smart Pointers - Passing derived class shared pointer to base through template

I have the following and having difficulty resolving the error please help.
i have the following class as template definition somewhere.
template<class ConcreteHandlerType>
class SomeAcceptor: public ACE_Acceptor<ConcreteHandlerType, ACE_SOCK_Acceptor>
In some other file, i initialize this class in the constructor
class initialize {
typedef SomeAcceptor<BaseClassSomeHandler> baseAcceptor_t;
typedef SomeAcceptor<DerivedClassSomeHandler> derivedAcceptor_t;
boost::shared_ptr<baseAcceptor_t;> mAcceptor;
boost::shared_ptr<derivedAcceptor_t;> mDerivedAcceptor;
bool HandleAcceptNotification(BaseClassSomeHandler& someHandler);
initialize() : mAcceptor(0), mDerivedAcceptor(new DerivedAcceptor_t) {
mAcceptor->SetAcceptNotificationDelegate(fastdelegate::MakeDelegate(this, &initialize::HandleAcceptNotification));
}
}
Error i get is
error: no matching function for call to `boost::shared_ptr<SomeAcceptor<BaseClassSomeHandler> >::shared_ptr(int)'common/lib/boost_1_39_0/boost/smart_ptr/shared_ptr.hpp:160: note: candidates are: boost::shared_ptr<SomeAcceptor<BaseClassSomeHandler> >::shared_ptr(const boost::shared_ptr<SomeAcceptor<BaseClassSomeHandler> >&)
common/lib/boost_1_39_0/boost/smart_ptr/shared_ptr.hpp:173: notboost::shared_ptr<T>::shared_ptr() [with T = SomeAcceptor<BaseClassSomeHandler>]
I also tried overloading the function with
bool HandleAcceptNotification(DerivedClassSomeHandler& someHandler);
but because mAcceptor is of type SomeAcceptor BaseClassSomeHandler, i get this error, but to fix this.
I guess i need to cast it somehow, but how to do it?
i tried doing like below inside the constructor and it didn't work
initialize() : mAcceptor(0), mDerivedAcceptor(new DerivedAcceptor_t) {
mAcceptor = mDerivedAcceptor; // Error here
mAcceptor->SetAcceptNotificationDelegate(fastdelegate::MakeDelegate(this, &initialize::HandleAcceptNotification));
}
From your code, it looks like you want mAcceptor to be assigned NULL (0), if that is the case you don't need to initialize it at all, as the default constructor will take care of that. But, since you call a function on that (NULL) pointer immediately, its not immediately clear exactly what you want to do.
If you want mAcceptor and mDerivedAcceptor to point to the same (shared) object and assuming DerivedClassSomeHandler is derived from BaseClassSomeHandler, this is a situation where you should use boost::shared_static_cast, as described here.
There's also some good information in this apparently related question.
The error is due to the mAcceptor(0) in
initialize() : mAcceptor(0), mDerivedAcceptor(new DerivedAcceptor_t) {
mAcceptor->SetAcceptNotificationDelegate(fastdelegate::MakeDelegate(this, &initialize::HandleAcceptNotification));
}
The smart_ptr default constructor assigns the wrapped ptr to NULL, so leave out mAcceptor(0) from the initialization list.
boost::shared_ptr<SomeAcceptor<BaseClassSomeHandler> >::shared_ptr(int)
It's yelling at you that there's no constructor that accepts an int.
Just use: mAcceptor()

Receiving assert failure on Reference Call

(Disclaimer: I have removed the Qt tag in case the problem is in my syntax / understanding of the references involved here)
I have a foreach loop with an object Member. When I enumerate through the list and try to access a member field, the debugger stops and I get a message:
Stopped: 'signal-received' -
The assert failure is:
inline QString::QString(const QString &other) : d(other.d)
{ Q_ASSERT(&other != this); d->ref.ref(); }
I have checked if the member is NULL, and it isn't. I have tried re-working the code, but I keep failing on this simple call.
Some thing's I missed out. MemberList is a singleton (definitely initialized and returns a valid pointer) that is created as the application launches and populates the MemberList with Members from a file. When this is created, there are definitely values, as I print them to qDebug(). This page is literally the next page. I am unsure as to how the List items can be destroyed.
The code is as follows:
int i = 0;
QList<Member*> members = ml->getMembers();
foreach (Member* mem, members)
{
QString memID = mem->getMemberID(); // Crash happens here
QListWidgetItem *lstItem = new QListWidgetItem(memID, lsvMembers);
lsvMembers->insertItem(i, lstItem);
i++;
}
The Member classes get is as follows:
QString getMemberID() const;
and the actual function is:
QString Member::getMemberID() const
{
return MemberID;
}
The ml variable is received as follows:
QList<Member*> MemberList::getMembers()
{
return MemberList::getInstance()->memberList;
}
Where memberList is a private variable.
Final answer:
I decided to rework the singleton completely and found that I was not instantiating a new Member, rather reusing the previous object over and over. This caused the double reference. S'pose thats pointers for you. Special thanks to Troubadour for the effort!
If mem is not null it could still be the case that the pointer is dangling i.e. the Member it was pointing to has been deleted.
If Member inherits from QObject then you could temporarily change your QList<Member*> that is stored in ml (assuming that's what's stored in ml) into a QList< QPointer<Member> >. If you then get a null QPointer in the list after calling getMembers or at any point during the loop then the object must have been destroyed at some point.
Edit
As regards the singleton, are you sure it's initiliased properly? In other words does MemberList::getInstance() return a valid pointer or just a random uninitialised one?
Edit2
Since we've exhausted most possibilities I guess it must be in the singleton somewhere. All I can suggest is to keep querying the first item in the list to find out exactly where it goes bad.