friend member of a class operating on private members c++ - c++

I am learning about friends in classes and my problem is:
I want funcC3() to set and permanently change C1::a value, how to do it?
I want global function gfunc() to be able to do the same, how?
Could you please provide me the way i do it, because in the book they don't specify?
#include <iostream>
using namespace std;
class C2;
class C3
{
public:
void funcC3(int const& x)
{
cout << "in third class...: " << x << endl;
};
};
class C1
{
private:
int a;
public:
void funcC1()
{
cout << "inside C1 private thingie: " << a << endl;
};
int C1::getcha();
friend class C2;
friend int gfunc(int chair);
friend void C3::funcC3(int const& a);
};
int C1::getcha()
{
return a;
};
class C2
{
public:
int a;
};
**int gfunc(int ch)**
{
int chair = ch;
return chair;
};
**int main()**
{
C1 obj1;
C3 obj3;
obj3.funcC3(10);
obj1.funcC1();
gfunc(12);
cout << C1.geta() << endl;
system("pause");
}

I want funcC3() to set and permanently change C1::a value, how to do
it?
Declare it as friend function in C1:
class C1; //forward declaration
class C3
{
//...
void funcC3( C1& c);
};
class C1
{
//...
private:
int a;
friend void C3::funcC3( C1&);
};
void C3::funcC3( C1& c) { c.a = 100;}
I want global function gfunc() to be able to do the same, how?
Same as above:
class C1;
void gfunc( C1& c);
class C1 {
//...
private:
int a;
friend void gfunc( C1& c);
};
void gfunc( C1& c) { c.a = 100;}

Related

Wrong context when calling method

How can I achieve that CoroutineManager::Routine() calls Operator::Worker() ?
Worker() must be called by Routine() in this test scenario.
So the question is whether how C++ handle the context. The Routine() method must not implemented by the Operator class itself.
template <class T>
class CoroutineManager {
private:
T var;
int _a, _b;
public:
CoroutineManager(int a, int b);
T Worker();
void Routine();
};
template <class T>
CoroutineManager<T>::CoroutineManager(int a, int b) {
this->_a = a;
this->_b = b;
}
template <class T>
T CoroutineManager<T>::Worker() {
std::cout << "wrong method" << std::endl;
return var;
}
template <class T>
void CoroutineManager<T>::Routine() {
std::cout << this->Worker() << std::endl;
}
class Operator : public CoroutineManager<double> {
using CoroutineManager::CoroutineManager;
public:
Operator(int a, int b) : CoroutineManager(a,b) {};
virtual double Worker();
};
double Operator::Worker() {
return 3.141;
}
// MARK: -
int main(int argc, const char * argv[]) {
Operator *op = new Operator(3,4);
op->Routine();
return 0;
}
I've changed the code to fulfill my requirements, but maybe there are exists more straight forward solutions(?). It's only about Worker and Worker2, two different methods in two objects which can be called by the derived Routine method without the boundaries of inheritance context:
// MARK: -
template <typename T, typename V>
class CoroutineManager {
private:
V _a, _b;
V (T::*workerPtr)();
T *cm;
public:
CoroutineManager(V a, V b) {
this->_a = a;
this->_b = b;
}
void Routine() {
std::cout << (*cm.*workerPtr)() << std::endl;
}
void SetWorker(T *cm, V (T::*ptr)()) {
this->workerPtr = ptr;
this->cm = cm;
}
V getA() {
return this->_a;
}
V getB() {
return this->_b;
}
};
// MARK: -
class Operator : public CoroutineManager<Operator,int> {
private:
int xx;
public:
Operator(int a, int b) : CoroutineManager(a,b) {
this->xx = a*2 + b*2;
};
int Worker();
};
int Operator::Worker() {
return getA() * getB() + this->xx;
}
// MARK: -
class Operator2 : public CoroutineManager<Operator2,double> {
public:
Operator2(double a, double b) : CoroutineManager(a,b) {};
double Worker2();
};
double Operator2::Worker2() {
return getA() + getB();
}
// MARK: -
int main(int argc, const char * argv[]) {
Operator *op = new Operator(4,4);
int (Operator::*workerPtr)() = &Operator::Worker;
op->SetWorker(op, workerPtr);
op->Routine();
Operator2 *op2 = new Operator2(3.14,2.78);
double (Operator2::*workerPtr2)() = &Operator2::Worker2;
op2->SetWorker(op2, workerPtr2);
op2->Routine();
return 0;
}
Output:
32
5.92
Program ended with exit code: 0

