This question already has answers here:
Calling a virtual function from the constructor
(3 answers)
Closed 5 years ago.
#include <iostream>
class Base {
public:
virtual void method() {
std::cout << "Base" << std::endl;
}
Base() {
method();
}
};
class Sub : public Base {
public:
virtual void method() {
std::cout << "Sub" << std::endl;
}
Sub() : Base() {
}
};
int main(void) {
Base *b = new Sub();
delete b;
system("PAUSE");
return 0;
}
Output: "Base"
What do i have to change to make the Base call the Sub Method instead of the Base?
This is probably a duplicate and a beginner-question, but i couldn't find an answer to this problem.
Also a suggestion for a better title is welcome as the current one might be wrong.
a) because the standard says so.
b) philosophically, because Sub at this point has not had its constructor called (inherited objects are constructed in a depth-first manner), so calling Subs version of method would surprise the author of Sub.
Related
This question already has answers here:
Why does an overridden function in the derived class hide other overloads of the base class?
(4 answers)
Closed 1 year ago.
This does not compile:
struct Base
{
void something( int a ) { }
};
struct Derived : public Base
{
static void something()
{
std::unique_ptr<Derived> pointer = std::make_unique<Derived>();
pointer->something( 11 );
}
};
It’s possible to fix with using Base::something but still, is it possible to make inheritance work as advertised even inside methods?
By using the same name for the function in the derived class you hide the symbol from the base class.
You can solve it by pulling in the name from the base class with the using statement:
struct Derived : public Base
{
// Also use the symbol something from the Base class
using Base::something;
static void something()
{
std::unique_ptr<Derived> pointer = std::make_unique<Derived>();
pointer->something( 11 );
}
};
I'm not exactly sure what you are trying to accomplish. I added virtual, and changed the name of the Derived something class function, and put in two variants. One variant calls through virtual inheritance, the other calls Base class member function directly.
#include <iostream>
using std::cout;
namespace {
struct Base {
virtual ~Base();
virtual void something(int a) { std::cout << "Base a:" << a << "\n"; }
};
Base::~Base() = default;
struct Derived : Base {
void something(int b) override { std::cout << "Derived b:" << b << "\n"; }
static void action() {
std::unique_ptr<Derived> pointer = std::make_unique<Derived>();
pointer->something(11);
}
static void other_action() {
std::unique_ptr<Derived> pointer = std::make_unique<Derived>();
pointer->Base::something(11);
}
};
} // anon
int main() {
Derived::action();
Derived::other_action();
}
This question already has answers here:
Calling child method from parent destructor in C++
(3 answers)
Closed 1 year ago.
#include <iostream>
using namespace std;
class Super {
public:
virtual ~Super() {
func();
}
virtual void func() {
cout << "super-class" << endl;
}
};
class Child : public Super {
public:
virtual void func() override {
cout << "child-class" << endl;
}
};
int main(void) {
Super super;
Child child;
return 0;
}
In this code, the default destructor of class Child is calling its super class Super's func() instead of its own overrided func(). And the output was:
super-class
super-class
I've tried this solution below.
#include <iostream>
using namespace std;
class Super {
public:
virtual ~Super() {
func();
}
virtual void func() {
cout << "super-class" << endl;
}
};
class Child : public Super {
public:
virtual ~Child() {
func();
}
virtual void func() override {
cout << "child-class" << endl;
}
};
int main(void) {
Super super;
Child child;
return 0;
}
And the output was:
child-class
super-class
super-class
But is there a way to let class Child automatically call its own func() in its destructor without virtual ~Child()?
By the time a base class destructor has started running, the derived class(es) have already been fully destructed. It (they) no longer exist(s). They cannot be called into. They are EX-objects! (Loosely paraphrasing Herb, paraphrasing the John.)
Level by level, as the object dies, the parts of it that have been destroyed are not left behind; they no longer exist. The type is adjusted accordingly upwards, and virtual calls resolve to the type being destroyed, until nothing is left of that object but a pile of bits.
This question already has answers here:
What is object slicing?
(18 answers)
Closed 9 years ago.
I have the following piece of code (#includes and using namespace std omitted):
class A {
public:
void call(){callme();}
private:
virtual void callme() {cout << "I'm A" << endl;}
};
class B : public A {
private:
virtual void callme() {cout << "I'm B" << endl;}
};
class C : public B {
public:
virtual void callme(){ cout << "I'm C" << endl;}
};
int main(){
vector<A> stuff = {
A(), B(), C(),
};
stuff[0].call(); // output: I'm A
stuff[1].call(); // output: I'm A
stuff[2].call(); // output: I'm A
return 0;
}
As stated in the comments, the output of the above program is:
I'm A
I'm A
I'm A
However, I would like that C++ automatically recognizes the type with which the corresponding element was created. I.e. I would like that C++ outputs
I'm A
I'm B
I'm C
(That is, the compiler shall pick the proper subclass for me.)
Is this possible in this scenario (i.e. if all the elements come out of a vector)?
Member functions virtuality works only when you call them from pointer to the actual object, not from an object itself, because in your example objects were automatically statically upcasted to class A. Change your code to:
std::vector<std::unique_ptr<A>> stuff = {
std::unique_ptr<A>(new A()),
std::unique_ptr<A>(new B()),
std::unique_ptr<A>(new C()),
};
stuff[0]->call();
stuff[1]->call();
stuff[2]->call();
For C++ Polymorphism, you should use either pointer or reference. You could do like this
int main(){
vector<A*> stuff;
stuff.push_back(new A);
stuff.push_back(new B);
stuff.push_back(new C);
stuff[0]->call(); // output: I'm A
stuff[1]->call(); // output: I'm A
stuff[2]->call(); // output: I'm A
while (!stuff.empty()){
delete stuff.back();
stuff.pop_back();
}
return 0;
}
Reference: http://www.cplusplus.com/doc/tutorial/polymorphism/
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Calling virtual functions inside constructors
main.cpp
#include <iostream>
class BaseClass {
public:
BaseClass() {
init();
}
virtual ~BaseClass() {
deinit();
}
virtual void init() {
std::cout << "BaseClass::init()\n";
}
virtual void deinit() {
std::cout << "BaseClass::deinit()\n";
}
};
class SubClass : public BaseClass {
public:
virtual void init() {
std::cout << "SubClass::init()\n";
}
virtual void deinit() {
std::cout << "SubClass::deinit()\n";
}
};
int main() {
SubClass* cls = new SubClass;
delete cls;
return 0;
}
Why is init() and deinit() not properly overriden and the BaseClasses' methods are called instead of the SubClasses ones? What are the requirements to make it work?
BaseClass::init()
BaseClass::deinit()
Because you are calling a virtual method inside a constructor. While constructing Base class the derived one (SubClass) isn't still constructed, so actually it doesn't still exist.
It's generally a good practice to avoid calling virtual methods inside constructors.
They are overridden just fine.
But you've invoked them from the base constructor, and when the base constructor is executing, the derived part of the object does not yet exist.
So this is a largely a safety feature, and it's mandated by the C++ standard.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is there a way to call an object's base class method that's overriden? (C++)
First question is calling super() constructor in java same as initializing the super class constructor first in c++ like.
sub() : super(){}
is there a way to call super class method in c++ like in java
ex.
public sub(){
super.someMethod();
}
To call the base constructor of a class, you call it as BaseClassName(args). For example:
class A
{
public:
A() { }
virtual void Foo() { std::cout << "A's foo" << std::endl; }
};
class B : public A
{
public:
B() : A() { }
void Foo();
};
To call the base class version of a method, you do BaseClassName::MethodName:
void B::Foo()
{
std::cout << "B's foo" << std::endl;
A::Foo();
}