This question already has answers here:
What is object slicing?
(18 answers)
Closed 8 years ago.
I checked this code, and i saw that by the end of the function func()
the destructor of base class have been called twice.
I dont understand why??
thank you..
class base {
public:
base(){cout << "ctor of base\n";}
~base(){cout << "d-ctor of base\n";}
};
class derived: public base
{
public:
derived(){cout << "ctor of derived\n";}
~derived(){cout << "d-ctor of derived\n";}
};
void func(base ob)
{
cout << "inside func\n";
}
void main()
{
derived ob;
func(ob);
system("pause");
}
Refactoring your base class like this:
class base {
public:
base(){cout << "ctor of base\n";}
base(const base&) {cout << "copy-ctor of base\n";}
~base(){cout << "d-ctor of base\n";}
};
would issue the following output:
ctor of base
ctor of derived
copy-ctor of base
inside func
d-ctor of base
d-ctor of derived
d-ctor of base
Showing pretty clearly your base variable inside func was copied and then destroyed.
base is passed by value to func.
This means a sliced copy of ob will be created.
This will be destroyed as well as ob itself. The destructor of ob (derived::~derived) will automatically call the base classes destructor.
Therefore the base destructor is called two times.
When you call the function you take the parameter by value. Therefore you create a local variable of type base in func.
When you return from func, the local variables are destroyed, so ob's descrutor (which has type base is called.
You have to pass polymorphic types via reference or pointer.
This is called the slicing problem. See this link for details.
Related
This question already has answers here:
Vectors and polymorphism in C++
(4 answers)
What is object slicing?
(18 answers)
Closed 3 months ago.
The code I am working with is for learning purpose only.
I have a vector with Base defined. I want to store both Derived1 and Derived2 objects inside. Single element of a vector is passed to a function. Inside a function I want to call a different prompt depending on if the passed object is actually of type Derived1 or Derived2.
class Super { virtual void v(void) = 0; };
class Base : public Super { inline void v(void) override {} };
class Derived1 : public Base {};
class Derived2 : public Base {};
std::vector<Base> objects;
Derived1 d1;
Derived2 d2;
objects.push_back(d1);
objects.push_back(d2);
void func(Base &b)
{
try
{
(void)dynamic_cast<Derived1 &>(b);
std::cout << "Are you Derived1?" << std::endl;
}
catch (std::bad_cast)
{
try
{
(void)dynamic_cast<Derived2 &>(b);
std::cout << "Are you Derived2?" << std::endl;
}
catch (std::bad_cast)
{
std::cout << "Object type cannot be deduced." << std::endl;
}
}
}
func(objects[0]);
func(objects[1]);
My code always terminates with:
Object type cannot be deduced.
Without Super class as soon as I would type dynamic_cast, compilation phase will abort with an error (Base is not a polymorphic class).
Because Base actually implements virtual method from Super, compilation phase passes, but dynamic_casts between Base and Derived1/2 will always terminate with std::bad_cast because there are no virtual methods that Derived1/2 implement.
How to get around this behaviour without adding virtual function to Base, since I want to be able to instantialise object of Base class as well?
This question already has answers here:
Why aren't copy constructors "chained" like default constructors and destructors?
(3 answers)
Closed 3 years ago.
From my understanding, when creating an object of a derived class the base class constructor get's automatically called (in case a one without parameters exists). This seems to not be the case for copy constructors:
#include <iostream>
class Base
{
public:
Base()
{
std::cout << "Base Constructor called" << std::endl;
}
Base(const Base& ref)
{
std::cout << "Base Copy Constructor called" << std::endl;
}
};
class Derived : Base
{
public:
Derived()
{
std::cout << "Derived Constructor called" << std::endl;
}
Derived(const Derived& ref) //: Base(ref) // <- without this Base copy constructor doesnt get called
{
std::cout << "Derived Copy Constructor called" << std::endl;
}
};
int main()
{
Derived d1;
Derived d2 = d1;
return 0;
}
Output without ": Base(ref)" :
Base Constructor called
Derived Constructor called
Base Constructor called
Derived Copy Constructor called
Output with ": Base(ref)" :
Base Constructor called
Derived Constructor called
Base Copy Constructor called
Derived Copy Constructor called
So unless you explicitly call the Base class copy constructor a new Base class object gets created instead of being copy constructed. So i guess only the Derived class members get actually copy constructed while all Base class members would be newly created by the Base class constructor. Now for me this seems like something you never really want. If you copy construct an object you expect all members to be copied instead of just a part of them.
Why are copy constructors different from normal constructors in this regard?
Why are copy constructors different from normal constructors in this regard?
They aren't. When you do not call a base class constructor, the default constructor is called for you. This happens for every contructor.
This question already has answers here:
Downcasting using the 'static_cast' in C++
(3 answers)
Closed 3 years ago.
I have the below piece of code where I have a base class and a derived class. Both base class and derived class are having a function member sharing the same name. In the main(), I have typecasted a base class object to a derived class pointer and trying to call the function. To my utter surprise, it is calling the derived class function member. As far as I know, the base class object won't be having any information about the derived class object. So, how come my derived class pointer is still able to access the derived member function?
In the case of upcasting, I do understand derived class object will be having the contents of the base class that's why a base class pointer pointing to a derived class object will work as expected.
Can someone please help me in understanding how the derived class member function is getting called in this even when I am having a derived class pointer pointing to a base class object(which is having no information of derived class)?
#include<iostream>
using namespace std;
class base
{
public:
void b()
{
cout << "base";
}
};
class derived:public base
{
public:
void b()
{
cout << "derived";
}
};
int main()
{
base b;
derived * d1;
d1 =static_cast<derived*>(&b);
d1->b();
return 0;
}
In your specific case, it's perfectly normal that b is called.
You have a pointer to Derived class, b it's not virtual. So the compiler will generate a call to Derived::b method.
Now, when b will be executed, as you put crap in the this pointer, it's undefined behavior.
But in your case, as you do not access the this pointer, there's no probleme.
Cast a base class to derived class results undefined behavior
As I know, the function doesn't takes any extra space in memory, it stores like the normal function. You can see a member function as a normal function with an extra this pointer. In general, which function to call is determined by the type of the object pointer. But the virtual function is different, it is called by virtual function table, in your code, there is no virtual function declared. So there is no virtual function table.
You can see your code in a different way:
void derived_b(derived* this)
{
cout << "derived";
}
void base_b(base* this)
{
cout << "base";
}
int main()
{
base b;
derived * d1;
d1 =static_cast<derived*>(&b);
derived_b(d1);
return 0;
}
If you define some member in class, and use it in function b, it may cause some error.like
class base
{
public:
void b()
{
cout << "base";
}
};
class derived:public base
{
int a;
public:
derived(){a = 1;}
void b()
{
cout << "derived" << a;
}
};
your code in main() may cause error because the object b don't have any member in memory.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
why does base class pointer pointing to derived class object still points to base class function, if the functions are not declared as virtual
class Base
{
public:
void draw() { cout << "base" << endl; }
virtual void fun() { cout << "base class function" << endl; }
};
class Derived : public Base
{
public:
void draw() { cout << "derived" << endl; }
void fun() { cout << "derived function" << endl; }
};
int main()
{
Derived d;
d.draw(); //derived
Base *b = &d;
b->draw(); //base
b->fun(); //derived function
return 0;
}
b is a pointer pointing to derived object even then why does b->draw() gives output as "base" but not "derived" ?
The function will have to be virtual to be overridden. That's what virtual means: that it can be overloaded.
In C++, non-virtual class functions and class variables (i.e. instance variables or fields) are called by class of pointer, not class of object. Java methods are virtual by default
The whole point of the virtual keyword is to decide whether re-definition of a function in a derived class means:
virtual: actual redefinition of the existing function interface
non-virtual: just another unrelated member function with the same signature
In the second case, the actual function you call with:
d.draw();
b->draw();
are defined by the compile-time type of the object you call it on, i.e. a Base instance will call Base::draw, whereas a Derived instance will call Derived::draw. Note that you can also statically call the base-defined method with the same name using:
d.Base::draw();
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Calling virtual functions inside constructors
class Base
{
virtual void method()
{ cout << "Run by the base."; };
public:
Base() { method(); };
};
class Derived: public Base
{
void method()
{ cout << "Run by the derived."; };
};
void main()
{
Derived();
}
Output:
Run by the base.
How can one have the derived method run instead, without making a derived constructor?
Calling virtual functions inside constructors
http://www.artima.com/cppsource/nevercall.html
You can't since the "derived" part of the object has not been constructed yet so calling a member function from it would be undefined behavior.
You can't do this without adding extra code.
A common way to achieve this is to use a private constructor and a create function that first calls the constructor (via new) and then a second finish_init method on the newly created object. This does prevent you from creating instances of the object on the stack though.