|
SodomFighter666 wrote: I know, that the vector needs a base class of all my object
Base class pointer. Only if for some reason you need to keep all of them in the same collection (ie, they all support a particular interface), in which case the exact type shouldn't matter to you. If their actual types do matter, then you should have a pretty good reason for putting them in the same collection. Your base class should also have a virtual destructor.
vector<Basis*> V;
A *a = new A;
V.push_back(a);
V[0]->reset();
for(vector<Basis*>::iterator i = V.begin(); i != V.end(); i++)
{
delete *i;
}
SodomFighter666 wrote: I know that the STL-Vector work with templates, so the call 'V.insert(V.begin(), a);' transforme the object a to the instance of 'Basis'.
You might want to note the distinction between making a copy of an object, and storing a pointer to an object.
SodomFighter666 wrote: ... and special methods (like 'A::loadGUI()')?
So what is the reason loadGUI isn't a virtual member of your Basis class? If you still want to do something like this you would have to have a method on Basis that can tell you at runtime what kind of derived class pointer it is and cast it to that class.
|
|
|
|
|
Hi hfry,
thank you for your help. Your advise for the 'Base class pointer' works fine.
hfry: So what is the reason loadGUI isn't a virtual member of your Basis class?
The reason is, that I can't change the base class. The base class is from the Qt library (It's a QWidget class).
In my application I call for every QWidget object (like pointer object 'a') the appropriate method (like 'loadGUI()').
The result is like this:
a->loadGUI();
b->loadGUI();
c->loadGUI();
d->loadGUI();
...
I would like to have these calls in a for-loop where 'V' is the vector to the QWidget objects:
for (int i=0; i < V.size(); i++)
{
V[i]-loadGUI();
}
/////////////////////////////////////////////////////////////////////////////
class B : public Basis {
public:
virtual void reset(void);
void loadGUI(void);
};
void B::reset(void)
{
cout << "Class B reset ! \n";
}
void B::loadGUI(void)
{
cout <<"Class B loadGUI! \n";
}
....
vector<Basis*> V;
//Build up object a
A* a = new A();
V.push_back(a);
//Build up object b
B* b = new B();
V.push_back(b);
for(int i = 0; i <V.size(); i++)
{
V[i]->reset(); //It works fine.
}
//Now, try to call loadGUI()
//First version
A* a1 = static_cast<A*>(V[0]);
a1->loadGUI();
B* b1 = static_cast<B*>(V[1]);
b1->loadGUI();
//Second version
for(int i = 0; i <V.size(); i++)
{
// V[i]->loadGUI(); //It doesn't work.
}
/////////////////////////////////////////////////////////////////////////////
If there isn't a solution with STL, I will tried with design pattern (maybe the decorator pattern). But this is an other topic and doesn't belong to this forum.
Kinds regard,
Thomas
|
|
|
|
|
You might want to look into delegates, there should be a few articles on codeproject on this.
Alternatively, here's a hack. You might want to get a second opinion before doing this though.
struct ICommon
{
virtual ~ICommon(){};
virtual void loadGUI() = 0;
virtual void reset() = 0;
};
template <class T, bool t_bManaged = true>
class Wrapper : public ICommon
{
public:
Wrapper(T* pObject)
{
m_pObject = pObject;
}
~Wrapper()
{
if(t_bManaged) delete m_pObject;
}
void reset()
{
m_pObject->reset();
}
void loadGUI()
{
m_pObject->loadGUI();
}
T* m_pObject;
};
class A {
public:
void reset(void)
{
cout << "Class A reset ! \n";
}
void loadGUI(void)
{
cout <<"Class A loadGUI! \n";
}
};
class B {
public:
void reset(void)
{
cout << "Class B reset ! \n";
}
void loadGUI(void)
{
cout <<"Class B loadGUI! \n";
}
};
vector<ICommon*> V;
V.push_back(new Wrapper<A>(new A));
V.push_back(new Wrapper(new B));
for(vector<ICommon*>::iterator i = V.begin(); i != V.end(); i++)
{
(*i)->reset();
(*i)->loadGUI();
}
for(vector<ICommon*>::iterator i = V.begin(); i != V.end(); i++)
{
delete *i;
}
-- modified at 16:37 Sunday 30th July, 2006
|
|
|
|
|
From what you are saying, you really don't want a vector or QtWidgets, you want a vector of QtWidgets that have a loadGUI method. Thus, you can do this:
class Base
{
public:
virtual void loadGUI() = 0;
virtual void reset() = 0;
};
class MyWidget : public QtWidget,
public virtual Base
{
virtual void loadGUI() {}
virtual void reset() {}
};
Then, in your code, you will create your MyWidgets and place them in a vector:
vector<Base*> myVector;
for (int i = 0; i < 5; ++i)
{
myVector.push_back(new MyWidget);
}
Then, whenever you decide to call your methods:
void loadGUIs(const MyWidget*& widget)
{
widget->loadGUI();
}
for_each(myVector.begin(), myVector.end(), loadGUIs);
As a side note: You will notice that I did not create a loop to iterate through the vector. You should use the algorithms as much as possible -- it will save you a LOT of headaches.
-- modified at 15:04 Monday 31st July, 2006
If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week
Zac
|
|
|
|
|
Thank you for your help,
@hfry:
My compiler (Visual Studio 2003) has problems with the following lines:
V.push_back(new Wrapper(new A));<br />
V.push_back(new Wrapper(new B));
The code output is "If you use a template class a template argument list is nessesary!" (translation from german).
After playing with the code I'm able to compile the wrapper class without pointer:
Wrapper<A> myWrapper(A); // with class 'A'
@Zac:
At this morning I produced a similar solution like you:
class Base : public QWidget<br />
{<br />
public:<br />
virtual void loadGUI() = 0;<br />
virtual void reset() = 0;<br />
};<br />
<br />
class MyWidget : public Base<br />
{<br />
virtual void loadGUI() {}<br />
virtual void reset() {}<br />
};<br />
<br />
vector<Base*> V;<br />
<br />
V.push_back(new MyWidget);<br />
...
But your solution is better. First your base class doesn't care about QWidgets (= less/simple code). Second your advise to use stl-algorithms for a good health (I only want headaches with a lot of beer at the next party!).
Bye,
Thomas
|
|
|
|
|
How to CComBSTR convert to char *?
alantop
|
|
|
|
|
USES_CONVERSION;
CComBSTR *pBString;
...
...
char *pString = OLE2T(pBString);
This should work.
The original point and click interface was a Smith & Wesson.
|
|
|
|
|
You're far better off with CW2A() et al (ATL7 and later). USES_CONVERSION is a biiiiiiig cludge. (Take a peek under the hood, and you'll see...)
--
Mr. Bender's Wardrobe by ROBOTANY 500
|
|
|
|
|
|
Do you have to use CComBSTR? If not, why are you using it? _bstr_t is a much more complete wrapper for BSTRs.
If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week
Zac
|
|
|
|
|
If you want to eliminate CRT dependencies, CComBSTR is the way to go.
--
Broadcast simultaneously one year in the future
|
|
|
|
|
I have created a Child Window with its style set to WS_VSCROLL. This child window houses some CEdit and CStatic Windows. Now I have set up the Vertical Scroll bar, but when I scroll the child Window, the controls on it do not get repainted properly. Can anyone explain why?
I am using WTL 7.1. Thanks.
---
Hakuna-Matada
It means no worries for the rest of your days...
It's our problem free, Philosophy
<marquee behavior="alternate" scrollamount="5" scrolldelay="50">
|
|
|
|
|
Did you try to set clipchildrens style bit (forgot the actual name), if that doesn't work try calling UpdateWindow for all the controls after scrolling.
My sins are bloody red, my coffee is a black hole.
|
|
|
|
|
Thank You for taking the time to reply to my woe. Well, I have set the WS_CLIPCHILDREN and WS_CLIPSIBLINGS styles to my control and UpdateWindow() also doesn't work. In the End, I tried Invalidate on all the child controls and it worked. although the scrolling is not smooth as expected, but it scrolls. Any other way that I can make the scrolling experience better?
Thank You once again.
---
Hakuna-Matada
It means no worries for the rest of your days...
It's our problem free, Philosophy
<marquee behavior="alternate" scrollamount="5" scrolldelay="50">
|
|
|
|
|
how to trap tab change event in IE7 or how to get active tab ?
|
|
|
|
|
i found the way to get tab change event and get the active tab.
|
|
|
|
|
Would you mind sharing it with us?
|
|
|
|
|
Hello,
I create a COM componet with ATL, but when I test it , by CoCreateInstance(),
the result value is always E_OUTOFMEMORY, who can tell me why? Thanks a lot!
|
|
|
|
|
chenxiujie wrote: I create a COM componet with ATL, but when I test it , by CoCreateInstance(),
the result value is always E_OUTOFMEMORY
Search the Support Knowledge Base[^]
|
|
|
|
|
Hi,
I'm creating dll using VS2005 ATL project. I'm using third party SDK API's which extracts data into a *string variable. Now I'm facing problem with converting the *string to _bstr_t and *BSTR.
Please guide me whether is it possible to convert *string to _bstr_t and *BSTR, if so how to do it. If possible with a sample piece of code.
thanking you,
Arun
|
|
|
|
|
Hello agarunk,
By "*string", do you mean a pointer to a STL string ?
By "*BSTR", do you mean a pointer to a BSTR ?
- Bio.
|
|
|
|
|
Hi Bio,
Its "std::string* ", i.e., pointer to std string.
and yes "BSTR* " is pointer to a BSTR.
-Arun
|
|
|
|
|
Both the _bstr_t wrapper class and BSTR expect the text to be UNICODE, rather than ANSI or MBCS. While _bstr_t can convert from LPCSTR, BSTR on it's own can't.
You will need to use the c_str() member function of the std::string to get your LPCSTR in the first place (unlike MFC/ATL/WTL CString class, there's no LPCTSTR operator). Like I say, you can then use this pointer with something like A2W or MultiByteToWideChar.
Steve S
Developer for hire
|
|
|
|
|
Hi Steve,
Below is the implementation which I'm using now....
BSTR* TargetBSTR ;<br />
string *SourceStr=new string;<br />
string StrBuff;<br />
const char *CharBuff;<br />
<br />
StrBuff=*SourceStr;<br />
CharBuff=StrBuff.c_str();<br />
*TargetBSTR = _com_util::ConvertStringToBSTR(CharBuff);
Is this what you are asking me to do???
It is working fine for me for time being... I would like to know if I'm doing any mistake.
Is there any issues with it???
-Arun
|
|
|
|
|
agarunk wrote: BSTR* TargetBSTR ;
string *SourceStr=new string;
string StrBuff;
const char *CharBuff;
StrBuff=*SourceStr;
CharBuff=StrBuff.c_str();
*TargetBSTR = _com_util::ConvertStringToBSTR(CharBuff);
That is far more code than you need to do for this. See my response below.
If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week
Zac
|
|
|
|