Can i call VFunc from outside of the object? - c++

I like the results of this code but i was curious, is it possible to call B::VFunc() from main()? I know writing B::VFunc(); inside of C will call it but is it possible to call the function from outside of the object?
http://ideone.com/Dg8aa
#include <cstdio>
class I { public: virtual void VFunc()=0; };
class B : public I { public: void VFunc() { printf("B\n"); } };
class C : public B { public: void VFunc() { printf("C\n"); } };
int main(){
C v;
B&i = v;
i.VFunc();
}
output:
C

This will do it:
#include <cstdio>
class I { public: virtual void VFunc()=0; };
class B : public I { public: void VFunc() { printf("B\n"); } };
class C : public B { public: void VFunc() { printf("C\n"); } };
int main(){
C v;
B&i = v;
i.B::VFunc();
}
Example: http://ideone.com/MfyYJ

You can resort to slicing:
C v;
B i = (B)v;
http://ideone.com/YVI2T
The dynamic type of v is lost, so B::VFunc is called.

Related

How do I call an overridden method that was declared after the class calling it?

Say I have this code:
class A
{
public:
A(){};
void some_func(){
std::cout << 1;
};
};
class B
{
A* my_A;
public:
B(A* a) : my_A{a} {};
void use_A()
{
my_A->some_func();
}
};
class C : public A
{
public:
C(){};
void some_func()
{
std::cout << 2;
}
};
int main()
{
C new_c;
B new_b(&new_c);
new_b.use_A();
}
Now this compiles just fine, however use_A() is calling the original some_func(), not the override declared after. How can I do that? I expect the program to print 2, not 1.
You need to declare A::some_func() as virtual in order for C to override it, eg:
class A
{
public:
A(){};
virtual void some_func(){ // <--
std::cout << 1;
};
};
class B
{
A* my_A;
public:
B(A* a) : my_A{a} {};
void use_A()
{
my_A->some_func();
}
};
class C : public A
{
public:
C(){};
void some_func() override // <--
{
std::cout << 2;
}
};
int main()
{
C new_c;
B new_b(&new_c);
new_b.use_A(); // prints 2, not 1
}
Online Demo

Overriding protected field members in C++ not working?

In the following, I expected class Child's protected field member _AorB to be of type B, and not A, but reality shows otherwise.
What am I mis-understanding, and how can I adjust the code for the desired behavior?
class A{
public:
void doit(){
std::cout<<" this is A!"<<std::endl;
}
};
class B{
public:
void doit(){
std::cout<<" this is B!"<<std::endl;
}
};
class Parent{
public:
void doit(){
_AorB.doit();
}
protected:
A _AorB;
};
class Child: public virtual Parent{
protected:
B _AorB;
};
int main()
{
cout<<"Hello World";
auto c = Child();
c.doit(); // I expected this to print "This is B" because c is Child(), and Child class's _AorB is of type B.
return 0;
}
You can make such changes:
template <typename AorB>
class Parent{
public:
void doit(){
_AorB.doit();
}
protected:
AorB _AorB;
};
class Child: public virtual Parent<B> {
}
Also take a look at What are the rules about using an underscore in a C++ identifier?
Reserved in any scope, including for use as implementation macros:
identifiers beginning with an underscore followed immediately by an uppercase letter
273K's answer is excellent.
Depending on what kind of problem you are trying to solve and how the data is held in the hierarchy, you could use a std::variant<A, B> to allow "flippy" behavior based on the type, and access that member variable through a virtual getter member function.
#include <iostream>
#include <variant>
class A {
public:
void doit() {
std::cout << " this is A!\n";
}
};
class B {
public:
void doit() {
std::cout << " this is B!\n";
}
};
class Parent {
public:
virtual ~Parent() = default;
void doit() {
auto ab = get_AorB();
std::visit([](auto arg) { arg.doit(); }, ab);
}
virtual auto get_AorB() -> std::variant<A, B> {
return _a;
}
protected:
A _a;
};
class Child : public virtual Parent {
protected:
B _b;
auto get_AorB() -> std::variant<A, B> override {
return _b;
}
};
int main() {
std::cout << "Hello World";
auto c = Child();
c.doit(); // "this is B!"
}

