In the last two lines of below program, static_cast<void*> and dynamic_cast<void *> behave differently. From what I understand, The result of a dynamic_cast<void*> always resolves to the address of the complete object. So it uses RTTI in some way. Could anyone explain how compilers uses RTTI to differentiate between the two.
#include <iostream>
using namespace std;
class Top {
protected:
int x;
public:
Top(int n) { x = n; }
virtual ~Top() {}
friend ostream& operator<<(ostream& os, const Top& t) {
return os << t.x;
}
};
class Left : virtual public Top {
protected:
int y;
public:
Left(int m, int n) : Top(m) { y = n; }
};
class Right : virtual public Top {
protected:
int z;
public:
Right(int m, int n) : Top(m) { z = n; }
};
class Bottom : public Left, public Right {
int w;
public:
Bottom(int i, int j, int k, int m): Top(i), Left(0, j), Right(0, k) { w = m; }
friend ostream& operator<<(ostream& os, const Bottom& b) {
return os << b.x << ',' << b.y << ',' << b.z<< ',' << b.w;
}
};
int main() {
Bottom b(1, 2, 3, 4);
cout << sizeof b << endl;
cout << b << endl;
cout << static_cast<void*>(&b) << endl;
Top* p = static_cast<Top*>(&b);
cout << *p << endl;
cout << p << endl;
cout << static_cast<void*>(p) << endl;
cout << dynamic_cast<void*>(p) << endl;
return 0;
}
Possible output: https://ideone.com/WoX5DI
28
1,2,3,4
0xbfcce604
1
0xbfcce618
0xbfcce618
0xbfcce604
From 5.2.7 / 7:
If T is "pointer to cv void," then the result is a pointer to the most
derived object pointed to by v. Otherwise, a run-time check is applied
to see if the object pointed or referred to by v can be converted to
the type pointed or referred to by T.
So using dynamic_cast<void*>(o) you get a pointer to the first byte of the most "derived" object (if o is polymorphic).
The code the compiler generates for dynamic_cast<void *>(...) is something like:
static_cast<void*>(dynamic_cast<most_derived_type *>(...))
This property is often used for serialization.
Related
cube is a class that from what i know can be both constexpr and not and for some reason c.get() is not constexpr because the second cout prints 5 which mean it changed the value of c to 5 instead of c.get() always returning 1.
class cube
{
private:
int roll;
public:
constexpr cube(const int& r) :roll(r) {}
void set(int const& a) { roll = a; }
constexpr int get() const { return roll; }
constexpr void fun() const
{
(const_cast <cube*> (this))->roll = 5;
}
};
int main()
{
constexpr cube c(1);
std::cout << "Old roll number: " << c.get() << std::endl;
c.fun();
std::cout << "New roll number: " << c.get() << std::endl;
return 0;
}
EDIT:
in the comments some said that the fun() breaks it but here it's still not constexpr as you can see here gcc.godbolt.org/z/zoz7KEqqn
#include<iostream>
class cube
{
private:
int roll;
public:
constexpr cube(const int& r) :roll(r) {}
void set(int const& a) { roll = a; }
constexpr int get() const { return roll; }
};
int main()
{
constexpr cube c(1);
std::cout << "Old roll number: " << c.get() << std::endl;
std::cout << "New roll number: " << c.get() << std::endl;
return 0;
}
I wonder if this code is well defined. Seems to me fine, but hopefully someone can explain this (either correct, or wrong) in standard terms.
template <typename T>
class B {
public:
B (int n) : p {n} {}
T& operator++ () {
++p;
return static_cast<T&> (*this); // (X)
}
int p;
};
class Z : public B<Z> {
public:
using B::B;
int boo = 42;
};
and usage:
Z z {10};
std::cout << z.p << " " << z.boo << "\n";
Z& x = ++z;
std::cout << x.p << " " << x.boo << "\n";
x.boo = 1;
++x;
std::cout << z.p << " " << z.boo << "\n";
What people always do is to have a reference to the base class and pass the derived object to it. Here I have the opposite behavior in (X). Output of usage is as expected. I am asking if extension of Z can cause a problem?
I have inherited from boost::static_visitor<> and defined a class as follows:
class move_visitor : public boost::static_visitor<> {
private:
double m_dx, m_dy;
public:
move_visitor() : m_dx(0.0), m_dy(0.0) {}
move_visitor(double dx, double dy) : m_dx(dx), m_dy(dy) {}
~move_visitor() {}
void operator () (Point &p) const {
p.X(p.X() + m_dx);
p.Y(p.Y() + m_dy);
}
void operator () (Circle &c) const {
Point center_point(c.CentrePoint().X() + m_dx, c.CentrePoint().Y() + m_dy);
c.CentrePoint(center_point);
}
void operator() (Line &l) const {
Point start(l.Start().X() + m_dx, l.Start().Y() + m_dy),
end(l.End().X() + m_dx, l.End().Y() + m_dy);
l.Start(start);
l.End(end);
}
};
This class is supposed to change the x and y position of some objects, Point, Line and Circle.
When I execute the following code:
int main()
{
typedef boost::variant<Point, Line, Circle> ShapeType;
Point p(1, 2);
Line l(p, p);
Circle c(p, 5);
ShapeType shape_variant;
std::cout << p << "\n\n"
<< l << "\n\n"
<< c << "\n\n";
shape_variant = p;
boost::apply_visitor(move_visitor(2, 2), shape_variant);
std::cout << p << std::endl;
shape_variant = l;
boost::apply_visitor(move_visitor(2, 2), shape_variant);
std::cout << std::endl << l << std::endl;
return 0;
}
p remains as 1, 2 and so does l. Why aren't my object changing after 'apply_visitor`?
You're modifying shape_variant, not p or l.
Try
std::cout << boost::get<Point>(shape_variant) << std::endl;
and
std::cout << boost::get<Line>(shape_variant) << std::endl;
how to overload assignment operator to satisfy ob1=ob2=ob3 (ob1,ob2,ob3 are objects of same class) where we have no concern for (ob2 = ob3) which is similar to (ob2.operator=(ob3)) but we need a parameter of type class when we are assigning this result to ob1 which is similar to (ob1.operator=(ob2.operator=(ob3)) below is the code that gives me error
#include<bits/stdc++.h>
using namespace std;
class A
{
public:
int x;
int *ptr;
A()
{
}
A(int a, int *f)
{
x = a;
ptr = f;
}
void operator=(A&);
};
void A::operator=(A &ob)
{
this->x = ob.x;
*(this->ptr) = *(ob.ptr);
}
int main()
{
int *y = new int(3);
A ob1, ob2, ob3(5, y);
ob1 = ob2 = ob3;
cout << ob1.x << " " << *(ob1.ptr) << endl;
cout << ob2.x << " " << *(ob2.ptr) << endl;
cout << ob3.x << " " << *(ob3.ptr) << endl;
return 0;
}
Your asignement operator should return a reference to *this, and be defined as
A& operator=(const A&);
or, better, pass by value and use the copy-and-swap idiom
A& operator=(A);
For an excellent intro to operator overloading, see this.
As you can see, only the overloaded version of the stream insertion operator for the base class is called on both instances. I understand why it's so. It's because there is no dynamic binding. But, how do I fix it?
#include <iostream>
using namespace std;
class A {
int i;
char c;
public:
A(int i = 0, char c = ' ') {
this->i = i;
this->c = c;
}
int getI() { return i; }
char getC() { return c; }
friend ostream& operator << (ostream&, A&);
};
class B : public A {
double d;
public:
B(int i = 0, char c = ' ', double d = 0.0) : A(i, c), d(d) {}
friend ostream& operator << (ostream&, B&);
};
ostream& operator << (ostream& out, A& a) {
out << "\nInteger: " << a.i << "\nCharacter: " << a.c << endl;
return out;
}
ostream& operator << (ostream& out, B& b) {
out << "\nInteger: " << b.getI() << "\nCharacter: " << b.getC() << "\nDouble: " << b.d << endl;
return out;
}
int main() {
A* a = new A (10, 'x');
B* b = new B(20, 'y', 5.23);
A* array[] = { a, b };
cout << *(array[0]);
cout << "\n______________________________\n";
cout << *(array[1]);
delete a;
delete b;
cin.get();
return 0;
}
How can I make cout << *(array[1]); call the overloaded stream insertion operator that takes an object of B as one of it's arguments?
You can't make it call the overloaded operator, since overloading is resolved at compile time.
To do resolution at runtime, i.e. use dynamic dispatch, you need to move the code that does the printing to a virtual member function.
Then call that from the operator (you only need one, for the base class).
class A
{
public:
// ...
// Override this in B
virtual void print(std::ostream& o) const
{
o << "\nInteger: " << i << "\nCharacter: " << c << endl;
}
// ...
};
ostream& operator << (std::ostream& out, const A& a) {
a.print(out);
return out;
}