问题
Why the sizeof any pointer is 4 or 8 bytes, but it cannot fit any different variable? I get error while trying to assign a double pointer an int pointer value.
int *int_ptr{nullptr};
float *float_ptr{nullptr};
double *double_ptr{nullptr};
long double *long_double_ptr{nullptr};
string *string_ptr{nullptr};
vector<int> *vector_ptr{nullptr};
cout << "sizeof int pointer is " << sizeof int_ptr; //8 or 4
cout << "sizeof float pointer is " << sizeof float_ptr; //8 or 4
cout << "sizeof double pointer is " << sizeof double_ptr; //8 or 4
cout << "sizeof double double pointer is " << sizeof long_double_ptr; //8 or 4
cout << "sizeof string pointer is " << sizeof string_ptr; //8 or 4
cout << "sizeof vector int pointer is " << sizeof vector_ptr; //8 or 4
double double_num{1020.7};
double_ptr = &int_ptr; //cannot convert ‘int**’ to ‘double*’ in assignment
回答1:
C++ is a statically typed language. The language enforces type safety and protects you from mistakes by rejecting arbitrary conversions between unrelated types. The meaning of a type is not wholly described by the size alone.
If an address contains an object of type int*
, then a int**
can point to that object. Given that the address contains an object of type int*
, it cannot possibly also contain an object of type double
, so there is no meaningful way to convert one of those pointers to another.
回答2:
Pointers are addresses. Let's say, you have two addresses:
- 53 Main avenue
- 85 WrongTurn Road
The first one is the address to a small 2 bedrooms house. The second is the address is to a mansion, 23 bedrooms, 10 bathrooms, etc...
You cannot expect all people living in the mansion to move into the small house rigth? but guess what? at the post office, their box sizes is just the same! That's how they work. They just tell you where to find your variable. Thay are not containers
回答3:
This code is illegal because there is no "implicit conversion" to map from &int_ptr
to double_ptr
, where an "implicit conversion" is defined as something:
Performed whenever an expression of some type
T1
is used in context that does not accept that type, but accepts some other typeT2
; in particular:
- when the expression is used as the argument when calling a function that is declared with
T2
as parameter;- when the expression is used as an operand with an operator that expects
T2
; when initializing a new object of typeT2
, including return statement in a function returningT2
;- when the expression is used in a switch statement (
T2
is integral type);- when the expression is used in an if statement or a loop (
T2
is bool). The program is well-formed (compiles) only if there exists one unambiguous implicit conversion sequence fromT1
toT2
.
I initially suggested you use a reinterpret_cast but this won't work either as using the result of a reinterpret_cast
between types is only legal if the types differ only by whether their signed, the type being cast to is a byte*
, char*
, or unsigned char*
, or the types are "similar" which is defined as:
- they are the same type; or
- they are both pointers, and the pointed-to types are similar; or
- they are both pointers to member of the same class, and the types of the pointed-to members are similar; or
- they are both arrays of the same size or both arrays of unknown bound, and the array element types are similar.
As you can see none of these situations apply to wanting to cast from the address of int* int_ptr
to double* double_ptr
. It's difficult for me to predict your use case for this type of cast within a strongly typed language, but perhaps a void*
is what you're looking for? It could point to either a valid int**
, in which case you could initialize it like this: const void* ptr = reinterpret_cast<void*>(&int_ptr)
or a valid double*
in which case you'd initialize it like this: const void* ptr = reinterpret_cast<void*>(double_ptr)
. Of course in order to use ptr
you'd need a variable telling you which type it contained, for example:
if(is_int) {
// recover int** (reinterpret_cast<const int* const*>(ptr)) and operate on it
} else {
// recover double* (reinterpret_cast<const double*>(ptr)) and operate on it
}
Live Example
I should admit at this point that this answer is somewhat contrived. A better solution anywhere this code is used would very likely be a template.
来源:https://stackoverflow.com/questions/55573060/why-cant-pointer-fit-variable-of-different-type-even-though-sizeof-is-same