I am looking into the pointers and I came up with code like that
class b
{
}
class d
{
}
d* a = 0;
b *t = new b();
*t = * ( b* )a;
What does this declaration mean?
What value does t have?
t will still be pointing to the object created with new b();. *t = changes the value of what t points to, not t itself.
Your last line contains undefined behavior as you're derefenrencing a null pointer. Also, your cast is actually a reinterpret_cast in disguise, which is something you shouldn't do.
Related
Lets assume the following code compiles:
int main()
{
A* p = new B(); // 1
C& c = p->method(); // 2
*c = *p; // 3
c = *p; // 4
}
given there is not a single operator= that expects the class A,B, C and not a single casting operator to any of those to any of those.
Is it possible that B inherits from A inherits from C?
And how is it possible that both line 3 and line 4 will compile?
This line
*c = *p
could never compile without overloading the *operator for C. References, while having a lot of similarities to pointers, are not pointers. They are not memory addresses and thus cannot be dereferenced. Instead, they act as pointers that are automatically dereferenced whenever used. Furthermore, references can't be reassigned to point to different objects so although the code would compile if you changed it to c = *p, it wouldn't work as intended. c would still be pointing to the object that method returned.
The relations you described between A, B and C could be the case if you made c a pointer to C instead of a reference, as well as remove the line 4. The code would then look like this:
int main()
{
A* p = new B(); // works because B inherits from A
C* c = p->method(); // works because is "method" is a member function
// of A and returns a pointer to an instance of C
c* = *p; // works because A inherits from C
}
I have a base class and a derived class
class A
{
public:
int a;
}
class B : public A
{
public:
int b;
}
if i have a pointer of type A to a B object, how can i retrieve the pointer to the B object?
i.e.
A * ptrA = new B;
how can i use ptrA to access b?
If you are sure the A* is actually pointing to a B, you can do it unconditionally with no performance overhead:
A * ptrA = new B;
B * ptrB = static_cast<B *>(ptrA);
ptrB->b = 42;
This will result in undefined behavior if ptrA doesn't actually point to an instance of B. If you aren't sure, you can check it this way:
if (B * ptrB = dynamic_cast<B *>(ptrA)) {
ptrB->b = 42;
} else {
// it's not a B, do something else
}
The difference here is that dynamic_cast will actually check at runtime to make sure the cast is good, and return NULL if not.
Please note that dynamic_cast will only work if your base class has at least one virtual method. Thanks to Dietmar Kühl for pointing that out in the comments.
Since your A* was obtained by a direct implicit conversion from B* you can use
static_cast<B*>(ptrA)->b
If you need to do so frequently in your code rather than just once in a blue moon, there is something wrong with your design though.
You may cast like (B*)ptrA->memberOfB() in c-style cast. Or more safely: dynamic_cast<A*>(ptrA).
ptrB = dynamic_cast<A*>(ptrA);
if(ptrB!=null)
{
//casted properly
ptrB->memberOfB();
}
else
{
//can not be casted
}
I have a doubt about downcasting an object in C++.
Here it comes an example:
class A { }
class B : public A {
public:
void SetVal(int i) { _v = i; }
private:
int _v;
}
A* a = new A();
B* b = dynamic_cast<B*>(a);
b->SetVal(2);
What would it happen with this example? We are modifying a base clase like if it is a child one... how does it work related with the memory?
With this cast... Is it like creating an instance of B and copying the values of A?
Thanks
A* a;
This just gives you a pointer to an A. It doesn't point anywhere in particular. It doesn't point at an A or B object at all. Whether your code works or not depends on the dynamic type of the object it is pointing at.
So there are two situations you might want to know about. First, this one:
A* a = new A();
B* b = dynamic_cast<B*>(a);
b->SetVal(2);
This will give you undefined behaviour because the dynamic_cast will return a null pointer. It returns a null pointer when the dynamic type of the object is really not a B. In this case, the object is an A. You then attempt to dereference the null pointer with b->SetVal(2), so you get undefined behaviour.
A* a = new B();
B* b = dynamic_cast<B*>(a);
b->SetVal(2);
This will work fine because the object really is a B object. The dynamic cast will succeed and the SetVal call will work just fine.
However, note that for this to work, A must be a polymorphic type. For that to be true, it must have at least one virtual member function.
That shouldn't even compile, because the classes aren't polymorphic so you can't use dynamic_cast.
If it did, it would be undefined behavior.
I'm new to C++, and are confused about sth
I'm going to define a class, and when should I define a member a pointer? or when should I define a member a value? or when should I just define it as a reference?
what confused me is when I read the book TCPL 24.3.3
It said that
"The pointer solution should be used when there is a need to change the pointer to the ‘‘contained’’ object during the life of the ‘‘containing’’ object. For example:
class C
{
int a;
public:
C(int i):a(i){};
};
class C2
{
C a;
C *p;
public:
C2(int i):a(i), p(new C(i)){};
~C2(){delete p;}
C ChangeValue(C c)
{
C temp = a;
a = c;
return temp;
}
C* ChangePointer(C *c)
{
C* temp = p;
p = c;
return temp;
}
};
I think there is no difference using a valus as a class member....
please help me through this:)
The best way to think about pointers is "shallow copy" vs "deep copy". When I work with a particular object, is it ok that it will be duplicated when I pass it to a different scope (a different function or class)? If I don't want it to be copied, I should use a pointer, otherwise I can just declare it as a value (I should note that passing by reference is a way around this general rule).
Really it depends on your application. Sometimes I will design a particular class with pointers as members and then find out that it makes more sense to switch and vice-versa.
"The pointer solution should be used when there is a need to change the pointer to the ‘‘contained’’ object during the life of the ‘‘containing’’ object"
Pointers can be pointed to different object types.
References are just alias of types and cannot be bound to other types. They remain alias to the object to which they were bound at time of declaration.
For Example:
int i,j,k;
i = 10;
j=20;
k=30;
int *ptr;
ptr = &i; //ptr now points to i
ptr = &j; //ptr now points to j, Allowed!
int &ref = i; //ref is alias of i
ref = j; //Allowed BUT It assigns value of j to i and doesnt point ref to j
The statement means if you want your member variable to be pointing to different objects then it should be pointer then it should be reference.
Note: You can acheive same behavior for pointers as references by using const pointers.
I have seen this in our code a couple times and it immediately makes me suspicious. But since I don't know the original intent I am hesitant to remove it.
//requires double indirection which I won't go into
FooClass::FooFunction(void ** param)
{
//do something
}
SomeClass * A = new SomeClass();
SomeClass **B = &A;
FooFunction( reinterpret_cast<void**>(&*B) ); // what is happening here?
The "&*B" part is the part in question? Feel free to integrate explanation of the reinterpret cast but I am pretty familiar with cast techniques.
I've done similar things with iterators - dereference the iterator to get a reference, and then do the "&" operator to get a pointer.
I don't see why it would be doing anything here though. If the type to the right of "&*" is a pointer type it does nothing.
I can see only one reason for this: B has overloaded operator*() to return an X, but whoever wrote the code needed an X*. (Note that in your code, X is A*.) The typical case for this is smart pointers and iterators.
If the above isn't the case, maybe the code was written to be generic enough to deal with smart pointers/iterators. Or it used to use smart pointers and whoever changed it didn't bother changing &*, too? Have you poked through its history to see when this was introduced and what the code looked then?
Consider the following sample;
class A {
public:
int f() { return 55; }
};
class B {
public:
B( A* a ) : a(a) {}
A*& operator*() { return a; }
A* a;
};
int main () {
A* a = new A();
B b = a;
// &* calls operator*, then gets address of A
void** x = reinterpret_cast<void**>(&*b);
cout << reinterpret_cast<A*>( *x )->f() << endl; // prints 55
void** x2 = reinterpret_cast<void**>( b ); // compile error
}
Your last edit of question leads to:
A* a = new A();
A** b = &a;
void** x = reinterpret_cast<void**>(&*b); // now this is equal to the following
void** x2 = reinterpret_cast<void**>( b ); // so using &* make no sense