List of multiple class to run same function name C++ [duplicate]

This question already has answers here:
How to store object of different class types into one container in modern c++?
(2 answers)
Closed 3 years ago.
I have multiple classes with same function as below
class A
{
void display()
{
// display something
}
};
class B
{
void display()
{
// display something two
}
};
I want to store difference class at a list or a vector and loop to call the same function with same name
int main()
{
A * a;
B * b;
//list or vector to store object
std::vector < Something that can store different class > listofclass;
listofclass.emplace_back(a);
listofclass.emplace_back(b);
for (int i = 0; i < listofclass.size(); i++)
{
listofclass[i].display();
}
}
Is that possible to do like this?
Because there is separate classes, having different purpose, and now i try to group them together
Or there is other alternative way to achieve something like this
If you control the definition of A and B, you can write a common base class, and have them inherit it.
class can_display {
public:
virtual void display() = 0;
virtual ~can_display() = default;
};
class A : public can_display
{
void display() override
{
// display something
}
};
class B : public can_display
{
void display() override
{
// display something two
}
};
int main()
{
A a;
B b;
std::vector<can_display *> displayables;
displayables.push_back(&a);
displayables.push_back(&b);
for (can_display * displayable : displayables)
{
displayable->display();
}
}
As an alternative to changing the definition of A and B to inherit from a common base, you can have a wrapper that inherits.
template <typename T>
class can_display_impl {
T * wrapped;
public:
can_display_impl(T * wrapped) : wrapped(wrapped) {}
void display() override { wrapped->display(); }
}
template <typename T>
std::unique_ptr<can_display> make_can_display(T & wrapped) {
return std::make_unique<can_display_impl<T>>(&wrapped);
}
int main()
{
A a;
B b;
std::vector<std::unique_ptr<can_display>> displayables;
displayables.emplace_back(make_can_display(a));
displayables.emplace_back(make_can_display(b));
for (auto & displayable : displayables)
{
displayable->display();
}
}
You have two solutions for this problem:
Use inheritance and just make a abstract class that will be a interface for your classes. In class A and class B just inherit from that interface and in std::vector hold pointer to base class.
#include <vector>
#include <iostream>
#include <memory>
class Interface_display {
public:
virtual void display() = 0;
virtual ~Interface_display(){};
};
class A : public Interface_display
{
public:
void display() override
{
std::cout << "Display from A\n";
}
~A() override = default;
};
class B : public Interface_display
{
public:
void display() override
{
std::cout << "Display from B\n";
}
~B() override = default;
};
int main(void)
{
std::vector<std::unique_ptr<Interface_display>> v;
v.emplace_back(std::make_unique<A>());
v.emplace_back(std::make_unique<B>());
for (const auto &element: v) {
element->display();
}
}
And if you are using c++17, you could use std::variant and wrap objects of your class to std::variant:
#include <vector>
#include <iostream>
#include <variant>
class A
{
public:
void display()
{
std::cout << "Display from A\n";
}
};
class B
{
public:
void display()
{
std::cout << "Display from B\n";
}
};
int main(void)
{
using variant_t = std::variant<A, B>;
std::vector<variant_t> v;
v.emplace_back(A());
v.emplace_back(B());
for (auto &element: v) {
std::visit([](auto &x) { x.display(); }, element);
}
}
https://wandbox.org/permlink/8VBmziWzafbPZk99
A way to solve this problem is by using polymorphism. You make a superclass, which contains a pure virtual version of this function and let both A and B inherit from this class. By doing this, you can dynamic_cast any pointer of type A or B to a superclass type, on which you have defined the display function.
This will get you something like this
class C {
public:
virtual void display() = 0;
virtual ~C() = default;
};
class A : public C {
public:
void display() override {
std::cout << "A" << std::endl;
};
~A() override = default;
};
class B : public C {
public:
void display(){
std::cout << "B" << std::endl;
};
~B() override = default;
};
So you can do:
C* c = new A();
// You can put the types of C* in the same list, and iterate over this list and do on each element
c->display();
delete c;