2 way friendship and between classes and it's solution as forward declaration

I wanted to know if there's any exsisting solution to the problem:
class b;
class a {
int x;
public:
friend class b;
a() { x = 5 }
void print(b obj) {
cout << x << endl;
cout << obj.y << endl;
}
};
class b {
int y;
public:
friend class a;
b() { y = 10 }
void print(a obj) {
cout << y << endl;
cout << obj.x << endl;
}
};
"This is giving me an issue since class b body is not define before class a, so what is there any easy and existing way to make it work?
For starters you forgot to place a semicolon after these statements
x = 5
and
y = 10
You can define member functions that access data members of other class when the other class is defined that is when it is a complete type.
So place the definition of the function print of the class a after the definition of the class b.
For example
#include <iostream>
using namespace std;
class b;
class a {
int x;
public:
friend class b;
a() { x = 5; }
/* inline */ void print(b obj);
};
class b {
int y;
public:
friend class a;
b() { y = 10; }
void print(a obj) {
cout << y << endl;
cout << obj.x << endl;
}
};
void a::print(b obj) {
cout << x << endl;
cout << obj.y << endl;
}
int main()
{
a a;
a.print( b() );
b b;
b.print( ::a() );
return 0;
}
The program output is
5
10
10
5
You could place the class definitions with member function declarations in a header and then define the member functions in a cpp file.

Can i use C++ function pointers like a C#'s Action?

In C ++, I first encountered function pointers.
I tried to use this to make it similar to Action and Delegate in C #.
However, when declaring a function pointer, it is necessary to specify the type of the class in which the function exists.
ex) void (A :: * F) ();
Can I use a function pointer that can store a member function of any class?
In general, function pointers are used as shown in the code below.
class A {
public:
void AF() { cout << "A::F" << endl; }
};
class B {
public:
void(A::*BF)();
};
int main()
{
A a;
B b;
b.BF = &A::AF;
(a.*b.BF)();
return 0;
}
I want to use it like the code below.
is this possible?
Or is there something else to replace the function pointer?
class A {
public:
void AF() { cout << "A::F" << endl; }
};
class B {
public:
void(* BF)();
};
int main()
{
A a;
B b;
b.BF = a.AF;
return 0;
}
I solved the question through the answer.
Thanks!
#include <functional>
#include <iostream>
class A {
public:
void AF() { std::cout << "A::F" << std::endl; }
};
class C {
public:
void CF() { std::cout << "C::F" << std::endl; }
};
class B {
public:
B(){}
std::function<void()> BF;
};
int main() {
A a;
C c;
B b;
b.BF = std::bind(&A::AF, &a);
b.BF();
b.BF = std::bind(&C::CF, &c);
b.BF();
int i;
std::cin >> i;
return 0;
}
What you want to do is probably something like this. You can use std::function to hold a pointer to a member function bound to a specific instance.
#include <functional>
#include <iostream>
class A {
public:
void AF() { std::cout << "A::F" << std::endl; }
};
class B {
public:
B(const std::function<void()>& bf) : BF(bf) {}
std::function<void()> BF;
};
int main() {
A a;
B b1(std::bind(&A::AF, &a)); // using std::bind
B b2([&a] { a.AF(); }); // using a lambda
b1.BF();
b2.BF();
return 0;
}
Here's a C# style implementation of the accepted answer, It is memory efficient and flexible as you can construct and delegate at different points of execution which a C# developer might expect to do:
#include <iostream>
#include <functional>
using namespace std;
class A {
public:
void AF() { cout << "A::F" << endl; }
void BF() { cout << "B::F" << endl; }
};
class B {
public:
std::function<void()> Delegate;
};
int main() {
A a;
B b;
b.Delegate = std::bind(&A::AF, &a);
b.Delegate();
b.Delegate = [&a] { a.BF(); };
b.Delegate();
return 0;
}

