|
So you're trying to ring my bell because now you are creating ambigious function pointers.
|
|
|
|
|
As far as I can remember once a type is defined that's it. The compiler does the conversion from T to int/double/long/etc. So at run-time there is no T, it as become a known integral type so you can't change it.
Also your code above is really strange and does not make much sense. But I really don't get what the real problem is. If you define T as double (as per VaporTrace) then you can set it as an integer or decimal from your input.
regards,
Rich
"Programming today is a race between software engineers striving to build bigger and
better idiot-proff programs, and the Universe trying to produce bigger and better idiots.
So far the Universe is winning." -- Rich Cook
|
|
|
|
|
The problem is that the input I an getting can be of any basic data type....int, double,char..etc
My data-structure is using templates that is been made at compile-time, but I need the type to change in real time. I think there is a way to do it using a derived class of the template class, but I can't seem to figure it out.
I'm sure many people had the same problem before with something like using a STL vector or list, and not knowing what type of data will be stored in the vector, at compile time.
Please help!!
I hope I explained my problem clearly.....?
|
|
|
|
|
Hi,
Ok, the way you could do it is by creating a union. Seeing the you need types int, double and char, just create a union of them all:
typedef union
{
char c;
double d;
int i;
} UTYPES;
This way you can use that for your template class. Now which ever type you need it will be in the union. But remember to be careful how you treat the union. You will also have to do some nifty programming in the template class to get around not being an exact type. The best would be a container class for it so that you can have some control over what values are stored in the union.
Hope this helps.
regards,
Rich
"Programming today is a race between software engineers striving to build bigger and
better idiot-proff programs, and the Universe trying to produce bigger and better idiots.
So far the Universe is winning." -- Rich Cook
|
|
|
|
|
We'll try that.
Thanks alot for your help.
|
|
|
|
|
Please help, and give me some details.
thanks
Lee
|
|
|
|
|
Of course. Like this:
class A
{
~A()
{
}
}; But I somehow wonder if you really didn't mean something altogether different, like "what will the implications be if I..." [1] or "when would I ever want to..." [2]. But, since it's Saturday evening, I couldn't possibly know, could I?
[1] You a) cannot do A* pA = new A; delete pA; and b) are prevented from making a local or member instance of A , since the compiler will automatically try to call the destructor when it goes out of scope.
[2] Perhaps a self-destructing object. Anyone can create it, but it can only destroy itself; no one else is allowed to destroy it. (Usually it will say delete this inside a member function.) If the object can only be safely destroyed under very specific circumstances, this can be a useful enforcement policy to prevent premature destruction.
--
The Blog: Bits and Pieces
|
|
|
|
|
Man, that's some good information. I never thought about it like that.
Can you help answer my questions posted below about pointers in C++?
Thanks.
|
|
|
|
|
Yes you can. That will cause that the class can only delete itself!
Don't try it, just do it!
|
|
|
|
|
Hi,
I have a question in c, can any body solve this problem
#include<stdio.h>
void change()
{
/*Write something in this function so that the output of printf in main
function should give 5 . Do not change the main function */ }
void main()
{
int i=5;
change();
i=10;
printf("%d",i);
}
rajesh
|
|
|
|
|
One answer is to use an inline assembly command to modify the return address to skip the i=10 part.
John
|
|
|
|
|
Hi John,
I think you might run into compiler problems when it generates code to return from the function. The best would be to change the values of the current stack (if the values of pushed on to the stack).
There is of cause the sneaky way around this. All you have to do is declare a static version of printf (e.g. static int __cdecl print (const char *format, ...) ). This way the compiler will link to this rather that the one in stdlib. Then you can print anything out you like.
regards,
Rich
"Programming today is a race between software engineers striving to build bigger and
better idiot-proff programs, and the Universe trying to produce bigger and better idiots.
So far the Universe is winning." -- Rich Cook
|
|
|
|
|
First, I appreciate any help or insight you can provide. Also, if there is a book or place wherin I can read up on the information I seek, please feel free to let me know. I am teaching myself how to program in C++.
My question regards pointers.
Assume: SomeObject * objectPtr = 0;
Assume: OtherObject * smallObjectPtr = 0;
Assume that SomeObject has member: OtherObject * leftPtr;
Also, each OtherObject object has member: OtherObject *leftPtr;
Note: this is from a binary tree node insertion and deletion attempt.
Assume that objectPtr has been pointed to an object of type SomeObject (Tree class) and that smallObjectPtr (Tree node class) has been pointed to an object of type OtherObject in a binary tree. Also, assume that these nodes are nestled midway down the tree and all the nodes at the level have at lest one or two children.
What is the difference between the following two declations:
*objectPtr->leftPtr = *smallObject->leftPtr
and
objectPtr->leftPtr = smallObjectPtr->leftPtr
Afterwards, I assign the pointers I have used to null.
Will the two result in different assignments?
How can I tell which one to use? Essentially, I want to know how the inclusion of the “*” dereference operator changes what happens.
This problem occurred because during the binary tree deletion attempt, the proper assignments were made via pointers to the different nodes, but any attempt to print the contents of the tree afterwards results in less than half of the remaining tree being printed.
Finally, is there anything wrong with the following declaration and what does it mean (or vice versa regarding the "*" dereference):
objectPtr->leftPtr = *smallObject->leftPtr;
Thanks, I appreciate any help you all can provide. If there is any way I can be of help or assistance to you or the community, let me know.
-- modified at 20:02 Saturday 17th September, 2005
|
|
|
|
|
First assume
objectPtr->leftPtr = 1111
and
smallObject->leftPtr = 2222
then
BlitzPackage wrote:
objectPtr->leftPtr = smallObjectPtr->leftPtr
will assign the value of 2222 to objectPtr->leftPtr
while
BlitzPackage wrote:
*objectPtr->leftPtr = *smallObject->leftPtr
This will assign the contents of the object pointed to by smallObject->leftPtr to the object pointed to by objectPtr->leftPtr. In otherwords it will call the assignment operator [i.e. the OtherObject::operator=(const OtherObject&) function].
BlitzPackage wrote:
objectPtr->leftPtr = *smallObject->leftPtr;
Is there anything wrong here? That depends on the definition of the class OtherObject. But the answer is usually, yes. The diference is if the OtherObject class overrides the address-of operator (&) [i.e. the OtherObject* OtherObject::operator&() function], which would return the address of an OtherObject, premuably "this".
|
|
|
|
|
Thanks Ahz. I appreciate your answer and will continue to ruminate over it. Pointers are indeed one of the most challenging parts of C++ to understand, but it is nonetheless essential to so much else that I must master it.
Thanks again.
|
|
|
|
|
Hi,
if you don't like pointers have a look at references (int&).
The main difference is: You can't have NULL references.
Regards
Achim Klein
We can do no great things, only small things with great love. - Mother Theresa
|
|
|
|
|
Achim,
Can you implement binary trees (and other data structures) with references?
It's just a matter of time!
|
|
|
|
|
I tend to 'no', but I'm no professional.
The crucial point is that you can't leave references uninitialized.
If you have a class like this:
class Node
{
Node& l;
Node& r;
};
You need a constructor like:
Node::Node(Node& Left, Node& Right)
: l(Left),
r(Right)
{
...
}
This means: 'You can only create a new Node, if you already have two other Nodes'.
We can do no great things, only small things with great love. - Mother Theresa
|
|
|
|
|
Hi,
You can't create a reference data structure in the same way you would with a pointer data structure. With pointers the compiler does not need to know what the object methods/vars are inorder to point to it. Hence the NULL pointer. As soon as you dereference the pointer you will be accessing the object, just pointing to it is no problem.
However with a reference, you are already "dereferencing a pointer" at compile time as it were. A reference stores the memory address of the object so there needs already to be a memory address for the object. Hence data structures that need to have a copy of themselves can't be just re-written easily. In the example about you would never be able to create a Node object because you would always need a Node to begin with, that Node would need another Node before it, and so on. A vicious circle.
The way around all this is to create some sort of container for the nodes.
class NodeCont
{
public:
NodeCont (void) : m_fIsNull (true) { }
void Set (void) { m_fIsNull = false; }
bool IsNull () { return fIsNull; }
protected:
bool m_fIsNull;
};
Your actual data node could be inheritered from this class. Then your Node class would be easy to update:
class Node
{
public:
Node (NodeCont& left, NodeCont &right) : l (left), r (right) { }
NodeCont& l;
NodeCont& r;
};
For NULL nodes you would just need to check the IsNull function. The trick now is to create presistant memory (memory not on the stack) for all the containers. e.g.:
NodeCont *left = new NodeCont;
NodeCont *right = new NodeCont;
Node N (*left, *right);
And that is how you can get around pointers if you really want to.
regards,
Rich
"Programming today is a race between software engineers striving to build bigger and
better idiot-proff programs, and the Universe trying to produce bigger and better idiots.
So far the Universe is winning." -- Rich Cook
|
|
|
|
|
Hi Richard,
this looks like a really smart approach.
Thanks for sharing your ideas.
Regards
Achim Klein
We can do no great things, only small things with great love. - Mother Theresa
|
|
|
|
|
Hi,
1) What is the difference between the following two declations:
a) *objectPtr->leftPtr = *smallObject->leftPtr
b) objectPtr->leftPtr = smallObjectPtr->leftPtr
In an expression like int* pVal = &Val; you always have 2 involved objects:
- the 'real' object (here: int Val (defined anywhere else))
- the pointer (here: int* pVal )
So, 1a) will copy the content of your 'real' objects as follows:
objectPtr->leftPtr->memberA = smallObject->leftPtr->memberA;
objectPtr->leftPtr->memberB = smallObject->leftPtr->memberB;
objectPtr->leftPtr->memberC = smallObject->leftPtr->memberC;
If OtherObject has a Copy-Constructor 1a) will call it.
And 1b) will copy the content of your pointers (the numerical adress values).
2) How can I tell which one to use?
Depends on what you want to do:
- if you want to copy the content of your object, use 1a)
- if you want to have two pointers pointing at the same object, use 1b)
3) Finally, is there anything wrong with the following declaration and what does it mean (or vice versa regarding the "*" dereference):
Your VC++ compiler should give you a C2440 error.
This line says: OtherObject* = OtherObject . It's like int* = int . Obviously this can't work.
Regards
Achim Klein
We can do no great things, only small things with great love. - Mother Theresa
|
|
|
|
|
Thanks Achim Klein. I appreciate you taking the time to respond. That's more good information.
|
|
|
|
|
Achim Klein wrote:
If OtherObject has a Copy-Constructor 1a) will call it.
Naaah. I suppose you mean copy assignment operator. This invokes the copy constructor: A secondA = firstA if firstA is of type A .
--
The Blog: Bits and Pieces
|
|
|
|
|
Hi Johann,
you're absolutely right. The statement given in 1a) just calls the assignment operator OtherObject& operator=(const OtherObject& Obj) if there is one.
Sorry for that mistake.
Regards
Achim Klein
We can do no great things, only small things with great love. - Mother Theresa
|
|
|
|
|
The basic thing to remember about a pointer of type A* is that it either points at nothing (NULL ) or to a memory address where a chunk of memory resides which size is an even multiple of sizeof(A) .
Imagine a part of the memory space, where an A[4] array resides and a pointer A* pA which points at the first of these A s:
A chunkA[4];
A* pA = A; And this looks like:
| | | | | | |A|A|A|A| | | | | | | |
|_|_|_|_|_|_|0|1|2|3|_|_|_|_|_|_|_|
^
|
|------------- pA Now we can say
A a0 = *pA++;
A a1 = *pA++;
A a2 = *pA++;
A a3 = *pA; Stepping pA once more would take it outside the A[4]. Since we don't know what is there, we don't want to dereference pA if it points there, e.g.:
A a3 = *pA++
A a4 = *pA; have small chances of resulting in expected behavior...
The expressions (a) - (d) will all invoke the copy constructor of A, which in the default case will invoke the copy constructor for all its members that have a copy constructor and make a binary copy of pod mebers that lack copy constructors. Ad infinitum. Sort of.
--
The Blog: Bits and Pieces
|
|
|
|