Consider the following:
// ConsoleApplication1.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <string>
#include <iostream>
using namespace std;
class Foo {
public:
// NVI
bool method() {
cout << "Foo::method" << endl;
return method_impl();
}
// Why not do this instead?
//virtual bool method() final {
// cout << "Foo::method" << endl;
// return method_impl();
//}
private:
virtual bool method_impl() = 0;
};
class Bar : public Foo {
public:
// What stops someone from doing this hiding the Foo::method identifier?
// Uncomment the below and see how the console output is instead Bar::method and then method_impl
//bool method() {
// cout << "Bar::method" << endl;
// return method_impl();
//}
private:
virtual bool method_impl() override {
return true;
}
};
int _tmain(int argc, _TCHAR* argv[]) {
Bar bar = Bar();
cout << bar.method() << endl;
return 0;
}
As you can see above, the Foo class is trying to follow the NVI pattern with the Foo::method() member function.
What prevents a child class, in this case Bar, from hiding the Foo::method() with Bar::method()? I tried it and I guess nothing. If you uncomment Bar::method(), the console application does indeed go down the Bar implementation of method() which makes total sense.
Which begs the question, why not use virtual final to disallow name hiding of that method in a child class? Example provided in the Foo class.
Thanks
Related
I have a Base class, which is then inherited by Foo, and Foo is in turn inehrited by Bar.
Here is the header file base.h for my Base class:
#pragma once
class Base {
public:
void runExample();
private:
virtual void print();
};
And the implementation base.cpp:
#include "base.h"
void Base::runExample() {
print();
}
void Base::print() {};
Here is the header file foo.h for my Foo class:
#pragma once
#include "../base/base.h"
class Foo : public Base {
public:
Foo();
private:
void print();
const char* toPrint;
};
And the implementation foo.cpp:
#include "foo.h"
Foo::Foo() {
toPrint = "Hello Foo";
}
void Foo::print() {
std::cout << toPrint << std::endl;
}
Here is the header file bar.h for my Bar class:
#pragma once
#include "../foo/foo.h"
class Bar : public Foo {
public:
Bar();
private:
const char* toPrint; // "overrides" toPrint from parent class Foo?
};
And the implementation bar.cpp:
#include "bar.h"
Bar::Bar() {
toPrint = "Hello Bar";
}
And finally, my main function:
#include "../bar/bar.h"
int main() {
Bar bar = Bar();
bar.runExample();
}
So, I have this kind of relationship between the classes:
Bar is a Foo which is a Base.
What I was expecting to see in the output was "Hello Bar", but what I actually see is "Hello Foo".
If I "override" the print method declared in Foo in Bar to print toPrint then I get the expected result, however this seems to break the point of inheritance; i.e. why would I need to re-define the functionality when it's already defined.
What I am expecting is that when Bar.print() is invoked, it uses Foos implementation, but the actual field toPrint has been "replaced" with the value inside the Bar implementation.
I am very new to C++, and I'm coming from a Kotlin background. Forgive me if this is like C++ 101 basics, but I'm pretty confused as to why this is happening. Could anyone point me in the right direction?
In C++, data members cannot be "overridden" as you expect, and a reference to toPrint will not be dynamically bound to equally named data members in subclasses.
With
class Bar : public Foo {
...
const char* toPrint; // "overrides" toPrint from parent class Foo?
};
you introduce a member variable Bar::toPrint next to Foo::toPrint, which is inherited. The code
void Foo::print() {
std::cout << toPrint << std::endl;
}
will always stick to the toPrint-member in his scope, i.e. to Foo::toPrint.
The following code illustrates this behaviour:
struct Base {
const char* toPrint = "Base";
virtual void print() const { cout << toPrint << std::endl; }
};
struct Derived: public Base {
const char* toPrint = "Derived";
void printBoth() const { cout << "own:" << toPrint << "; inherited: " << Base::toPrint << std::endl; }
};
int main() {
Derived d;
cout << "call inherited method print:" << std::endl;
d.print();
cout << "call method printBoth, showing both data members:" << std::endl;
d.printBoth();
}
Output:
call inherited method print:
Base
call method printBoth, showing both data members:
own:Derived; inherited: Base
I have the following test code. Here, the output is "from parent", how can I call the child function? Why is the child function not getting called? is is recommended to inherit from a singleton?
#include <iostream>
using namespace std;
class Singleton
{
public:
static Singleton& getInstance()
{
static Singleton s;
return s;
}
virtual void func()
{
cout << "from parent" << endl;
}
};
class Child : public Singleton
{
public:
void func() override
{
cout << "from child" << endl;
}
};
int main()
{
Singleton& s = Child::getInstance();
s.func();
}
Right now, Singleton::getInstance always returns a Singleton. Child doesn't have its own version of getInstance, so Child::getInstance() resolves to a call to Singleton::getInstance() which returns a Singleton, not a Child. If we use the CRTP, we can make it so Singleton::getInstance actually knows the derived type we're trying to get an instance of:
#include <iostream>
#include <type_traits>
template <class Derived>
class Singleton
{
public:
static Derived& getInstance()
{
// Assert that the template arg really is derived from the appropriate instantiation of the base class template
static_assert(std::is_base_of<Singleton<Derived>, Derived>::value);
static Derived s;
return s;
}
virtual void func()
{
std::cout << "from parent" << std::endl;
}
};
class Child : public Singleton<Child>
{
public:
void func() override
{
std::cout << "from child" << std::endl;
}
};
int main()
{
auto& s = Child::getInstance(); // s is a Child here
s.func(); // Outputs "from child" as expected
}
I want an attribute in a C++ class be an uninstantiated class from a particular class heirachy. All members of this class heirachy would then implement the same method, meaning I could instantiate the object and then use the method when the situation calls for it. Here's some code (that doesn't compile) demonstrating what I mean:
#include <iostream>
using namespace std;
class Event {
public:
Event() = default;
virtual void go() = 0;
};
class EventA : Event {
public:
EventA() = default;
void go(){
cout << "Running event A"<< endl;
}
};
class EventB : Event {
public:
EventB() = default;
void go(){
cout << "Running event B"<< endl;
}
};
class Situation{
private:
Event* current_event = &EventA; //Problematic code: EventA does not refer to a value
public:
Situation() = default;
void setEvent(Event* event){
current_event = event;
}
void runEvent(){
current_event.go();
}
};
int main() {
Situation situation;
situation.runEvent();
situation.setEvent(&EventB);
situation.runEvent();
return 0;
};
No, you cannot form pointers to classes, and you cannot invoke [non-static] member functions without a class instance (object).
You should probably std::make_unique an instance of the type you want to use.
Don't forget to give your base a virtual destructor, since you're doing polymorphism things.
A static alternative would be std::variant.
In two places, you seem to be doing what could be described as trying to take a pointer from a type:
Event* current_event = &EventA;
and
situation.setEvent(&EventB);
This doesn't work and is not really a thing with proper meaning in C++. What you are trying to do could be implemented in 3 different ways I can think of.
Method 1: instead of having a class, you can have a function pointer, and pass the function pointer as parameter:
#include <iostream>
using namespace std;
void eventA_go(){
cout << "Running event A"<< endl;
}
void eventB_go(){
cout << "Running event B"<< endl;
}
class Situation{
private:
using EventFunctionPtr = void (*)();
EventFunctionPtr current_event = &eventA_go;
public:
Situation() = default;
void setEvent(EventFunctionPtr event){
current_event = event;
}
void runEvent(){
current_event();
}
};
int main() {
Situation situation;
situation.runEvent();
situation.setEvent(&eventB_go);
situation.runEvent();
return 0;
};
Method 2: you can make this code a little more generic, by allowing any type of callable in your Situation class, not only function pointers:
#include <iostream>
#include <functional>
using namespace std;
void eventA_go(){
cout << "Running event A"<< endl;
}
void eventB_go(){
cout << "Running event B"<< endl;
}
class Situation{
private:
std::function<void ()> current_event = eventA_go;
public:
Situation() = default;
template <typename F>
void setEvent(F&& event){
current_event = event;
}
void runEvent(){
current_event();
}
};
int main() {
Situation situation;
situation.runEvent();
situation.setEvent(&eventB_go);
situation.runEvent();
return 0;
};
Method 3: you can go back to your original idea of having a base class that must be implemented to provide a go() method, but in this case you will actually have to make sure the objects you are calling do exists. A possible way to do it is with std::unique_ptr:
#include <iostream>
#include <memory>
using namespace std;
class Event {
public:
Event() = default;
virtual ~Event() = default;
virtual void go() = 0;
};
class EventA : public Event {
public:
EventA() = default;
void go(){
cout << "Running event A"<< endl;
}
};
class EventB : public Event {
public:
EventB() = default;
void go(){
cout << "Running event B"<< endl;
}
};
class Situation{
private:
std::unique_ptr<Event> current_event = std::make_unique<EventA>();
public:
Situation() = default;
void setEvent(std::unique_ptr<Event>&& event){
current_event = std::move(event);
}
void runEvent(){
current_event->go();
}
};
int main() {
Situation situation;
situation.runEvent();
situation.setEvent(std::make_unique<EventB>());
situation.runEvent();
return 0;
};
Notice that, in this case, the destructor of the abstract class must be virtual, and the inheritance must be public.
You seem to be confused about classes and variables. Which object would situation.runEvent(); run on? I think you want to publicly derive the classes from Event and initialize current_event when you need to. You don't need to do anything like current_event = &EventB. C++ automagically determines which function is needed to be called based on what current_event is dynamically pointing to. Here's what I think you meant to do:
#include <cassert>
#include <iostream>
class Event {
public:
virtual void go() = 0;
virtual ~Event() = default; // Don't forget the virtual destructor
};
class EventA : public Event {
public:
void go() override { std::cout << "Running event A" << std::endl; }
};
class EventB : public Event {
public:
void go() override { std::cout << "Running event B" << std::endl; }
};
class Situation {
private:
Event* current_event = nullptr;
public:
void setEvent(Event* event) { current_event = event; }
void runEvent() {
assert(current_event);
current_event->go();
}
};
int main() {
Situation situation;
EventA a;
EventB b;
situation.setEvent(&a);
situation.runEvent();
situation.setEvent(&b);
situation.runEvent();
}
If I have a pure virtual function can it be overriden with a function pointer? Scenario below (I'm aware that it's not 100% syntactically correct):
#include<iostream>
using namespace std;
class A {
public:
virtual void foo() = 0;
};
class B : public A {
public:
B() { foo = &B::caseOne; }
void caseOne() { cout << "Hello One" << endl; }
void caseTwo() { cout << "Hello Two" << endl; }
void (B::*foo)();
void chooseOne() { foo = &B::caseOne; }
void chooseTwo() { foo = &B::caseTwo; }
};
int main() {
B b;
b.(*foo)();
}
EDIT: In case anyone's interested, here's how I accomplished what I wanted to do:
#include<iostream>
using namespace std;
class A {
public:
virtual void foo() = 0;
};
class B : public A {
public:
B() { f = &B::caseOne; }
void caseOne() { cout << "Hello One" << endl; }
void caseTwo() { cout << "Hello Two" << endl; }
void (B::*f)();
void chooseOne() { f = &B::caseOne; }
void chooseTwo() { f = &B::caseTwo; }
void foo() { (this->*f)(); }
};
int main() {
B b;
b.foo();
b.chooseTwo();
b.foo();
}
The output is:
Hello One
Hello Two
No. And you use this wrong. In your code you are trying to assign member-function pointer to function-pointer - it's cannot be compiled.
C++03 standard 10.3/2
If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or
indirectly from Base, a member function vf with the same name and same parameter list as Base::vf is
declared, then Derived::vf is also virtual (whether or not it is so declared) and it overrides
Base::vf.
As #ForEveR said, your code cannot compile. However, since what you actually need is the ability of switching B's implementation of foo in the runtime, we do have workaround:
#include <iostream>
using namespace std;
class A {
public:
virtual void foo() = 0;
};
class B : public A {
private:
void (B::*_f)();
public:
B() { chooseOne(); }
void caseOne() {
cout << "case one" << endl;
}
void caseTwo() {
cout << "case two" << endl;
}
void chooseOne() { _f = &B::caseOne; }
void chooseTwo() { _f = &B::caseTwo; }
void foo() {
(this->*_f)();
}
};
int main(int argc, const char *argv[])
{
A* b = new B();
b->foo();
((B*)b)->chooseTwo();
b->foo();
return 0;
}
UPDATE:
Just found the OP added his answer in the question, which is almost the same as mine. But I think calling foo through pointer instead of instance object is better, for that can exhibit the effect of polymorphism. Besides, it's better to hide f as a private member function.
I think when compile time, the syntax can NOT be compiled. You should provide an override function with the certain name and same args list.
I am having a weird problem, which I'm sure has an easy fix. I have a super class let's call it "Bird". Bird has a virtual function called chirp, which returns me 0. I also have a subclass lets call it...SomeOtherBird. SomeOtherBird is a subclass of Bird. The chirp() function for my subclass is supposed to return me 1.
So far:
Bird.Chirp() should return 0
SomeOtherBird.Chirp() should return 1
Some other bird is a subclass of bird.
Now assuming I pass in Bird into a seperate constructor, let's call it nest.
So: nest(Bird& x)
if I pass a SomeOtherBird in, and I call Chirp, it calls the virtual function of the main super-class and not of the subclass, so for example:
SomeOtherBird x;
Nest(x);
and then if I do x.chirp, the main method is called, not the one of the subclass.
How do I get the function in the sub-class to be called, and not the virtual main function?
Thanks
I worked for me.
ideone.com/RRfau
You really ought to include some example code with questions like this so we can help you.
#include <iostream>
#include <typeinfo>
class Bird
{
public:
virtual ~Bird() {}
virtual int chirp() { return 0; }
};
class SomeOtherBird : public Bird
{
public:
virtual int chirp() { return 1; }
};
void nest( Bird& x )
{
std::cout << typeid(x).name() << " says " << x.chirp() << '\n';
}
int main()
{
SomeOtherBird s;
nest( s );
Bird b;
nest( b );
}
Works fine as shown below. Perhaps you might not have made the base method virtual. Or there is something else wrong in the code, since the code was not posted, it is impossible to tell.
#include <iostream>
using namespace std;
class Bird
{
public:
Bird() {}
~Bird() {}
virtual int Chrip() { cout << "Bird version" << endl; return 0; }
};
class SomeOtherBird:public Bird
{
public:
SomeOtherBird() {}
~SomeOtherBird() {}
virtual int Chrip() { cout << "SomeOtherBird version" << endl; return 1; }
};
int nest(Bird &b)
{
b.Chrip();
}
int main()
{
SomeOtherBird s;
Bird &b = s;
int retcode = nest(b);
cout << "retcode " << retcode << endl;
}
Output:
rhdevblade1-~/cpp: ./virt
SomeOtherBird version
retcode 1
Without seeing your code it's impossible to answer you for sure. However, this sounds like you did not write "virtual Bird()" in your base class, only in the derived class. That doesn't work.
class Bird {
virtual int Bird();
};
class MoreBird : public Bird {
int Bird();
};
The virtual keyword is not required in the deriving class (although it is not good practice not to put it there even if 99.9% of the programmers are lazy and don't do it.)