Hi all,
I have a template class (call it Object) whose instances have a
variable size part - an array of of T objects. But this variable size
part is fixed at creation time so instead of allocating two blocks
(one for the object and one for the variable-sized part) one can
allocate a single block via a placement new operator like
template<typename T>
void* Object<T>::operator new(std::size_t sz, std::size_t number) {
return new char[sz + number*sizeof(T)];
}
Creation of Object's goes through factory static methods so these
implementation details are hidden from the client.
I have the following function to get the pointer to the variable part
template<typename T>
T* Object<T>::getPtr() const {
return (T*)(this + 1);
}
Now the problem is the following: suppose (fixing the parameter type
T) that I derive from Object<T> and also assume that the derived class
adds some instance data. Then am I right in concluding that the above
getPtr returns the wrong answer? And if I am right, how to make sure
that getPtr returns the right pointer for derived classes?
TIA, with my best regards,
G. Rodrigues 8 1506
What you are trying to do is a bad idea.
overload the casting operator to cast any type to any type.
class B
{
};
class A
{
operator B() const;
};
In your case B would the address of the first element of the array.
But a word of caution casting operator is invoked only when you cast a
object (A) to a certain type (B). Not when you cast a object pointer
(A*) to (B)
Raj
Gonçalo Rodrigues wrote: I have a template class (call it Object) whose instances have a variable size part - an array of of T objects. But this variable size part is fixed at creation time so instead of allocating two blocks (one for the object and one for the variable-sized part) one can allocate a single block via a placement new operator like
template<typename T> void* Object<T>::operator new(std::size_t sz, std::size_t number) { return new char[sz + number*sizeof(T)]; }
Creation of Object's goes through factory static methods so these implementation details are hidden from the client.
Who's the client? Did you disable normal construction of your objects?
I have the following function to get the pointer to the variable part
template<typename T> T* Object<T>::getPtr() const { return (T*)(this + 1); }
Now the problem is the following: suppose (fixing the parameter type T) that I derive from Object<T> and also assume that the derived class adds some instance data. Then am I right in concluding that the above getPtr returns the wrong answer?
I am a bit puzzled by your initial explanation. What's the 'sizeof'
return for your object? And if I derive from your object and define
my own 'operator new', what 'sz' am I going to get?
If you did disable normal construction of your object, how can there be
any derived class?
I can understand that you might want to have the number of 'T' objects
in your 'Object<T>' to be totally dynamic, but pretending that your
object is small but let its allocation function to grab a lot of memory
and screw up all the processing for derived types is not the best way
to manage dynamic allocation.
And if I am right, how to make sure that getPtr returns the right pointer for derived classes?
Allocate the array correctly, dynamically, store a pointer to its first
element and return it. IOW, be normal, be C++.
V
On Mon, 07 Mar 2005 10:45:38 -0500, Victor Bazarov
<v.********@comAcast.net> wrote: Gonçalo Rodrigues wrote: I have a template class (call it Object) whose instances have a variable size part - an array of of T objects. But this variable size part is fixed at creation time so instead of allocating two blocks (one for the object and one for the variable-sized part) one can allocate a single block via a placement new operator like
template<typename T> void* Object<T>::operator new(std::size_t sz, std::size_t number) { return new char[sz + number*sizeof(T)]; }
Creation of Object's goes through factory static methods so these implementation details are hidden from the client. Who's the client? Did you disable normal construction of your objects?
I have the following function to get the pointer to the variable part
template<typename T> T* Object<T>::getPtr() const { return (T*)(this + 1); }
Now the problem is the following: suppose (fixing the parameter type T) that I derive from Object<T> and also assume that the derived class adds some instance data. Then am I right in concluding that the above getPtr returns the wrong answer?
I am a bit puzzled by your initial explanation. What's the 'sizeof' return for your object? And if I derive from your object and define my own 'operator new', what 'sz' am I going to get?
Hmm, rereading my explanation I just noticed I left out some important
details.
Let me try to explain myself a little bit better: Object<T> instances
are roughly of the form
template<typename T>
class Object {
private:
//Number of T objects (usually small <= 8).
std::size_t number;
//Pointer to array of T objects.
T* ptr;
//Some more data.
...
}
An initial analysis showed that a lot of instances of Object<T> will
be created and destroyed during a run of the program. Having a little
bit of free time (and out of boredom) I started hashing out a scheme
to make creation/destruction of objects a little more efficient.
As I said Object<T> instances are immutable, once created they never
change. Creation of Object<T> instances goes through a factory static
method; constructors are protected so that all clients (except derived
classes) have to go through the factory function.
One possible optimization is to allocate the Object and the array in a
single block (instead of two blocks, one for the Object and another
for the array) via a placement new operator with the array being
placed right next to the Object.
Now comes what I left out: Since the array is next to the Object,
another possible optimization, is getting rid of the T* ptr and
calculate the address of the array as an offset
template<typename T>
virtual T* Object<T>::getPtr() const {
return (T*)(this + 1);
}
IOW if you an Object<T>* pointer ptr to a derived class (assume it has
some more instance data) instance, does getPtr return the right
address?
If you did disable normal construction of your object, how can there be any derived class?
I can understand that you might want to have the number of 'T' objects in your 'Object<T>' to be totally dynamic, but pretending that your object is small but let its allocation function to grab a lot of memory and screw up all the processing for derived types is not the best way to manage dynamic allocation.
And if I am right, how to make sure that getPtr returns the right pointer for derived classes?
Allocate the array correctly, dynamically, store a pointer to its first element and return it. IOW, be normal, be C++.
Be normal :-) good advice - I will follow it. View the above as a
curiosity question.
TIA, best regards,
G. Rodrigues
Gonçalo Rodrigues wrote: [...] Be normal :-) good advice - I will follow it. View the above as a curiosity question.
I just couldn't imagine how you could have a dynamically sized object
using the 'new' trick and at the same time inherit from that object,
which requires a constant size of the class object.
V
Gonçalo Rodrigues schrieb: template<typename T> class Object { private: //Number of T objects (usually small <= 8). std::size_t number; //Pointer to array of T objects. T* ptr; //Some more data. ... }
if I understand your explanation correctly, what you want is something
like this:
template<typename T>
struct ObjectBase{
//pure virtual accessor functions to moreData
};
template<typename T,unsigned int i>
struct Object : ObjectBase<T>{
T moreData[i];
//virtual accessor functions to moreData
};
On Wed, 09 Mar 2005 01:29:28 +0100, Stefan Strasser
<ss*******@systemhaus-gruppe.de> wrote: Gonçalo Rodrigues schrieb: template<typename T> class Object { private: //Number of T objects (usually small <= 8). std::size_t number; //Pointer to array of T objects. T* ptr; //Some more data. ... }
if I understand your explanation correctly, what you want is something like this:
template<typename T> struct ObjectBase{ //pure virtual accessor functions to moreData };
template<typename T,unsigned int i> struct Object : ObjectBase<T>{ T moreData[i]; //virtual accessor functions to moreData };
Heh, I'm not very good at explaining things, am I? :-)
Boiling down, it resumes to: since sizeof is a compile time operator,
if I have a pointer
Base* ptr = & of some Derived object
sizeof(*ptr) returns the size of the static type (is this the correct
wording?) of the pointed to object, that is, sizof(Base), not the size
of the dynamic type, that is, sizeof(Derived). So the question is: is
it possible to calculate the "dynamic size"?
Just a curiosity question.
Regards,
G. Rodrigues
P:S: My appologies for not being very good at explaining myself.
"Gonçalo Rodrigues" wrote:
Boiling down, it resumes to: since sizeof is a compile time operator, if I have a pointer
Base* ptr = & of some Derived object
sizeof(*ptr) returns the size of the static type (is this the correct wording?)
Yep.
of the pointed to object, that is, sizof(Base), not the size of the dynamic type, that is, sizeof(Derived).
Yep.
So the question is: is it possible to calculate the "dynamic size"?
AFAIK No.
--
Karl Heinz Buchegger kb******@gascad.at
Gonçalo Rodrigues schrieb: if I understand your explanation correctly, what you want is something like this:
template<typename T> struct ObjectBase{ //pure virtual accessor functions to moreData };
template<typename T,unsigned int i> struct Object : ObjectBase<T>{ T moreData[i]; //virtual accessor functions to moreData };
So the question is: is it possible to calculate the "dynamic size"?
no, but you can implement a virtual function for that.
it looked to me like you want to get the "dynamic size" of your object
to be able to store some other data associated with the object behind
it. and this is what my example does. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Victor Hannak |
last post by:
I have two classes derived from a base class. The two derived classes each
utilize a structure that is slightly different from one another. i.e.
DerivedClass1:
struct NodeStruct {
float...
|
by: Art |
last post by:
This is partially an academic question, but I'm trying to understand
templates better. I have a base class that uses template parameters to
define the behavior of its class. I want to subclass this...
|
by: Shao Zhang |
last post by:
Hi,
I am not sure if the virtual keyword for the derived classes are
required given
that the base class already declares it virtual.
class A
{
public:
virtual ~A();
|
by: J.J. Feminella |
last post by:
(Please disregard the previous message; I accidentally sent it before it was
completed.)
I have source code similar to the following.
public class Vehicle
{
protected string dataV;
// ......
|
by: Mark McDonald |
last post by:
This question kind of follows on from Mike Spass’ posting 10/11/2004; I don’t
understand why you can’t declare an implicit operator to convert a base class
to a derived class.
The text...
|
by: John Glover |
last post by:
I'm having a very strange problem with XML serialization. I'm writing web
services which pass instances of various classes back and forth as parameters
and return values of web methods. The...
|
by: Jordan Taylor |
last post by:
Hi, can anyone suggest how the compiler will decide which bar() to
invoke when we call d.dio()? I am getting the following output:
B foo
B bar
but is there a situation when the same code can...
|
by: desktop |
last post by:
On this page:
http://www.eptacom.net/pubblicazioni/pub_eng/mdisp.html
Shape specify the virtual function:
virtual double Intersect( const Shape& s) = 0;
then the derived class Circle...
|
by: Bob Johnson |
last post by:
I have a base class that must have a member variable populated by, and only
by, derived classes.
It appears that if I declare the variable as "internal protected" then the
base class *can*...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 2 August 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM)
The start time is equivalent to 19:00 (7PM) in Central...
|
by: kcodez |
last post by:
As a H5 game development enthusiast, I recently wrote a very interesting little game - Toy Claw ((http://claw.kjeek.com/))。Here I will summarize and share the development experience here, and hope it...
|
by: Taofi |
last post by:
I try to insert a new record but the error message says the number of query names and destination fields are not the same
This are my field names
ID, Budgeted, Actual, Status and Differences
...
|
by: Rina0 |
last post by:
I am looking for a Python code to find the longest common subsequence of two strings. I found this blog post that describes the length of longest common subsequence problem and provides a solution in...
|
by: DJRhino |
last post by:
Private Sub CboDrawingID_BeforeUpdate(Cancel As Integer)
If = 310029923 Or 310030138 Or 310030152 Or 310030346 Or 310030348 Or _
310030356 Or 310030359 Or 310030362 Or...
|
by: lllomh |
last post by:
Define the method first
this.state = {
buttonBackgroundColor: 'green',
isBlinking: false, // A new status is added to identify whether the button is blinking or not
}
autoStart=()=>{
|
by: lllomh |
last post by:
How does React native implement an English player?
|
by: Mushico |
last post by:
How to calculate date of retirement from date of birth
|
by: DJRhino |
last post by:
Was curious if anyone else was having this same issue or not....
I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...
| |