Overridden function applied to base class list

i just want to know if there is any way to do something like this:
Class A {}; //Base class
Class B : A {}; //B inherits from A
Class C : A {}; //C inherits from A
...
...
...
void func(B){do x;}
void func(C){do y;}
...
...
...
list<A> l //l contains Bs or Cs.
for each element in l {func(element);}
And get the expected behaviour for each one?
You can do something like the following:
class A // Base clss
{
public: // or protected, depends on your needs
virtual void func() {};
};
class B : public A //B inherits from A
{
public: // or protected, depends on your needs
void func() { do x };
};
class C : public A //C inherits from A
{
public: // or protected, depends on your needs
void func() { do y };
};
...
...
...
list<A*> l //l contains Bs or Cs.
for each element in l { element->func(); }
In this way you use polymorphism instead of overloading the static function func.
#include <iostream>
#include <vector>
class A
{
public:
virtual void func() {}
};
class B : public A
{
public:
void func()
{
std::cout << "B prints x" << std::endl;
}
};
class C : public A
{
public:
void func()
{
std::cout << "C prints y" << std::endl;
}
};
int main()
{
std::vector<A*> v;
v.push_back(new B());
v.push_back(new C());
for (std::vector<A*>::iterator it = v.begin(); it != v.end(); ++it){
(*it)->func();
}
return 0;
}
Output:
B prints x
C prints y
You can use polymorphism. For example
#include <iostream>
#include <memory>
#include <list>
#include <algorithm>
class A
{
public:
virtual ~A() {}
virtual void do_it() = 0;
};
class B : public A
{
public:
virtual void do_it() { std::cout << "processing of B\n"; };
};
class C : public A
{
public:
virtual void do_it() { std::cout << "processing of C\n"; };
};
void f( std::unique_ptr<A> &pa ) { pa->do_it(); }
int main()
{
std::list<std::unique_ptr<A>> l;
l.push_back( std::unique_ptr<A>( new B ) );
l.push_back( std::unique_ptr<A>( new C ) );
std::for_each( l.begin(), l.end(), f );
}

Forcing a compiler to state whether method has been implemented - C++

if I have the following code:
class A
{
public:
virtual void Yo();
}
class B : public A
{
public:
virtual void Yo() override;
}
Is there a way to force B to implement method Yo in A? Like an interface or more specifically (in this case) an abstract?
My full code is here:
BaseObject.h
#pragma once
namespace Game
{
namespace Model
{
namespace Graphic
{
class BaseObject
{
public:
int Width;
int Height;
float X;
float Y;
float Z;
virtual void SetUp() = 0;
virtual void Reset() = 0;
};
}
}
}
Player.cpp
#include "pch.h"
#include "Abstract\BaseObject.h"
using namespace Game::Model::Graphic;
class Player : public BaseObject
{
public:
Player();
~Player();
//virtual void SetUp();
//virtual void Reset() override;
};
in A make Yo pure virtual
virtual void Yo() = 0;
a complete example
#include <iostream>
struct A
{
virtual void Yo() = 0;
};
struct B : A
{
virtual void Yo() { std::cout << "I'm B\n"; }
};
int main()
{
B b;
b.Yo();
return (0);
}
if B doesn't implement Yo this will not compile.
The override keyword it's not needed in this case.
You have to take pointer of the base class to implement virtual functions in C++. This seems quite obvious. But i think we have missed that. The most basic example is given below.
#include <iostream>
using namespace std;
class base {
public:
virtual void vfunc() {
cout << "This is base's vfunc().\n";
}
};
class derived1 : public base {
public:
void vfunc() {
cout << "This is derived1's vfunc().\n";
}
};
int main()
{
base *p, b;
derived1 d1;
// point to base
p = &b;
p->vfunc(); // access base's vfunc()
// point to derived1
p = &d1;
p->vfunc(); // access derived1's vfunc()
return 0;
}