I'm working on a small project, and I found myself in a situation like this :
class A{}
class B : class A {
public:
void f();
int getType() const;
private:
int type;
}
class C : class A{
public:
int getType() const;
private:
int type;
}
I want to know if there's a way to call the f() function (in class B) from an object of type A?
I tried this but it says function f() cannot be found in class A :
int main(){
vector<A*> v;
// v initialized with values of A ...
if (v->getType() == 1){ // 1 is the type of B
v->f();
}
}
As you've seen, this code won't compile because A doesn't have an f method. In order to make it work, you'd have to explicitly downcast the pointer:
B* tmp = dynamic_cast<B*>(v);
tmp->f();
To begin with, with your current classes, you can't call getType() on an A*. Because the interface of A doesn't have this method. To solve this problem, you either need to make getType a virtual function in A, or move the type field to base class A (as protected) and initialize it in the constructors of the child classes. Let me show you the first method, because I think it is a better approach, since it makes the objective of this function more clear.
class A {
public:
virtual int getType() { return 0; } // or delete the function: ... getType() = 0;
}
class B : public A {
public:
int getType() override { return 1; }
}
With these classes, once you create an instance of B, getType() returns 1 when called on that instance, whether it is pointed to by an A* or B*:
A *object = new B();
object->getType(); // returns 1
Now, if you need to access the f() from B, you can again add it as a virtual method to A's interface, or make a cast to B*.
Using a virtual method:
class A {
public:
virtual void f() { /* a default action maybe? */ }
}
class B : public A {
public:
void f() /* override if you want */ { /* whatever this function does in B */ }
}
...
for (A *ptr : v)
ptr->f();
Using a cast:
class A {
public:
virtual int getType() { return 0; }
}
class B : public A {
public:
void f();
int getType() override { return 1; }
}
...
for (A *ptr : v)
if (ptr->getType() == 1)
dynamic_cast<B*>(ptr)->f();
Related
class Builder
{
public:
virtual void Build(int a) = 0;
};
class ConcreteBuilder1 : public Builder
{
public:
void Build(int a);
};
class ConcreteBuilder2 : public Builder
{
public:
void Build(int a. struct A* a);
};
So My question is how to design Build() method to take both parameters(int, struct* A). But with same builder interface ?
So that,
int x;
struct A* y;
Builder concrteBuilder1 = new ConcreteBuilder1();
concrteBuilder1 ->Build() // // Here I am forced to pass struct A* a eventhough not needed for concerte builder1 . And I am also forced to forced to change Builder interface too.
My apologies if I did not convey the question clearly.
Builder usually builds an object of another class. You may try something similar to this:
class ToBuild
{
//some code here
};
class Builder
{
public:
virtual ToBuild * build() = 0;
};
class ConcreteBuilder : public Builder
{
int _valA;
int _valB;
public:
ToBuild * build() override
{
ToBuild * obj = new ToBuild();
//initalize obj using _valA and _valB variables;
return obj;
}
ConcreteBuilder& valA(const int val)
{
_valA = val;
return *this;
}
ConcreteBuilder& valB(const int val)
{
_valB = val;
return *this;
}
};
int main()
{
ConcreteBuilder b;
ToBuild * obj = b.valA(1).valB(2).build();
//some code
delete obj;
return 0;
}
[edit]
You can write another derived class with as many parameters as you want and still use a single 'build' method.
Add
using Builder::Build;
to the derived class's declarations. This will import this symbol into the derived class, and make both it, and the derived class methods, of the same name, available to overload resolution. I.e.
using Builder::Build;
void Build(int a);
I'm ignoring the fact that you can't construct the derived class anyway, since it fails to implement this pure virtual function from the base class.
Derived class override their functions from the one which has same parameters and same return value.
So if you declare a function like...
class Builder
{
public:
virtual void Build() = 0;
};
class ConcreteBuilder1 : public Builder
{
public:
void Build(int a);
};
class ConcreteBuilder2 : public Builder
{
public:
void Build(int a. struct A* a);
};
Here, Build function in ConcreteBuilder1 class treated as a new function, not override function.
So try this.
class Builder
{
public:
virtual void Build(int a, A* b = 0) = 0;
};
class ConcreteBuilder1 : public Builder
{
public:
void Build(int a);
};
class ConcreteBuilder2 : public Builder
{
public:
void Build(int a, struct A* a);
};
I wish it's helpful for you.
This question already has answers here:
Force all classes to implement / override a 'pure virtual' method in multi-level inheritance hierarchy
(5 answers)
Closed 5 years ago.
Consider this:
struct Base {
virtual void fn() = 0;
};
struct A: Base {
virtual void fn();
};
struct B: A {
// fn is not overridden here
};
Basically, fn is implemented in A. B derives from A, and B doesn't override fn.
I'd like to have technique to make B must override fn, because it is an error, if it is not overridden.
Is is possible to do this? A compile-time error (or maybe warning) would be the best, but if it is not possible, then a runtime error is OK too. I'd just like to know, if someone forgets to override fn in a derived class.
The reason for this? fn could return class-related information. For example, it could return the class name. Or it could return the amount of allocated space the object uses (for debug purposes). Or do some class-related task (for example, loading/saving its state).
You cannot force the compiler to generate an error if fn is not overridden in B.
You can modify your code a little bit to get what you want.
Make A::fn a pure-virtual. Leave the implementation as is in A. Remember that it's perfectly OK to implement A::fn even when it is declared pure-virtual.
That will force you to override fn in B. The implementation of B::fn can utilize as much of A::fn as it needs to.
truct Base {
virtual void fn() = 0;
};
struct A : Base {
virtual void fn() = 0;
};
void A::fn()
{
// Add implmentation details
}
struct B : A {
// fn must be overridden here
virtual void fn();
};
void B::fn()
{
A::fn();
// Add additonal logic for B
}
You can generate run time error though if A::fn is called an on B object.
Here's one way to do it.
#include <iostream>
struct Base
{
virtual void fn() = 0;
virtual int getTypeID() = 0;
protected:
static int getNextID()
{
static int nextid = 0;
return ++nextid;
}
static int getClassTypeID()
{
static int id = getNextID();
return id;
}
};
struct A : Base
{
virtual void fn();
virtual int getTypeID()
{
return getClassTypeID();
}
private:
static int getClassTypeID()
{
static int id = getNextID();
return id;
}
};
void A::fn()
{
if ( this->getTypeID() != A::getClassTypeID() )
{
// Problem.
std::cout << "ERROR. fn() called on a derived class object.\n";
}
else
{
std::cout << "OK. fn() called on an A object.\n";
}
}
struct B : A
{
virtual int getTypeID()
{
return getClassTypeID();
}
static int getClassTypeID()
{
static int id = getNextID();
return id;
}
};
int main()
{
A* a1Ptr = new A;
A* a2Ptr = new B;
a1Ptr->fn();
a2Ptr->fn();
}
Output:
OK. fn() called on an A object.
ERROR. fn() called on a derived class object.
I am very new to c++ so I am trying to get a feeling of how to do things the right way in c++. I am having a class that uses one of two members. which one gets determined at instantiation. It looks something like
main() {
shared_pointer<A> a = make_shared<A>();
if ( checkSomething ) {
a->setB(make_shared<B>());
} else {
a->setC(make_shared<C>());
}
a->doStuff();
class A {
public:
doStuff() {
/*here I want to do something like call
m_b->doStuff() if this pointer is set and m_c->doStuff() if
that pointer is set.*/
}
setB( B* p ) { m_b = p; }
setC( C* p ) { m_c = p; }
B* m_b;
C* m_c;
}
}
B and C are some classes with doStuff() member function
There are many members like doStuff. Ideally I would avoid checking for nullptr in each of them. What is the best/most efficient/fastest way to create a switch between those two members?
Is there a way to use a static pointer so that I have a member
static **int m_switch;
and do something like
m_switch = condition ? &m_b : &m_c;
and call
*m_switch->doStuff();
Does the compiler here also replace the extra pointer hop because it is a static?
Is there any other smart way to do those switches?
Normally, class A would be an interface class, which both B and C would inherit and implement. But it sounds like you cannot do this for whatever reason.
Since you want to emulate this, you can start by making the interface:
class A_interface
{
public:
virtual void doStuff() = 0;
virtual void doThings() = 0;
virtual void doBeDoBeDo() = 0;
};
And then you make a template wrapper:
template< class T >
class A : public A_interface
{
public:
void doStuff() override { target.doStuff(); }
void doThings() override { target.doThings(); }
void doBeDoBeDo() override { target.doBeDoBeDo(); }
private:
T target;
};
This essentially does half of what your own example class A was trying to do, but now you can use a common interface. All you need to do is construct the correct templated version you want:
std::shared_ptr<A_interface> a;
if( checkSomething ) {
a = std::make_shared<A<B>>();
} else {
a = std::make_shared<A<C>>();
}
a->doStuff();
You need to have both members implement a common interface to use them similarly. But in order to do that, you need to define the interface and relay the calls to the B and C classes.
// existing classes
class B
{
public:
void doStuff() { std::cout << "B"; }
};
class C
{
public:
void doStuff() { std::cout << "C"; }
};
// define your interface
class I
{
public:
virtual void doStuff() = 0;
};
// new classes
class D : public B, public I
{
public:
void doStuff() override { B::doStuff(); }
};
class E : public C, public I
{
public:
void doStuff() override { C::doStuff(); }
};
// your A class
class A
{
public:
D* b = nullptr; // now type D
E* c = nullptr; // now type E
// your toggle
I* getActive()
{
if (b)
return b;
else
return c;
}
// simple doStuff() function
void doStuff()
{
getActive()->doStuff();
}
};
int main()
{
A a;
if (true)
a.b = new D; // need to initialize as D
else
a.c = new E; // need to initialize as E
a.doStuff(); // prints B
}
But typing this up made me realize that defining D and E could get really tiresome and against what you're trying to save. However, you can define a template to create them like #paddy has done.
There's no one-size-fits-all solution for your problem. What to use depends on your particular problem. A few possible answers:
Interfaces
Strategy Pattern
Pointers (to hold a function or class which implements doStuff)
An interface is like a contract. Any class which inherits from the interface must implement its members. For instance,
class IDoesStuff
{
public:
virtual ~IDoesStuff() {};
virtual void DoStuff() = 0;
};
Can now be used by other classes:
class Foo : public IDoesStuff
{
public:
virtual void DoStuff()
{
// ....
}
};
class Bar : public IDoesStuff
{
public:
virtual void DoStuff()
{
// ....
}
};
And now, in general, one may do:
Foo foo;
IDoesStuff *stuffDoer= &foo;
stuffDoer->doStuff();
This can be used in your particular use case as follows:
class A
{
IDoesStuff *stuffDoer; // Initialize this at some point.
public:
void doStuff() { stuffDoer->doStuff(); }
};
First you must change your memebr variables m_b and m_c to std::shared_ptr.
Add a member variable of type std::function(void()) to hold the target function you want to call. In your sample it is do_stuf.
In your setter functions you can bind target function to your std::function and in do_stuf just call std::function.
(You need a C++11 compiler)
class B
{
public:
void doStuff()
{
}
};
class C
{
public:
void doStuff()
{
}
};
class A
{
public:
void doStuff()
{
m_target_function();
}
void setB(std::shared_ptr<B> p)
{
m_b = p;
m_target_function = std::bind(&B::doStuff, m_b.get());
}
void setC(std::shared_ptr<C> p)
{
m_c = p;
m_target_function = std::bind(&C::doStuff, m_c.get());
}
std::shared_ptr<B> m_b;
std::shared_ptr<C> m_c;
std::function<void()> m_target_function;
};
int _tmain(int argc, _TCHAR* argv[])
{
std::shared_ptr<A> a = std::make_shared<A>();
bool use_B = false;
if (use_B)
{
a->setB(std::make_shared<B>());
}
else
{
a->setC(std::make_shared<C>());
}
a->doStuff();
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
it is possible to change return type when override a virtual function in C++?
I am getting error:
error: conflicting return type specified for Ă¢virtual bool D::Show()
7: error: overriding Ă¢virtual void A::Show()"
When i compile my code. The code is :
class A
{
public:
virtual void Show()
{
std::cout<<"\n Class A Show\n";
}
};
class B : public A
{
public:
void Show(int i)
{
std::cout<<"\n Class B Show\n";
}
};
class C
{
public:
virtual bool Show()=0;
};
class D :public C, public B
{
public:
bool Show(){
std::cout<<"\n child Show\n";
return true;}
};
int main()
{
D d;
d.Show();
return 0;
}
I want to use Show() function from class C. Where is my error?
Your compiler is complaining because the two functions don't have the same return types: one of them returns a void and the other one returns a bool. Your two functions should have the same return type.
You should have
class A {
public:
virtual bool Show() {
std::cout<<"\n Class A Show\n";
return true; // You then ignore this return value
}
};
class B : public A {
public:
bool Show(int i) {
std::cout<<"\n Class B Show\n";
return true; // You then ignore this return value
}
};
If you can't change classes A and B, you can change classes C and D to have a void Show() method instead of a bool Show() method.
If you can't do any of these things, you can use composition over inheritance: have a member of type B inside your D function instead of inheriting from it:
class D : public C {
public:
bool Show() {
std::cout<<"\n child Show\n";
return true;
}
void ShowB() {
b.Show();
}
private:
B b;
};
You need to add a middle man.
Something like:
class C1 : public C{
public:
virtual bool show(){ /* magic goes here */ }
};
class D: public C1, public B{
....
To call Show, you will need something like:
static_cast<C&>(c).Show();
I am designing a framework in c++ which is supposed to provide basic functionality and act as interface for the other derived systems.
#include <stdio.h>
class Module
{
public:
virtual void print()
{
printf("Inside print of Module\n");
}
};
class ModuleAlpha : public Module
{
public:
void print()
{
printf("Inside print of ModuleAlpha\n");
}
void module_alpha_function() /* local function of this class */
{
printf("Inside module_alpha_function\n");
}
};
class System
{
public:
virtual void create_module(){}
protected:
class Module * module_obj;
};
class SystemAlpha: public System
{
public:
void create_module()
{
module_obj = new ModuleAlpha();
module_obj->print(); // virtual function, so its fine.
/* to call module_alpha_function, dynamic_cast is required,
* Is this a good practice or there is some better way to design such a system */
ModuleAlpha * module_alpha_obj = dynamic_cast<ModuleAlpha*>(module_obj);
module_alpha_obj->module_alpha_function();
}
};
main()
{
System * system_obj = new SystemAlpha();
system_obj->create_module();
}
Edited the code to be more logical and it compiles straight away. The question is, that is there a better way to design such a system, or dynamic_cast is the only solution. Also, if there are more derived modules, then for type-casting, there is some intelligence required in the base Module class.
If Derived is the only concrete instance of Base you could use static_cast instead.
Personally, I define a function, like MyCast for every specialized class. I define four overloaded variants, so that I can down-cast const and non-const pointers and references. For example:
inline Derived * MyCast(Base * x) { return static_cast<Derived *> (x); }
inline Derived const * MyCast(Base const * x) { return static_cast<Derived const *>(x); }
inline Derived & MyCast(Base & x) { return static_cast<Derived &> (x); }
inline Derived const & MyCast(Base const & x) { return static_cast<Derived const &>(x); }
And likewise for Derived2 and Base2.
The big advantage in having all four is that you will not change constness by accident, and you can use the same construct regardless if you have a pointer or a reference.
Of course, you could replace static_cast with a macro, and use dynamic_cast in debug mode and static_cast is release mode.
Also, the code above can easily be wrapped into a macro, making it easy to batch-define the functions.
Using this pattern, you could then implement your code as:
class Derived : public Base
{
public:
virtual void func2()
{
base2_obj = new Derived2();
}
void DerivedFunc()
{
MyCast(base2_obj)->Derived2Func();
}
}
The design gets much cleaner if Base does not contain the base_obj object, but rather gets a reference via a virtual method. Derived should contain a Derived2 object, like:
class Base
{
public:
virtual void func1();
private:
class Base2;
virtual Base2& get_base2();
};
class Derived : public Base
{
Derived2 derived2;
public:
Base2& get_base2() { return derived2; }
void DerivedFunc()
{
derived2->Derived2Func();
}
}
If you are worried about performance, pass the reference in the constructor of Base.
I took your code with its many compile errors and tried to simplify it. Is this what you are trying to acheive? It will compile.
class Base2 {
public:
virtual void Derived2Func(){
}
};
Base2* fnToInstantiateABase2();
class Base {
public:
Base() : base2_obj(fnToInstantiateABase2()) {
}
virtual void DerivedFunc() {
}
protected:
Base2* base2_obj;
};
class Derived : public Base {
public:
void DerivedFunc() {
base2_obj->Derived2Func(); // not possible as base2_obj is of type Base2
}
};
class Derived2 : public Base2 {
public:
void Derived2Func() {
}
};
void test() {
Base * base_obj = new Derived();
base_obj->DerivedFunc();
}
Base2* fnToInstantiateABase2() {
return new Derived2();
}