This question already has answers here:
Why is there no call to the constructor? [duplicate]
(3 answers)
Most vexing parse
(1 answer)
What does A a() mean? [duplicate]
(2 answers)
Closed 8 years ago.
#include<iostream>
using namespace std;
class base {
public:
base() {
cout<<"Constructing base \n";
}
virtual ~base() {
cout<<"Destructing base \n";
}
};
class derived: public base {
public:
derived() {
cout<<"Constructing derived \n";
}
~derived() {
cout<<"Destructing derived \n";
}
};
int main(void) {
derived d();
return 0;
}
Why in this program its not calling constructor?
Can Anyone explain?
.......
The problem is that you are declaring a function here:
// function d(), returns a derived object.
derived d();
What you need is
derived d; // C++03, C++11
or
derived d{}; // C++11 only
This is an "interesting" aspect of C++, where anything that can be parsed as a function declaration will be (provided it is in a context where a function can be declared).
See more on variable initialization in GoTW #1 Variable initialization - or is it?.
Try like this:
int main(void) {
derived d;
return 0;
}
When you type derived d() you are declaring a function and not creating object.
Declaration not proper for derived d();
Change it to:
int main(void)
{
derived d; // note the difference
return 0;
}
What you are doing -> derived d(), it declares a function. that returns instance of derived class.
See this for details: http://en.wikipedia.org/wiki/Most_vexing_parse
It is because derived d() is treated as "function d, called without any arguments, returning instance of derived". Google 'most vexing parse'.
int main(void)
{
derived d(); //here you are actually declaring a function
return 0;
}
You should do it like this:
derived d;
Then it will work.
In C++, before a compiler calls a function, it must be aware of the function. Either you need to write the function in the flow before it is called or it should at least be declared before the function is called. So by calling derived d() you have declared a function called d() with return type as derived object, you never created derived object. it should have been like,
int main() {
derived d;
return 0
}
Related
This question already has answers here:
C++ Inheritance: Derived class pointer to a Base class invokes Derived class method
(6 answers)
Closed 2 years ago.
#include <iostream>
using namespace std;
struct Base {
void doBase() {
cout << "bar" << endl;
}
};
struct Derived : public Base {
void doBar() {
cout << "bar" << endl;
}
};
int main()
{
Base b;
Base* b_ptr = &b;
Derived* d_ptr = static_cast<Derived*>(b_ptr);
d_ptr->doBar(); //Why there is no compile error or runtime error?
return 0;
}
The output of this program is bar\n.
d_ptr is in fact pointing to a Base class while it 's calling a derived class member function.
Is it a undefined behaviour or something else?
Yes, it is undefined behavior.
There is no compile-time error because you used static_cast - this is a way to tell the compiler "I know the type better than you do". You are telling your object is Derived. You lied to the compiler - thus the undefined behavior.
It happened to work because doBar() does not use any Derived members.
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.
This question already has answers here:
Problem overridding virtual function
(3 answers)
Closed 7 years ago.
I have a Rabbit struct, and CrazyRabbit struct that inherits it.
When I execute this code:
#include <iostream>
using namespace std;
struct Rabbit {
virtual void sayCry() {
cout << "..." << endl;
}
};
struct CrazyRabbit : Rabbit {
void sayCry() { cout <<"Moo"<< endl; }
};
void foo(Rabbit r, Rabbit* pr, Rabbit& rr) {
r.sayCry();
pr->sayCry();
rr.sayCry();
}
int main(int argc, char *argv[]) {
Rabbit *pr = new CrazyRabbit();
foo(*pr, pr, *pr);
}
I have the results:
...
Moo
Moo
Why the first case executes the method in super class? Is there any rule for execution defined in C++?
foo()'s first argument type is not a pointer, what you're actually doing is copying into an instance of the superclass. This is because every function parameter gets initialized with whatever you provide as arguments when you actually call the function. So it's as if you had done the following:
Rabbit r = *pr; // (from your main()) object slicing happens here
Rabbit* pr = pr; // (the rhs pr is from your main(), not the pr from foo())
Rabbit& rr = *pr; // (from your main())
So in the first case, you are simply declaring an object of type Rabbit and assigning its derived class, which causes object slicing, meaning that any data that belongs to the derived class CrazyRabbit is lost and the only data that is left is that of the Rabbit type.
For virtual function calls, you require a pointer. At run time, C++ will check the vptr and vtbl to correctly identify which virtual function to call.
This is called "Object Slicing", what you are actually doing is to assign a pointer to derived class object to base class type, the compiler will slice off the things so that it matches with the base class type.
Since, here the base class does not know anything about derived class's function cry(), it will slice it off, and after that compiler can only see base class's cry().
in this example: Though you may think objA will have a,b & c but the "c" of derived is sliced by the compiler.It is called UpCasting.
class A
{
public:
int a, b;
A()
{
a = 10;
b = 20;
}
};
class B :public A
{
public:
int c;
B()
{
c = 30;
}
};
int main()
{
A objA;
B objB;
objA = objB;
return 0;
}
This question already has answers here:
What is object slicing?
(18 answers)
Closed 8 years ago.
For instance, consider:
class Deriv : public Base {...};
...
bar(Deriv d);
bar(Base b);
foo(Base b) {bar(b);}
...
Deriv x;
foo(x); // does x get treated as Base for the bar() call
// or retain its Deriv type?
And also what if foo passes by reference?
You're passing by value, hence you're creating a new object of type Base and doing a copy assign to it..
Very bad, you'll experience slicing..it will not retain it's stage an not suggested.
http://en.wikipedia.org/wiki/Object_slicing
Either pass by reference or const reference which is anyhow better and quicker:
bar(const Base& b)
or pass a pointer to the object and you'll retain the state.
bar(Base* b);
That would be the correct way to handle this.
In your example, x will be a Base, this is because you are creating a new Base object when you call the function. That is, on the function call, the constructor for Base is called, creating a Base b copied from the argument's (x's) Base subobject (known as object slicing). It's not being treated as a Base, it creates a new Base
If you, however, take the argument as a Base &, it will be treated as a Derived, consider the following code:
#include <iostream>
class Base {
public:
virtual void func() const {
std::cout << "Base::Func()" << std::endl;
}
};
class Derived : public Base {
public:
virtual void func() const {
std::cout << "Derived::Func()" << std::endl;
}
};
int do_func_value(Base b){
b.func(); // will call Base::func
}
int do_func_ref(const Base & b){
b.func(); // will call whatever b's actual type is ::func
}
int main(void){
Derived d;
do_func_value(d);
do_func_ref(d);
return 0;
}
this outputs:
Base::Func()
Derived::Func()
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Public virtual function derived private in C++
class B
{
private:
int b;
public:
B(int i);
virtual void show()
{
cout<<"B::show()called. "<<b<<endl;
}
};
B::B(int i=0)
{
b=i;
}
class D:public B
{
private:
int d;
void show()
{
cout<<"D::show() called. "<<d<<endl;
}
public:
D(int i, int j);
};
D::D(int i=0, int j=0):B(i)
{
d=j;
}
void fun(B&obj)
{
obj.show();
}
/*if I redefine fun() as follow, the result would be the same
void fun(B*obj)
{
obj->show();
}
*/
int main()
{
D *pd=new D(5,8);
fun(*pd); //K
delete pd;
}
The output of the program is "D::show() called.", which means the virtual function declared in the private part of class D is invoked. Don't you think it weird? How could a private member of a class be accessed from outside?
The crucial part is that your function void fun(B&obj) takes an argument of static type B& (so a conversion happens at the call site; the same happens with B*).
Since B::show is public, your code has no problem calling it. When the compiler looks at how to dispatch the call it sees that show is virtual so it calls D::show. The fact that you could not have called D::show if obj was of type D is irrelevant.
Unlike Java, in C++ the access specifier doesn't affect the virtual functions.
'Access specifier' is a compile time check which is made on the class method with respect to static type of the handle. e.g. in your code obj is of type B and B::show() is public; hence the code is legal.
obj may refer dynamically to some other type than B.
Remember that virtual function dispatch is a runtime phenomena. (In Java it would have given a runtime error.)
B::show() is public and once it's invoked, the virtual functionality will kick in and call the appropriate object's function.
If you try calling D::show() directly then you will get the expected compiler error.
It's not weird. In B, the method is public. You can call show() on a B object.
It's just that the method gets dispatched to an extending class.