I want to achieve such an outcome using c++:
Java:
public interface ITemp {
void onCall(double value);
}
In main:
double d=2;
ITemp mVariable = new ITemp() {
#Override
public void onCall(double value) {
... what to do... you can use 'd' variable...
}
};
In C++:
class ITemp {
public:
virtual void onCall(double something) =0;
virtual ~ITemp();
};
In main:
double d=2;
ITemp mVariable = .... // I cannot instantiate class containing pure virtual method
// But I want to use variable d to create a method
You can't do exactly that since you can't create anonymous classes in C++, but you can do something similar:
int main()
{
double d = 2;
class T : public ITemp
{
double& m_v;
public:
T(double& v) : m_v(v) {}
void onCall(double value)
{
// Do something with m_v;
m_v *= value;
}
} t(d);
t.onCall(4);
std::cout << "d: " << d << std::endl; // d is 8.
}
The reference ('&') makes m_v the same variable as d, but under a different name.
What about constructing class with d in constructor?
class ITemp {
double m_d;
public:
ITemp(double d) : m_d(d) {}
virtual void onCall(double something) = 0; // inside, you can use m_d variable along with something for whatever you want.
virtual ~ITemp();
};
I think i do not understand what is done in onCall method and how you want to use it. If you want to work with d, pass it to constructor or pass it to onCall as another parameter.
Of course, if that is not what you are trying to do, templates would help you. They are usually used to send different types into class each time however. It seems you do not need that.
You can implement the interface as an unnamed class, but you cannot access local variables and create a closure.
int main(int argc, char* argv[])
{
class : public ITemp
{
public:
virtual void onCall(double something)
{
std::cout << something;
}
} temp;
ITemp& itemp = temp;
itemp.onCall(100.3145);
return 0;
}
Related
In multiple inheritance,where all the base class contains same function name with different functionality, we can access the protected function from particular base class using "::" scope resolution operator.
However, I tried something else. I created the objects of the base class in inside the child class. And tried calling the function using through object of that particular class.
But I was getting the following compiler error:
"‘void A::func(int&)’ is protected within this context."
Please let me know where did i go wrong.
#include <iostream>
using namespace std;
class A
{
protected:
void func(int & a)
{
a = a * 2;
}
};
class B
{
protected:
void func(int & a)
{
a = a * 3;
}
};
class C
{
protected:
void func(int & a)
{
a = a * 5;
}
};
class D : public A,public B,public C {
public:
int a;
A a_val;
B b_val;
C c_val;
void update_val(int new_val)
{
a = new_val;
a_val.func(a);
b_val.func(a);
c_val.func(a);
}
void check(int);
};
void D::check(int new_val)
{
update_val(new_val);
cout << "Value = " << a << endl;
};
int main()
{
D d;
int new_val;
cin >> new_val;
d.check(new_val);
}
If you want to keep your code with the base classes as having independent functionality and still remaining protected the easiest way to resolve your issue is by slightly changing the name of your protected functions and adding a public function that calls the protected members: See these class declarations for example:
class A {
public:
void func( int& a ) {
func_impl( a );
}
protected:
void func_impl( int& a ) {
a = a * 2;
}
};
class B {
public:
void func( int& b ) {
func_impl( b );
}
protected:
void func_impl( int& b ) {
b = b * 3;
}
};
class C {
public:
void func( int& c ) {
func_impl( c );
}
protected:
void func_impl( int& c ) {
c = c * 5;
}
};
class D : public A, public B, public C {
public:
int a;
A a_val;
B b_val;
C c_val;
void update_val( int val ) {
a = val;
a_val.func( a );
b_val.func( a );
c_val.func( a );
}
void check( int );
};
void D::check( int val ) {
update_val( val );
std::cout << "Value = " << a << std::endl;
}
This provides a nice public interface to call the protected member functions. This also resolves the issue of accessing the protected members. When I run your program and input a value of 5 it returns a result of 150 and works as expected.
This snippet should show you how inheritance works and when you can and can not access protected members:
class DerivedA : public Base {
public:
Base b;
void call_message() {
b.message(); // Protected Member of Base class can not be accessed
}
};
class DerivedB : public Base {
public:
void call_message() {
message(); // This works without problem!
}
};
Just as I did above one way to resolve this is by adding a public interface caller to the protected implementation.
class Base {
public:
void message() {
message_impl();
}
protected:
void message_impl() {
std::cout << "This is a protected member of Base\n";
}
};
Now you can do this:
class DerivedA {
public:
Base b;
void call_message() {
b.message(); // Accessible through public interface.
}
};
When you are in your derived class, it has access to its own ancestor methods. But it doesn't have access to your variables member protected and private methods and variables.
Redesign your code, you are trying things and contorting the other classes design for bad reasons. Francis' code is a good solution, but D doesn't need to inherit from anything.
If you don't want to create another function, you can do something like this:
#include <iostream>
using namespace std;
class A
{
protected:
void func(int & a)
{
a = a * 2;
}
};
class B
{
protected:
void func(int & a)
{
a = a * 3;
}
};
class C
{
protected:
void func(int & a)
{
a = a * 5;
}
};
class D : public A,public B,public C {
public:
int a;
void update_val(int new_val)
{
a = new_val;
this->A::func(a);
this->B::func(a);
this->C::func(a);
}
void check(int);
};
void D::check(int new_val)
{
update_val(new_val);
cout << "Value = " << a << endl;
};
int main()
{
D d;
int new_val;
cin >> new_val;
d.check(new_val);
}
This works because, this refers to the current instance of class D, and it already inherits class A, class B, class C. So you can directly access the protected functions of the respective classes.
Remember: It will not work if you have not inherited the classes.
I have two base classes and derivered versions that overload / override certain parts like this:
class base
{
public:
int X = 1;
};
class deriv : public base
{
public:
int X = 2;
};
class A
{
public:
base K;
virtual void doSmth()
{
std::cout << "A" << std::endl;
smthElse();
}
virtual void smthElse()
{
std::cout << K.X << std::endl;
}
};
class B : public A
{
public:
deriv K;
void doSmth()
{
std::cout << "B" << std::endl;
smthElse();
}
};
the application looks like this
int main()
{
A instanceA;
B instanceB;
instanceA.doSmth();
instanceB.doSmth();
getchar();
return 0;
}
And the output therefore is X=1 for both instances A and B. I was wondering why that is.
A uses base (X=1) and B uses deriv (X=2). deriv overloads X and B overloads K. Is this because the function smthElse() is only defined in A, thus A can't know about the existance of the overloaded variable K?
If so, is there a way for the function smthElse() to use the overloaded variable K?
I found the using keyword but also adding a using A::smthElse; in B won't change the behaviour of X not being printed as 2. The only way I can achieve this is by copying the function smthElse() from A and insert it into B.
Is there a different way to achieve what I'm looking for? Since it seems like an overkill to copy'n'paste the same function into B just to use an overridden variable.
Thanks in advance!
instanceB has two variables named K, A::K and B::K. However, the base class, A, only knows about one K, A::K.
That explains the output.
If so, is there a way for the function smthElse() to use the overloaded variable K?
Yes, you can do that by adding a virtual function in A that returns a reference to base and adding a virtual function in base that returns a reference to i.
class base
{
public:
int& getX( return X;}
private:
int X = 1;
};
class deriv : public base
{
public:
int& getX( return X;}
private:
int X = 2;
};
class A
{
public:
base& getK() { return K; }
virtual void doSmth()
{
std::cout << "A" << std::endl;
smthElse();
}
virtual void smthElse()
{
std::cout << getK().getX() << std::endl;
// ^^^^^^^^^^^^^ use the virtual functions
}
public:
base K;
};
class B : public A
{
public:
deriv& getK(){ return K; }
void doSmth()
{
std::cout << "B" << std::endl;
smthElse();
}
public:
base K;
};
PS I hope this is just curiosity and you don't write production code with such style. You will end up confusing yourself and anybody who tries to understand your code.
When you write
virtual void smthElse()
{
std::cout << K.X << std::endl;
}
smthElse is virtual
K is not (a member variable could not be virtual: it has no meaning for an attribute).
In other terms, it means that B::smthElse will ovevrride A::smthElse but B::K and A::K are two distinct, unrelated and independent variables.
When smthElse is called in the context of a B, K still means A::K.
As a solution, you might create a virtual accessor to Ks:
class base { ...};
class deriv{ ...};
class A
{
base K;
public:
virtual const base& theK() { return K; }
virtual void smthElse() { std::cout << theK().X << "\n"; }
};
class B : public A
{
deriv K;
public:
virtual const base& theK() { return K; }
};
When B{}.smthElse() is called, it will call B::theK() which will return B::K (a deriv instance).
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();
}
Sorry for the convoluted title of my question, conceptually it is quite simple but I can't find any good design to do it.
I have a base class accessible by the end user :
class A {
private:
// m is a functor
Base* m;
};
class Base {
public:
virtual void someInterface();
};
class DerivedT1 : public Base {
public:
virtual void someInterface()
{
some_parameter++;
}
private:
int some_parameter; // how to set?
};
class DerivedT2 : public Base {
public:
virtual void someInterface()
{
some_other_parameter += a_third_parameter;
}
private:
double some_other_parameter; // how to set?
double a_third_parameter; // how to set?
};
And I am trying to find the most generic way to set some_parameter and some_other_parameter from A's public interface.
I have thought of giving a number to my parameters but this sounds really ugly.
Is there any beautiful, object-oriented way to do this ?
you want to use A's public interface to set derived class parameters:
you can define a public function In A, which have a Base* parameter:
class A
{
public:
void setter(const Base *p);
{
m = p;
}
};
if you want to set Drived1 you can define a object of Derived1, can pass it to setter;
I think you want to pass value using A's public function, you must know the type of pointer of Base*,so you can pass value by the constructor of Derived1 or Derived2!
I nothing else works, you could always use a dynamic cast:
DerivedT1 *d1 = dynamic_cast<DerivedT1>(m);
if (d1 != nullptr)
{
// do something with derived 1
}
else
{
DerivedT2 *d2 = dynamic_cast<DerivedT2>(m);
if (d2 != nullptr)
{
// do something with derived 2
}
}
But if you need that, it's usually a sign that there is something wrong with your design.
If you want to do something along these lines
A a; a.setAlgorithmFamily(Algorithm::Type1);
a.getAlgorithmImplementation().setSomeParameter(34);
This is a quick and kind of dirty example of how you could do it. A::setAlgorithmType is basically a factory pattern in it's simplest form.
nclude <iostream>
using namespace std;
class Algorithm {
public:
virtual void setParameter(int value) = 0;
};
class AlgoX : public Algorithm {
int mX;
public:
void setParameter(int value) {
cout <<"Setting X to " <<value <<endl;
mX = value;
}
};
class AlgoY : public Algorithm {
int mY;
public:
void setParameter(int value) {
cout <<"Setting Y to " <<value <<endl;
mY = value;
}
};
class A {
public:
void setAlgorithmType(std::string type) {
cout <<"Now using algorithm " <<type <<endl;
if(type == "X")
mAlgorithm = new AlgoX();
else if(type == "Y")
mAlgorithm = new AlgoY();
}
Algorithm* getAlgorithmImplementation() { return mAlgorithm; }
private:
Algorithm* mAlgorithm;
};
int main(int argc, char** argv) {
A a;
a.setAlgorithmType("X");
a.getAlgorithmImplementation()->setParameter(5);
return 0;
}
This gives:
Now using algorithm X
Setting X to 5
I am trying to do something like this with c++.
void showContensofArray(void *data[])
{
//In this function have to display the values of respective objects.
// Any ideas how do I do it?
}
int main(){
A phew(xxx,abcdefg); //object of class A
B ball(90),ball2(88); //object of class B
void *dataArray[2];
dataArray[0] = &ph1;
dataArray[1] = &ball;
showContentsofArray(dataArray); //function
}
If you want to treat the objects in the data[] generically (i.e by calling a common function on them to extract a description or values) then define a class hirachy for your objects and in your showContentsofArray function call virtual methods on your (common base class) object pointers.
This is a textbook example of Polymorphism:
"polymorphism allows values of different data types to be handled using a uniform interface."
In the example below the base class BaseObject defines the uniform interface.
class BaseObject {
virtual string description() { return "Base object"; }
virtual bool bounces() { return false; }
}
class B : public BaseObject {
string description() { return "Im a B object" }
bool bounces() { return true; }
}
class A : public BaseObject {
string description() { return "Im an A object" }
}
void showContensofArray(BaseObject* data[], int size) {
for (int i=0; i<size; i++) {
cout << data[i]->description();
if (data[i]->bounces())
cout << "I bounce!";
}
}
int main() {
A phew(xxx,abcdefg); //object of class A
B ball(90),ball2(88); //object of class B
BaseObject* dataArray[2];
dataArray[0] = &ph1;
dataArray[1] = &ball;
showContentsofArray(dataArray);
}
Will output:
Im an A object
Im a B object
I bounce!
void showContensofArray(void *data[], int len)
{
int i;
for(i=0;i<len;i++){
((Base*)(data[i]))->print();
}
}
And every Class should have an implementation of the method print() that knows how to print its values.
You could also use inheritance.
EDIT:
#Ricibob's answer is correct, but if you need to do the casting inside the function, you need to do something like this:
#include <iostream>
using namespace std;
class Base{
public:
virtual void print()=0;
};
class A: public Base{
public:
void print(){
cout<<"Object A"<<endl;
}
};
class B: public Base{
public:
void print(){
cout<<"Object B"<<endl;
}
};
void showContensofArray(void* data[], int len)
{
int i;
for(i=0;i<len;i++){
((Base*)(data[i]))->print();
}
}
int main(){
A a;
B b;
void* v[2];
v[0]= &a;
v[1] = &b;
showContensofArray(v,2);
return 0;
}
You can't evade inheritance.
Just cast back to the original type:
A* p1 = static_cast<A*>(data[0]);
B* p2 = static_cast<B*>(data[1]);