C++ operator overloading in abstract class

Let's say we have the following scenario:
We have a base abstract class A. Then we have classes B and C which derived from A. We also have class D which is a custom implementation of a std::vector<T> - it contains a private property list of type std::vector<T> and some custom methods to work with it.
Now my problem is as follows: I would like to overload the operator + in class A to be able to do this:
B* b = new B();
C* c = new C();
D mList = b+c; //the property *list* of mList would contain b an c
I have tried everything and can't seem to be able to get it to work and am out of ideas. Is it even possible to override an operator in a base abstract class so that it will apply to derived classes?
EDIT:
Here is what I have tried so far:
File A.h:
#pragma once
#include <string>
#include <iostream>
using namespace std;
class A
{
protected:
double price;
string name;
public:
A() :name(""){};
A(string n, double p){
price = p;
name = n;
};
~A(){};
virtual void calculate(double value) = 0;
virtual void print() const = 0;
};
File B.h:
#pragma once
#include "A.h"
class B : public A
{
private:
public:
B() :A(){};
B(string n, double p) :A(n,p){};
~B();
void calculate(double value)
{
price = price + value;
}
void print() const
{
cout << name << " says: " << " " << price;
}
};
File C.h:
#include "A.h"
class C : public A
{
private:
public:
C() :A(){};
C(string n, double p) : A(n,p){};
~C();
void calculate(double value)
{
price = price * value;
}
void print() const
{
cout << name << " says: " << " " << price;
}
};
File D.H:
#include <vector>
class D
{
private:
vector<A*> list;
public:
D(){}
~D()
{
int len = list.size();
for (int i = 0; i < len; i++)
{
delete list[i];
}
};
void push(A* item)
{
list.push_back(item);
}
A* pop()
{
A* last = list.back();
list.pop_back();
return last;
}
//I have tried overriding it here and in A.h
friend D D::operator+(A* first, A* second)
{
D temp;
temp.push(first);
temp.push(second);
return temp;
}
};
It looks like you're are adding two pointers, so A::operator+() won't even be called. But to answer your question, yes, operator overloading is inheritable. Even from an abstract base class.
class A
{
public:
virtual void test() = 0;
int operator+(const A &a) {return 42;}
};
class B : public A
{
void test() {};
};
class C : public A
{
void test() {};
};
int main()
{
B* b = new B();
C* c = new C();
cout << "result: " << *b + *c << endl;
return 0;
}
Output:
result: 42
When c in C* and d is a D* if you write c+d you're just adding pointers, whatever overloads you defined.
Maybe you could redefine pointer addition for A* with a global operator(A*, A*) (not sure it's possible) but it would be quite dangerous for users since it overrides standard behavior.
The better solution is to define operators on references (const) and not pointers, which in your case is a little less convenient since you'd have to write: list = *c + *d;
Also, since you're using containers of pointers for polymorphism, I strongly recommend using shared_ptr.
Working code below (simplified, but with the ability to add more than 2 elements):
#include <list>
using std::list;
struct A {
list<const A*> operator+(const A& right) { // A + A
list<const A*> r;
r.push_back(this);
r.push_back(&right);
return r;
}
list<const A*> operator+(const list<const A*> & right) { // A + list
list<const A*> r = right;
r.push_front(this);
return r;
}
virtual void print() const = 0;
};
list<const A*> operator+(const list<const A*> & left, const A & right) { // list + A
list<const A*> r = left;
r.push_back(&right);
return r;
}
#include <iostream>
struct B : A {
void print() const { std::cout << "B" << std::endl; }
};
struct C : A {
void print() const { std::cout << "C" << std::endl; }
};
int main() {
B b;
C c;
B* pb = new B;
list<const A*> lst = b + c + *pb;
for(list<const A*>::iterator i = lst.begin(); i != lst.end(); ++i) {
(*i)->print();
}
return 0;
}
Take a look at this code-example:
#include <iostream>
class B;
class A;
class A
{
public:
virtual void overrideProp() = 0;
friend int operator+(const B& b, const A& a);
friend std::ostream& operator<<(std::ostream& os, const A& a)
{
return os << a.prop;
}
protected:
int prop;
};
class B : public A
{
public:
B(){overrideProp();}
void overrideProp(){prop=1;}
};
class C : public A
{
public:
C(){overrideProp();}
void overrideProp(){prop=3;}
};
int operator+(const B& b, const A& a)
{
return b.prop + a.prop;
}
class D
{
public:
void operator=(const int& i){d = i;}
friend std::ostream& operator<<(std::ostream& os, const D& a)
{
return os << a.d;
}
private:
int d;
};
int main()
{
B b;
C c;
D d; d = b+c;
std::cout << "B contains: " << b << " C contains: " << c << " D contains: " << d;
}
The output is B contains: 1 C contains: 3 D contains: 4
Here's an compilable and runnable example (http://codepad.org/cQU2VHMp) I wrote before you clarified the question, maybe it helps. The idea is that the addition overload can either be unary (and D defined as a friend), as here, or defined as a non-member binary operator using public methods. Note that I have to dereference the pointers b and c to make this work, as adding pointers often don't make sense.
#include <iostream>
#include <string>
class D {
public:
void Foo() {
std::cout << "D: " << member_ << std::endl;
}
friend class A;
private:
std::string member_;
};
class A {
public:
virtual void Foo() = 0;
A(const std::string &member) : member_(member) {}
D operator+(const A &rhs) {
D out;
out.member_ = member_ + " " + rhs.member_;
return out; // Uses the default copy constructor of D
}
protected:
std::string member_;
};
class B : public A {
public:
B(const std::string &member) : A(member) {}
void Foo() {
std::cout << "B: " << member_ << std::endl;
}
};
class C : public A {
public:
C(const std::string &member) : A(member) {}
void Foo() {
std::cout << "C: " << member_ << std::endl;
}
};
int main() {
B *b = new B("hello");
C *c = new C("world");
b->Foo();
c->Foo();
D d = (*b) + (*c);
d.Foo();
delete b;
delete c;
return 0;
}
The output of this program is:
B: hello
C: world
D: hello world

Friend Function calling Static Members of Derived Classes. Not getting expected output

My first post here :)
I am having a problem with the following C++ code. I have an ABC class A, and two derived classes B and C. All of them have a static member called id:
using std::cout;
class A
{
private:
friend int bar(A& a);
static const int id = 1;
virtual void foo() = 0;
};
class B : public A
{
private :
friend int bar(A& a);
static const int id = 2;
void foo() { /*Do something*/ }
};
class C : public A
{
private:
friend int bar(A& a);
static const int id = 3;
void foo() { /*Do something*/ }
};
int bar(A& a)
{
return a.id;
}
int main()
{
B b;
C c;
cout << bar(b) << "\n";
cout << bar(c) << "\n";
return 0;
}
I was expecting this code to print out 2 and 3 - rather it prints out 1 and 1 (bar() is always using A::id). What am I doing wrong? Any ideas?
Based on the comments below, this the final code I am using. It works, but would love to hear more thoughts :)
#include <iostream>
using std::cout;
class A
{
private:
virtual void foo() = 0;
};
class B : public A
{
private:
template <typename T>
friend int bar(T& t);
static const int id = 2;
void foo() { /*do something*/ }
};
class C : public A
{
private:
template <typename T>
friend int bar(T& t);
static const int id = 3;
void foo() { /*do something*/ }
};
template <typename T>
int bar(T& t)
{
return t.id;
}
int main()
{
B b;
C c;
cout << bar(b) << "\n";
cout << bar(c) << "\n";
return 0;
}
a.id will be defined at compile-time as A::id. You would need to define a virtual member (non-static) function in class A and have it overridden in B and C to return their respective ids and call this function in bar.
Is there any way to avoid writing int foo() { return id; } for all the derived classes?
Yes, using templates. For example:
template <typename T>
int foo (T& x)
{
return x.id;
}
However, if id is private, this doesn't reduce the code by all that much.