- 3,372
- 465
C:
TTree* inputTree = (TTree*)source->Get( "<YourTreeName>" );
Could someone please explain me what the above statements mean? I don't understand what " (TTree*) " does (source is a TFile). Thanks.
TTree* inputTree = (TTree*)source->Get( "<YourTreeName>" );
int one = 1; //int on the stack, value of 1
int * oneptr = &one;//pointer on the stack, value of the location of "one"
TTree* inputTree //create a variable named inputTree of type TTree pointer
This is extremely incorrect. It is good coding practice to do exactly the opposite and use the -Wall option in the compiler to make sure it's what you expect, these languages are very strongly typed on purpose. Other languages let you go back and forth between types willy-nilly because the concept of a variable is abstract, in C/C++ they are coupled directly to the structure of memory.cpscdave said:However it is always good coding practice to explicitally cast returned pointers to what type it is.
That is done with the (TTree*).
Hope that make sense!
int i = 10; //32 bits
long j = 100L; //64 bits
long * jp = (int *)jp; //C cast, no checking, telling the compiler that you know better
*jp = 100L; //Write 64 bit constant to 32 bit memory chunk. Holy, memory corruption!
int i = 10;
long j = 100L;
long * jp = static_cast<int *>(jp); //Proper style of cast, will not compile
*jp = 100L;
newjerseyrunner said:This is extremely incorrect.
int* myFunction() { //some stuff}
void myFunction2()
{
int* myPointer;
//a bunch of code
myPointer = (int*) myFunction()
}
cpscdave said:First off you'll notice I said RETURNED pointers.
It has everything to do with readability of the code.
Imagine this situation:you've done nothing to affect the operation of the code. You've cast an int* to an int*.
But 6 months later when you're reviewing the code for whatever reason you won't need to search through the code to figure out what myPointer is supposed to be.
//Assume Child inherits publically from Parent and getObjectByName is implemented elsewhere
Parent * getObjectByName(const char * name);
Child * mychild = getObjectByName("child"); //Will not compile because the return type and assigned type are not the same INVALID!
Child * mychild = (Child*)getObjectByName("child"); //mychild is valid ONLY if it were created with the Child() constructor UNSAFE!
Child * mychild = reinterpret_cast<Child *>(getObjectByName("child")); //mychild is valid ONLY if it were created with the Child() constructor UNSAFE!
Child * mychild = static_cast<Child*>(getObjectByName("child")); //Will not compile because of reason above INVALID!
try {
Child * mychild = dynamic_cast<Child *>(getObjectByName("child")); //mychild is valid if it were created with the Child() constructor OR you've defined a conversion SAFE!
} catch (const std::bad_cast& e) { }
I'm with @newjerseyrunner on this. This is very widely regarded as a poor programming practice. Many C++ projects make it a rule to compile with -Wold-style-cast compilation flag so that (TTree*)source->Get("<YourTreeName>") gets flagged with a warning (or with an error if you've enabled -Werror).cpscdave said:However it is always good coding practice to explicitally cast returned pointers to what type it is.
TTree* inputTree = (TTree*)source->Get( "<YourTreeName>" );
I apologize, that may be my fault. There was a minor issue with what you posted I wanted to clarify about typecasting, but as for your question @tAllan's explanation of pointers is very good. A pointer just points to a block of memory. In your case that block of memory represented a TTree.ChrisVer said:Is it a big problem that I find it difficult to follow the conversation from Post8 and on?
Sorry Chris -- I don't often look in this forum. (Maybe I should check more often to see if there's C++ questions here.)ChrisVer said:Is it a big problem that I find it difficult to follow the conversation from Post8 and on?
...it could indeed help to know the type (class) of which "source" is an instance, hence what type is returned by "source->Get(...)" .I don't think that the definition of these classes could help.