|
hello,
i've created a std::list of objects, and it works well, but i'd like to support additional functionality for the list, such as writing certain aspects of the objects to stdout/cout (or dumping them using TRACE macros), matching certain aspects of objects (i.e., several different "match" functions), populating a list box with objects' names, etc. i've tried 2 approaches:
1. wrap the std::list in a class that handles these functions by using the list's iterators. this is inelegant, so i switched to:
2. subclass my std::list<myobject>, and add the functions i need to the new class. from what i've read on the web, subclassing std::list isn't a good idea, due to the virtual destructor problem.
my guess is that i should be using functions that operate on this list, but creating functions instead of list methods seems to violate the whole point of using c++. i'd appreciate any advice, since this is my first project using the stl, and i'm still waiting for my stl book to arrive in the mail....
ed
|
|
|
|
|
If you don't add any new data in your derived class, you should be OK in most cases (because your derived destructor won't actually need to do anything more than the std::lsit destructor).
OTOH - ehh wrote: violate the whole point of using c++ - well, C++ is a multi-paradigm language, so using separate free functions doesn't really violate any point of C++....
Stuart Dootson
'Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p'
|
|
|
|
|
Hi All, I have a program which uses the IE engine to display HTML documents (using ATL) in my program's window. I'm trying to figure out how to make the COPY work, when some of the highlighted display is right-clicked. The program isn't creating the edit menu which appears when it is right-clicked, so I assume IE is doing that. The COPY appears in the menu, but clicking on it does not copy the text to the clipboard (at least, doing paste after that does not paste what I just tried to copy). If I display the same html doc in Internet Explorer, then the copy works fine. I've tried adding this code: m_spOleCmdTarg->Exec(NULL,OLECMDID_COPY,OLECMDEXECOPT_DONTPROMPTUSER,NULL,NULL); which does get executed when the user clicks on Copy in the System Menu. But still, the paste does not paste what I just tried to copy. Does anyone have any idea what I might be missing here? Any ideas are greatly appreciated. Thanks, Melena
|
|
|
|
|
I did this in one of my apps:
pWB2->ExecWB ( OLECMDID_COPY, OLECMDEXECOPT_DONTPROMPTUSER, NULL, NULL ); and it works without a hitch. I'm using a different interface than you, however.
--Mike--
Visual C++ MVP
LINKS~! Ericahist | 1ClickPicGrabber | CP SearchBar v2.0.2 | C++ Forum FAQ
Strange things are afoot at the U+004B U+20DD
|
|
|
|
|
Thanks Mike. So you didn't have to enable anything to make the copy work? I've seen things like UIEnable function calls, so I'm wondering if that's what I'm missing. Also, had you created your own menu which is run when the user right-clicks in the browser, or was it just using the IE engine right-click menu? I'm wondering how you knew when to execute the pWB2->ExecWB... Thanks again, Melena
|
|
|
|
|
I've figured this problem out. Was using CoInitialize() instead of OleInitialize(). The OleInitialize() makes the clipboard available, once I started using that, the copy worked fine.
|
|
|
|
|
|
If I have an STL container that contains objects, then I can compare them easily - for example:
class CMyClass
{
int m_n;
CMyClass(int n) : m_n(n) { }
bool operator==(const CMyClass& o) const
{
}
};
...
vector<CMyClass> v1;
vector<CMyClass> v2;
v1.push_back(CMyClass(1234));
v2.push_back(CMyClass(1234));
if (v1 == v2)
However, I often use containers of pointers, and when I do, comparing two containers doesn't call the objects operator== function. For example:
class CMyClass
{
int m_n;
CMyClass(int n) : m_n(n) { }
bool operator==(const CMyClass& o) const
{
}
};
...
vector<CMyClass*> v1;
vector<CMyClass*> v2;
v1.push_back(new CMyClass(1234));
v2.push_back(new CMyClass(1234));
if (v1 == v2)
My question is - are there any operators I can overload to make the comparison work for containers of pointers, or do I need to hand-roll my own comparison function? I hope this makes sense!
The Rob Blog
|
|
|
|
|
OK, after some experimenting I realised that std::equal can be passed a function object, so I now have something like this:
template <class T>
class EqualT
{
public:
inline bool operator()(const T* t1, const T* t2) { return *t1 == *t2; }
};
...
vector<CMyClass*> v1;
vector<CMyClass*> v2;
...
if (equal(v1.begin(), v1.end(), v2.begin(), EqualT<CMyClass>()))
Using a function object template means I can compare containers containing other pointer type - the EqualT operator() handles the de-referencing. Nice.
The Rob Blog
|
|
|
|
|
I meant:
struct EqualT
{
template <class T>
inline bool operator()(const T* t1, const T* t2) const { return *t1 == *t2; }
};
...
vector<CMyClass*> v1;
vector<CMyClass*> v2;
...
if (equal(v1.begin(), v1.end(), v2.begin(), EqualT()))
|
|
|
|
|
|
You could use boost::indirect_iterator[^] - then you don't need to do anything much (except use Boost!).
Of course, you're pulling a fair number of headers in, but who knows, you might find other parts of Boost you want to use...
Stuart Dootson
'Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p'
|
|
|
|
|
I recommend you use a smart pointer like the following:
http://code.axter.com/clone_ptr.h
The above smart pointer has operator==() functions that work on the object itself instead of the pointer.
Example code:
#include <iostream><br />
#include <list><br />
#include "clone_ptr.h"<br />
<br />
using namespace std;<br />
<br />
class A<br />
{<br />
public:<br />
A(int a) : m_a(a) {}<br />
virtual ~A() {}<br />
virtual void Somefunction() const<br />
{<br />
cout << "I'm A " << m_a << endl;<br />
}<br />
bool operator==(const A& Src)const{return (m_a == Src.m_a);}<br />
int m_a;<br />
};<br />
<br />
class B : public A<br />
{<br />
public:<br />
B(int a) : A(a) {}<br />
void Somefunction() const<br />
{<br />
cout << "I'm B " << m_a << endl;<br />
}<br />
};<br />
<br />
class C : public A<br />
{<br />
public:<br />
C(int a) : A(a) {}<br />
void Somefunction() const<br />
{<br />
cout << "I'm C " << m_a << endl;<br />
}<br />
};<br />
<br />
int main(int argc, char* argv[])<br />
{<br />
list<clone_ptr<A> > MyListOfA_PtrsX;<br />
MyListOfA_PtrsX.push_back(new A(1));<br />
MyListOfA_PtrsX.push_back(new A(2));<br />
MyListOfA_PtrsX.push_back(new A(3));<br />
<br />
list<clone_ptr<A> > MyListOfA_PtrsY;<br />
MyListOfA_PtrsY.push_back(new B(4));<br />
MyListOfA_PtrsY.push_back(new B(5));<br />
MyListOfA_PtrsY.push_back(new B(6));<br />
<br />
list<clone_ptr<A> > MyListOfA_PtrsZ;<br />
MyListOfA_PtrsZ.push_back(new C(1));<br />
MyListOfA_PtrsZ.push_back(new C(2));<br />
MyListOfA_PtrsZ.push_back(new C(3));<br />
<br />
bool IsEqual1 = (MyListOfA_PtrsX == MyListOfA_PtrsY);
bool IsEqual2 = (MyListOfA_PtrsX == MyListOfA_PtrsZ);
<br />
cout << IsEqual1 << endl;<br />
cout << IsEqual2 << endl;<br />
<br />
system("pause");<br />
return 0;<br />
}
Top ten member of C++ Expert Exchange.
http://www.experts-exchange.com/Cplusplus
|
|
|
|
|
forgive me if my ask is not about the theme treated in this forum.
I am working in c++ builder 6.0, i am using the GetHeapStatus function to know the memory allocated by the application, but all the fields of the struct returned by the function are in 0, why can I do??
Thanks.
|
|
|
|
|
I have a lot of places in my code where I am using a static const table that I then use for lookup purposes. For example:
static const struct
{
LPCTSTR psz;
UINT n;
} table[] =
{
_T("Rob"), 1971,
_T("Becky"), 1977,
};
...
for (int i = 0; i < sizeof(table) / sizeof(*table); i++)
{
...
}
This is all well and good, but now I am an STL fanatic I would rather using a static vector (so I can utilize find_if, for_each, etc.
My question - is there an elegant way to initialise a container whilst still making the whole thing const. For example, the following would be sweet:
class CMyData
{
public:
LPCTSTR m_psz;
UINT m_n;
CMyData(LPCTSTR psz, UINT n) : m_psz(psz), m_n(n) { }
};
static const vector<CMyData> v =
{
CMyData(_T("Rob"), 1971),
CMyData(_T("Becky"), 1977),
};
The above doesn't work. No surprises. If instead I do something like this:
static const vector<CMyData> v;
if (v.empty())
{
v.push_back(...);
v.push_back(...);
}
The fact the vector is defined as 'const' means I can't add anything to it the first time the function is called. I guess I could instead do:
static vector<const CMyData> v;
if (v.empty())
{
v.push_back(...);
v.push_back(...);
}
The above works OK, but I wondered if any STL gurus had any other solutions?
The Rob Blog
|
|
|
|
|
I don't see how making the container itself const would be useful. If you can't modify the vector, how can you add objects to it?
BTW check out boost::assign[^] for some neat classes that make STL container initialization nicer.
--Mike--
Visual C++ MVP
LINKS~! Ericahist | 1ClickPicGrabber | CP SearchBar v2.0.2 | C++ Forum FAQ
Strange things are afoot at the U+004B U+20DD
|
|
|
|
|
Michael Dunn wrote:
I don't see how making the container itself const would be useful.
Because, like in my first static const struct example, I only want the container for lookups - I won't add anything to it once it has been initialized. Looks like I might have to check Boost out...
|
|
|
|
|
Looks like the Boost 'list_of' function is exactly what I need!
e.g.:
static const vector<int> v = list_of(1)(2)(3)
|
|
|
|
|
Is there any way to use a function object with find_if instead of a predicate? Predicates have limited use, and it would be neat if I could do something like this:
struct findfunc
{
CMyPtr* m_pData;
findfunc(CMyPtr* p) : m_pData(p) { }
bool operator()(CMyData* ptr)
{
return (ptr->blah == m_pData->blah);
}
}
...
std::list<CMyData*> mylist;
...
CMyPtr somedata;
...
std::list<CMyData*>::iterator it = std::find_if(mylist.begin(), mylist.end(), findfunc(somedata));
Basically, I want to perform a more advanced search (on any STL container) than find_if currently allows. I am quite new to STL, so please bear with me!
The Rob Blog
|
|
|
|
|
|
You're right - it does work - I was having a blonde moment!
The STL rocks. I feel I have hardly scratched the surface yet already I am in awe of its capabilities...
|
|
|
|
|
Don't forget to make operator() of your functors a const method. Otherwise it may not work, if your STL implementation passes the functor objects by const reference.
Good music: In my rosary[^]
|
|
|
|
|
Top tip - cheers. It does actually mention this in the excellent C++ Standard Library book I have (Nicolai Josuttis) so there's no excuse...
|
|
|
|
|
Greetings...
I have been working on some ATL controls which have MFC support. I can view the property page of the ATL classes and see the events they can handle, which are a partial list of those available to pure MFC classes. However I need to handle the event WM_SETTINGCHANGE and that is not listed as a possible event. I can manually type it under:
<br />
BEGIN_MSG_MAP(CSomeClass)<br />
...<br />
MESSAGE_HANDLER(WM_SETTINGCHANGE, OnSettingChange)<br />
...<br />
END_MSG_MAP()<br />
but this doesn't work..the debugger never stops in the OnSettingChange function.
However, if I make a new purely MFC project, WM_SETTINGCHANGE is listed under the events tap of the classe's property page, and it all works just fine.
The question I guess is, how can it be that ATL "with MFC support" has only some of the events? also what is the work arround, especially as in pure MFC the event handling function is in the form of
<br />
OnSettingChange(UINT uFlags, LPCTSTR lpszSection)<br />
and in ATL control project with MFC support it is in the form of:
<br />
OnSettingChange(UINT , WPARAM , LPARAM , BOOL& )<br />
Thanks,
Aristotel
|
|
|
|
|
Hi,
In my main frame I have a splitter pane with two views. I want to scroll the appropriate window when the mouse hovers over it. What is the best way to do this?
I was thinking of handling the WM_MOUSEWHEEL message and checking if the cursor is within the bounds of the view's rectangle (using GetCursorPos() and GetWindowRect()) but I think it would waste too many CPU cycles
Is there a better way?
Thanks in advance.
|
|
|
|
|