I am wondering that how a pointer of Derived Class can points to Base Class after type conversion and access then the elements of Derived Class also
#include<iostream>
using namespace std;
class Base
{
private:
int b;
public:
void setB(int x) { b = x; }
int getB() { return b; }
};
class Derived : public Base
{
private:
int d;
public:
void setD(int x) { d = x; }
int getD() { return d; }
};
int main()
{
cout << endl;
Derived dObj;
Base * bPtr = &dObj;
bPtr->setB(10);
cout << bPtr->getB() << endl;
//bPtr->setD(11); //error: 'class Base' has no member named 'setD'; did you mean 'setB'?
//cout << bPtr->getD() << endl; //error: 'class Base' has no member named 'getD'; did you mean 'getB'?
((Derived *)bPtr)->setD(11);
cout << ((Derived *)bPtr)->getD() << endl;
cout << endl;
//-------------------------
Base bObj;
//Derived * dPtr = &bObj; //error: invalid conversion from 'Base*' to 'Derived*' [-fpermissive]
**//Derived Class Pointer points to Base Class Object**
Derived * dPtr = (Derived *)&bObj;
**//How can this be done? Class Base do any such member?**
dPtr->setB(20);
cout << dPtr->getB() << endl;
dPtr->setD(21);
cout << dPtr->getD() << endl;
cout << "Base Class = " << sizeof(class Base) << ", Object = " << sizeof(bObj) << endl;
cout << "Derived Class = " << sizeof(class Derived) << ", Object = " << sizeof(dObj) << endl;
cout << endl << endl;
}
In above code how can Derived Calls pointer dptr set the value of Derived::d using setD(), because I have declared object of Class Base which do not have the member d.
I have tried printing the size of Class Base and its object and then printed sizeof Class Derived and its object and code sizes as 4, 4, 8, 8 respectively. Which are correct and I was expecting the same. But I am still confused that I am accessing a memory which is not allocated. Am I accessing garbage or out of bound memory?
Related
I have some doubts about the result of the following snippet. Thank you in advance!
why isn't the B1 destructor called? In my opinion, "Dest B" should display ahead of "Dest A"
Any explanation would be appreciated.
class A1 {
public:
A1() { cout << "Const A" << endl; }
~A1() { cout << "Dest A" << endl; }
virtual const char* ClassName() const{ return ("A"); }
};
class B1:public A1 {
public:
B1() { cout << "Const B" << endl; }
~B1() { cout << "Dest B" << endl; }
virtual const char* ClassName() const { return ("B"); }
};
void foo1(A1 *a1)
{
cout << "foo1 has been passed an object of class " << a1->ClassName() << endl;
delete a1;
}
int main()
{
B1 *b1 = new B1;
foo1(b1);
return 0;
}
Since your class A1 has non-virtual destructor, your delete a1 produces undefined behavior. It is illegal to apply delete to a pointer of type A1 * when the pointer actually points to a B1 object, unless class A1 has virtual destructor.
What you observe is just a specific manifestation of undefined behavior.
Declare A1's destructor as virtual and you should start observing the proper behavior.
I have a base class named A containing a string type parameter.
Class B is derived from A.
I define class C have parameter A* a, and
assign it to B.
In the main function, I cannot get the string value of the base class as it became blank when b deconstructs.
I want it to output:
"Hello!"
"Hello!"
end
But the output is:
"Hello!"
end
Here is my code:
class A {
public:
string str;
};
class B : public A {
public:
B(string _str) {
str = _str;
}
};
class C {
public:
A *a;
public:
void printOut() {
B b("Hello!");
a = &b;
cout << a->str << endl;
}
};
int main() {
C c;
c.printOut();
cout << c.a->str << endl;
cout << "end" << endl;
return 0;
}
How can I deal with it?
Correct, because B b("Hello!"); goes out of scope, c.a is now a dangling pointer that will cause undefined behaviour upon being dereferenced. If you want it to outlive the scope you could allocate it on the heap instead :
class A {
public:
string str;
};
class B : public A {
public:
B(string _str) {
str = _str;
}
};
class C {
public:
A *a;
public:
void printOut() {
B* b = new B("Hello!");
a = b;
cout << a->str << endl;
}
};
int main() {
C c;
c.printOut();
cout << c.a->str << endl;
cout << "end" << endl;
delete c.a;
return 0;
}
This gets messsy real fast though because you have to track the memory allocated yourself and call delete appropriately, consider redesigning or using smart pointers.
Why are you storing an A* ? You know that doesn't work, so stop doing it.
Make a copy of the A object, or a copy of the string it contains, and stop trying to do something silly.
class A {
public:
string str;
};
class B : public A {
public:
B(string _str) {
str = _str;
}
};
class C {
public:
string str;
public:
void printOut() {
B b("Hello!");
str = b.str;
cout << str << endl;
}
};
int main() {
C c;
c.printOut();
cout << c.str << endl;
cout << "end" << endl;
return 0;
}
I have problem with clone() method in the following example. I have expected that sizeof(*((*ptr1).clone())) would be the same as b1 and sizeof(*(ptr2.clone())) would be the size of c1 but they are not. They are sizeof(a1). What am I missing?
Here is the code.
class A
{int a;
public:
virtual A * clone() {return this;}
};
class B : public A
{int b,c;
public:
B * clone() {return this;}
};
class C : public A
{int b,c,d;
public:
C * clone() {return this;}
};
int main()
{
A a1;
B b1;
C c1;
A * ptr1 = &b1;
A & ptr2 = c1;
std::cout << "sizeof(a1) = " << sizeof(a1) << '\n';
std::cout << "sizeof(b1) = " << sizeof(b1) << '\n';
std::cout << "sizeof(*(b1.clone())) = " << sizeof(*(b1.clone())) << '\n';
std::cout << "sizeof(c1) = " << sizeof(c1) << '\n';
std::cout << "sizeof(*((*ptr1).clone()))" << sizeof(*((*ptr1).clone())) << '\n';
std::cout << "sizeof(*(ptr2.clone()))" << sizeof(*(ptr2.clone())) << '\n';
return 0;
}
sizeof(*((*ptr1).clone())) is a compile time value, and expression is not executed.
so here we have sizeof(*((*std::declval<A*>()).clone())) which is sizeof(A) (we use A::clone() which returns A*).
sizeof only takes the static type of its argument into account, not the dynamic type. Thus the argument to sizeof can be an unevaluated operand, and the result of sizeof does not depend on any run-time information (such as vtables required for dynamic type information). And so the result of sizeof is always a compile-time constant expression, suitable to be used e.g. as a template argument.
See C++11: ยง5.3.3 [expr.sizeof]/2.
The following test code seems to indicate that if a class has two abstract base classes with common pure virtual methods, then these methods are "shared" in the derived class.
#include <iostream>
#include <string>
using namespace std;
struct A
{
virtual string do_a() const = 0;
virtual void set_foo(int x) = 0;
virtual int get_foo() const = 0;
virtual ~A() {}
};
struct B
{
virtual string do_b() const = 0;
virtual void set_foo(int x) = 0;
virtual int get_foo() const = 0;
virtual ~B() {}
};
struct C : public A, public B
{
C() : foo(0) {}
string do_a() const { return "A"; }
string do_b() const { return "B"; }
void set_foo(int x) { foo = x; }
int get_foo() const { return foo; }
int foo;
};
int main()
{
C c;
A& a = c;
B& b = c;
c.set_foo(1);
cout << a.do_a() << a.get_foo() << endl;
cout << b.do_b() << b.get_foo() << endl;
cout << c.do_a() << c.do_b() << c.get_foo() << endl;
a.set_foo(2);
cout << a.do_a() << a.get_foo() << endl;
cout << b.do_b() << b.get_foo() << endl;
cout << c.do_a() << c.do_b() << c.get_foo() << endl;
b.set_foo(3);
cout << a.do_a() << a.get_foo() << endl;
cout << b.do_b() << b.get_foo() << endl;
cout << c.do_a() << c.do_b() << c.get_foo() << endl;
}
This code compiles cleanly in g++ 4.1.2 (admittedly old), using -std=c++98 -pedantic -Wall -Wextra -Werror. The output is:
A1
B1
AB1
A2
B2
AB2
A3
B3
AB3
This is what I desire, but I question whether this works generally, or only "by accident." Fundamentally, this is my question: can I depend on this behavior, or should I always inherit from a virtual base class for this type of scenario?
Don't make it harder than it is. A function with the same signature as a virtual function in a base class overrides the base version. Doesn't matter how many bases you have, or whether another base has a virtual function with the same signature. So, yes, this works.
If I create a static const in the base class of my hierarchy, can I redefine its value in a derived class?
edit:
#include <iostream>
class Base
{
public:
static const int i = 1;
};
class Derived : public Base
{
public:
static const int i = 2;
};
int main()
{
std::cout << "Base::i == " << Base::i << std::endl;
std::cout << "Derived::i == " << Derived::i << std::endl;
Base * ptr;
ptr= new Derived;
std::cout<< "ptr=" << ptr->i << std::endl;
return 0;
}
...ptr refers to Base::i, which is undesirable.
Access via ptr to static members is via its declared type Base * and not its runtime type (sometimes Base *, sometimes Derived *). You can see this with the following trivial extension of your program:
#include <iostream>
class Base
{
public:
static const int i = 1;
};
class Derived : public Base
{
public:
static const int i = 2;
};
int main()
{
std::cout << "Base::i == " << Base::i << std::endl;
std::cout << "Derived::i == " << Derived::i << std::endl;
Base *b_ptr = new Derived;
std::cout<< "b_ptr=" << b_ptr->i << std::endl;
Derived *d_ptr = new Derived;
std::cout<< "d_ptr=" << d_ptr->i << std::endl;
return 0;
}
Output:
Base::i == 1
Derived::i == 2
b_ptr=1
d_ptr=2
No. It's const, so you cannot modify its value.
But you can declare a new static const of the same name for the derived class, and define its value there.
#include <iostream>
class Base
{
public:
static const int i = 1;
};
class Derived : public Base
{
public:
static const int i = 2;
};
int main()
{
std::cout << "Base::i == " << Base::i << std::endl;
std::cout << "Derived::i == " << Derived::i << std::endl;
return 0;
}
you must initiate the const memember variable in the Constructor member initialization list.
you can not modify the const variable.