Casting pointer to pointer of class [modified]
-
Hi, I have a class that wraps a COM object and has only 1 member, a pointer to the COM object (interface pointer) and several methods. It could also be any other pointer. The size of an instance of this class is 4 bytes, there are no virtual methods or other members.
class CIntPtr { public: void AddOne () { (*m_pMyInt)++; } int *m_pMyInt; };
Is it now safe to cast an int* to an CIntPtr*?int myInt = 0; int *myIntPtr = &myInt; CIntPtr *myIntWrapper = (CIntPtr *) &myIntPtr; myIntWrapper->AddOne ();
The code runs fine and I don't see any problem with this. Actually I would even say it is better than creating a new object and calling the constructor which makes a copy of the pointer. There is also no additional object that needs to be deleted. But maybe this causes problems I'm not aware of. -
Hi, I have a class that wraps a COM object and has only 1 member, a pointer to the COM object (interface pointer) and several methods. It could also be any other pointer. The size of an instance of this class is 4 bytes, there are no virtual methods or other members.
class CIntPtr { public: void AddOne () { (*m_pMyInt)++; } int *m_pMyInt; };
Is it now safe to cast an int* to an CIntPtr*?int myInt = 0; int *myIntPtr = &myInt; CIntPtr *myIntWrapper = (CIntPtr *) &myIntPtr; myIntWrapper->AddOne ();
The code runs fine and I don't see any problem with this. Actually I would even say it is better than creating a new object and calling the constructor which makes a copy of the pointer. There is also no additional object that needs to be deleted. But maybe this causes problems I'm not aware of.I'm new to C++ (just a question), how can you use *m_pMyInt before you intialize it?
class CIntPtr { public: void AddOne () { (*m_pMyInt)++; } <-------use int *m_pMyInt; <-------intialize };
Just wondering.... or am I just stupid? "C++ will solve any problem." -
I'm new to C++ (just a question), how can you use *m_pMyInt before you intialize it?
class CIntPtr { public: void AddOne () { (*m_pMyInt)++; } <-------use int *m_pMyInt; <-------intialize };
Just wondering.... or am I just stupid? "C++ will solve any problem."#hackC++ wrote:
how can you use *m_pMyInt before you intialize it?
Have a look at the other code, I'm 'faking' an object. Or do you mean declare instead of initialize? It's common practice to have the members at the bottom of the class and the methods at the top.
-
Hi, I have a class that wraps a COM object and has only 1 member, a pointer to the COM object (interface pointer) and several methods. It could also be any other pointer. The size of an instance of this class is 4 bytes, there are no virtual methods or other members.
class CIntPtr { public: void AddOne () { (*m_pMyInt)++; } int *m_pMyInt; };
Is it now safe to cast an int* to an CIntPtr*?int myInt = 0; int *myIntPtr = &myInt; CIntPtr *myIntWrapper = (CIntPtr *) &myIntPtr; myIntWrapper->AddOne ();
The code runs fine and I don't see any problem with this. Actually I would even say it is better than creating a new object and calling the constructor which makes a copy of the pointer. There is also no additional object that needs to be deleted. But maybe this causes problems I'm not aware of.You're being too clever for your own good. Casting pointers like that may work, on your current OS and current compiler. There's no guarantee it will work on others or even future versions of your current compiler.
ABuenger wrote:
Actually I would even say it is better than creating a new object and calling the constructor which makes a copy of the pointer.
A temporary object of
CIntPtr
can be created and deleted very quickly. Again, you're being too clever, and besides unless you're creating billions of temp objects, you're not going to see any speed increase on any computer built this century.--Mike-- Visual C++ MVP :cool: LINKS~! Ericahist | PimpFish | CP SearchBar v3.0 | C++ Forum FAQ VB > soccer
-
Hi, I have a class that wraps a COM object and has only 1 member, a pointer to the COM object (interface pointer) and several methods. It could also be any other pointer. The size of an instance of this class is 4 bytes, there are no virtual methods or other members.
class CIntPtr { public: void AddOne () { (*m_pMyInt)++; } int *m_pMyInt; };
Is it now safe to cast an int* to an CIntPtr*?int myInt = 0; int *myIntPtr = &myInt; CIntPtr *myIntWrapper = (CIntPtr *) &myIntPtr; myIntWrapper->AddOne ();
The code runs fine and I don't see any problem with this. Actually I would even say it is better than creating a new object and calling the constructor which makes a copy of the pointer. There is also no additional object that needs to be deleted. But maybe this causes problems I'm not aware of.This is just another way of exploiting power of pointers provided by C++. But this is not considered as good practice.
-
You're being too clever for your own good. Casting pointers like that may work, on your current OS and current compiler. There's no guarantee it will work on others or even future versions of your current compiler.
ABuenger wrote:
Actually I would even say it is better than creating a new object and calling the constructor which makes a copy of the pointer.
A temporary object of
CIntPtr
can be created and deleted very quickly. Again, you're being too clever, and besides unless you're creating billions of temp objects, you're not going to see any speed increase on any computer built this century.--Mike-- Visual C++ MVP :cool: LINKS~! Ericahist | PimpFish | CP SearchBar v3.0 | C++ Forum FAQ VB > soccer
I agree that this kind of technique should be avoided; but as long as you’re careful it should work on all standard compliant compilers. As long as you don't have any
virtual
functions the layout will be compatible with that of the member. The layout of astruct
orclass
is predictable and standard for the most part. Certainly for a simple class with no base classes or virtual functions it is. Steve -
Hi, I have a class that wraps a COM object and has only 1 member, a pointer to the COM object (interface pointer) and several methods. It could also be any other pointer. The size of an instance of this class is 4 bytes, there are no virtual methods or other members.
class CIntPtr { public: void AddOne () { (*m_pMyInt)++; } int *m_pMyInt; };
Is it now safe to cast an int* to an CIntPtr*?int myInt = 0; int *myIntPtr = &myInt; CIntPtr *myIntWrapper = (CIntPtr *) &myIntPtr; myIntWrapper->AddOne ();
The code runs fine and I don't see any problem with this. Actually I would even say it is better than creating a new object and calling the constructor which makes a copy of the pointer. There is also no additional object that needs to be deleted. But maybe this causes problems I'm not aware of.ABuenger wrote:
Actually I would even say it is better than creating a new object and calling the constructor which makes a copy of the pointer.
This is an illusion. Firstly note that
sizeof(CIntPtr*) == sizeof(CIntPtr)
. This means that, from a storage point of view, there is no difference. i.e.class CIntPtr { public: CIntPtr(int *pInt = NULL) : m_pMyInt(pInt) {} // Added. void AddOne () { (*m_pMyInt)++; } int *m_pMyInt; }; int myInt = 0; int *myIntPtr = &myInt; CIntPtr *myIntWrapper = (CIntPtr*)&myIntPtr; // sizeof(myIntWrapper) is 4 (on Win32). We’re copying the pointer explicitly. CIntPtr myOtherWrapper(&myInt); // sizeof(myOtherWrapper)==4. Copy is performed inside constructor which is inlined.
In short the advantages of this confusing technique may be imagined. Steve -
I agree that this kind of technique should be avoided; but as long as you’re careful it should work on all standard compliant compilers. As long as you don't have any
virtual
functions the layout will be compatible with that of the member. The layout of astruct
orclass
is predictable and standard for the most part. Certainly for a simple class with no base classes or virtual functions it is. SteveIt's not a question of whether it works, it's a question of whether code like that should be written in the first place. If I saw code like that, and I knew nothing else of the author, I'd be highly suspicious of his grasp of C++ basics.
--Mike-- Visual C++ MVP :cool: LINKS~! Ericahist | PimpFish | CP SearchBar v3.0 | C++ Forum FAQ VB > soccer
-
It's not a question of whether it works, it's a question of whether code like that should be written in the first place. If I saw code like that, and I knew nothing else of the author, I'd be highly suspicious of his grasp of C++ basics.
--Mike-- Visual C++ MVP :cool: LINKS~! Ericahist | PimpFish | CP SearchBar v3.0 | C++ Forum FAQ VB > soccer
As I said, "I agree that this kind of technique should be avoided". My comment was motivated by your statement that, "Casting pointers like that may work, on your current OS and current compiler. There's no guarantee it will work on others or even future versions of your current compiler." This need not be the case: the layout of structures in C/C++ is well defined. This is why a
struct
can be used to write to the registers on a hardware device in device drivers for example. In short, code like the OP's can be made to work portably although in general it should be avoided. Steve