| View previous topic :: View next topic |
| Author |
Message |
Zara Guest
|
Posted: Wed Dec 28, 2005 4:38 pm Post subject: Re: Array of TImage Boxes |
|
|
On Wed, 28 Dec 2005 17:20:59 +0100, "Bono" <bono (AT) ingv (DOT) it> wrote:
| Quote: | Hi there!!
I'm trying to create an array of TImages for my CLX (multiplatform)
applicatio.
I created a class and in the header file I wrote:
vector<TImages> myImages
Now, the problem is that when I attempt to do a "myImages.resize(number)", I
get the following compilation error:
Could not find a match for TImage::TImage()
Is there anyone who can help me?
Thanks a lot!!
Andrea
|
Use:
std::vector<boost::shared_ptr myImages;
www.boost.org
Best regards
Zara
|
|
| Back to top |
|
 |
Don Ziesig Guest
|
Posted: Wed Dec 28, 2005 5:06 pm Post subject: Re: Array of TImage Boxes |
|
|
Bono wrote:
| Quote: | Hi there!!
I'm trying to create an array of TImages for my CLX (multiplatform)
applicatio.
I created a class and in the header file I wrote:
vector<TImages> myImages
Now, the problem is that when I attempt to do a "myImages.resize(number)", I
get the following compilation error:
Could not find a match for TImage::TImage()
Is there anyone who can help me?
Thanks a lot!!
Andrea
Hi Andrea, |
You have two problems here [ not bad for one line ]
Borland's VCL objects can not be created statically;
in BDS2006:
void TForm1::TestIt()
{
TImage staticImage; // shouldn't compile
TImage *dynamicImage; // should compile
}
The first statement (comment //shouldn't compile) generates the errors:
[C++ Error] Test1.cpp(21): E2459 VCL style classes must be constructed
using operator new
[C++ Error] Test1.cpp(21): E2285 Could not find a match for
'TImage::TImage()'
the elements of a vector are created statically so they will fail.
You need:
vector<TImage *> myImages;
Then when adding TImage to the vector during initialization use
something like:
myImages.push_back(new TImage(Application));
This illustrates your second problem (which appears in your error).
TImages can not be created without an owner parameter. There is no
available TImage::TImage();
This version of function TestIt() compiles properly:
#include <vector>
*
*
*
void TForm1::TestIt()
{
// TImage staticImage; // shouldn't compile
TImage *dynamicImage; // should compile
std::vector<TImage *> myImages;
myImages.push_back(new TImage(Application));
}
The Application parameter is the VCL owner of the image, with all that
that entails. It is required or you get the error:
[C++ Error] Test1.cpp(21): E2285 Could not find a match for
'TImage::TImage()'
which looks very much like what you are getting as well.
Enjoy!
Donz
|
|
| Back to top |
|
 |
Remy Lebeau (TeamB) Guest
|
Posted: Wed Dec 28, 2005 5:41 pm Post subject: Re: Array of TImage Boxes |
|
|
"Bono" <bono (AT) ingv (DOT) it> wrote
| Quote: | vector<TImages> myImages
|
You are trying to create a vector that contains actual object instances.
You cannot do that with VCL object. You need to use pointers instead:
vector<TImages*> myImages
| Quote: | Now, the problem is that when I attempt to do a
"myImages.resize(number)", I get the following compilation
error:
Could not find a match for TImage::TImage()
|
As well you should be. Because your are trying to store actual object
instances in the vector, it needs to be able to create new instances when
necesary. But it cannot because TImage does not have a default constructor.
Most VCL objects do not. You will have to instantiate the objects yourself
and then put the pointers into the vector when needed, ie:
vector<TImages*> myImages;
{
size_t number = ...;
for(size_t i = number; i < myImages.size(); ++i)
delete myImages[i];
myImages.resize(number);
for(size_t i = myImages.size(); i < number; ++i)
myImages[i] = new TImage(NULL);
}
Gambit
|
|
| Back to top |
|
 |
Remy Lebeau (TeamB) Guest
|
Posted: Wed Dec 28, 2005 7:04 pm Post subject: Re: Array of TImage Boxes |
|
|
"Bono" <bono (AT) ingv (DOT) it> wrote
| Quote: | But what about using NON VCL objects?
|
What about them?
| Quote: | I'd prefer using CLX for a multiplatform application. Is there
any control (with a canvas) I can use and that makes "resize"
operation easier?
|
I do not understand what you are trying to accomplish in the first place.
Please elaborate.
Gambit
|
|
| Back to top |
|
 |
Jonathan Benedicto Guest
|
Posted: Wed Dec 28, 2005 10:15 pm Post subject: Re: Array of TImage Boxes |
|
|
Bono wrote:
| Quote: | Thanks...
But what about using NON VCL objects? I'd prefer using CLX for a
multiplatform application. Is there any control (with a canvas) I can
use and that makes "resize" operation easier?
|
Just use TImage pointers as Mr Lebeau said. It works VCL or CLX.
Jonathan
http://jomitech.com/mtbcc32.shtml - Multi-threaded compilation for BCB
http://jomitech.com/forum - JomiTech Forums
|
|
| Back to top |
|
 |
Clayton Arends Guest
|
Posted: Sun Jan 01, 2006 7:16 pm Post subject: Re: Array of TImage Boxes |
|
|
"Bono" <bono (AT) ingv (DOT) it> wrote
| Quote: | Is there any control (with a canvas) I can use and that makes "resize"
operation easier?
|
As Remy stated the issue is that the controls do not have a default
constructor which means you must supply one during construction. The STL
containers do not offer a method to pass arguments during construction. You
will need to either do what Remy has suggested or do something slightly more
complex. To give you an idea, and as a thought experiment for myself, here
is what I came up with.
// in header
class TImageBox
{
private:
struct TData
{
TImage* Image;
int RefCount;
inline TData(TWinControl* AOwner) : RefCount(1)
{
Image = new TImage(AOwner);
Image->Parent = AOwner;
}
inline ~TData()
{
delete Image;
}
inline void AddRef() { ++RefCount; }
inline void Release() { if (--RefCount == 0) delete this; }
};
TData* Data;
public:
static TWinControl* Owner;
TImageBox() { Data = new TData(Owner); }
TImageBox(const TImageBox& rhs) : Data(rhs.Data) { Data->AddRef(); }
~TImageBox() { Data->Release(); }
const TImageBox& operator=(const TImageBox& rhs)
{
Data->Release();
Data = rhs.Data;
Data->AddRef();
return *this;
}
};
typedef std::vector<TImageBox> TImageBoxes;
// in cpp
TWinControl* TImageBox::Owner = NULL;
A little explanation. std::vector uses copy constructors and operator=() to
perform its memory management. Because of this a reference counted data
member is required to house the actual image pointer (otherwise the image
would keep getting created and destroyed, or destroyed multiple times).
Now, you can use this type the way you originally attempted. The only
requirement is that you set TImageBox::Owner before attempting a resize of
the vector. Example:
// ImageBoxes is declared in TForm as "TImageBoxes ImageBoxes;"
// in a method of TForm1
TImageBox::Owner = this;
ImageBoxes.resize(25);
HTH, however this seems like a long way to go to simply allow vector to
control the memory allocation
- Clayton
|
|
| Back to top |
|
 |
|