I am not able to use a friend function properly - c++

I am writing a code to declare a member function of a class as a friend, but I am getting errors.
The code is
#include<iostream>
class Vect;
class Coordinate {
float x;
float y;
public:
Coordinate(float a,float b):x(a),y(b){}// constructor
Coordinate():x(0),y(0){};//constructor
display()
{
std::cout<<"\nx:"<<x<<" "<<"y:"<<y;
}
friend Vect::add(Coordinate B);
};
class Vect {
public:
add(Coordinate A)
{
std::cout<<A.x;
}
};
The exact errors are
invalid use of incomplete type 'class Vect'| and forward declaration
of 'class Vect'|

class Y; //forward declaration of class Y
class X
{
public:
int getmark(Y);
};
class Y
{
int mark;
public:
Y() {}
friend int X::getmark(Y);
};
int X::getmark(Y obj) {
cin >> obj.mark;
return obj.mark;
}
int main()
{
X a;
Y b;
a.getmark(b);
}
At first, when the object a (class X) is created, a forward declaration of class Y is necessary in order to declare the Y argument to X::getmark().
Creating object b (class Y) wont be a problem as the compiler knows class X exists (for the friend function).
Then, simply call the function getmark() through the object a.
Note: It is necessary to declare the function getmark() after the declaration of class Y, or else compiler will consider the class Y as an incomplete type.

you can use this :
class Vect;
class Coordinate
{
public:
Coordinate(float a = 0f, float b = 0f) :x(a), y(b) {}// constructor
float x;
float y;
void display()
{
std::cout << "\nx:" << x << " " << "y:" << y;
}
friend int add(Coordinate B);
};
class Vect
{
friend int add(Coordinate B);
public:
};
int add(Coordinate B)
{
std::cout << B.x << std::endl;
return B.x;
}

Related

How to initialize a class object?

I have these 2 specific classes:
class foo{
private:
int a;
int b;
public:
foo(int x, int y)
:a(x), b(y)
{
cout << "I just created a foo! << endl;
}
~foo()
{
cout << "A foo was just destroyed!" << endl;
}
void set_a(int a_num)
{
a = a_num;
}
void set_b(int b_num)
{
b = b_num;
}
class bar{
private:
int T;
int S;
foo f;
public:
bar(int x, int y, foo n=(0,0) <--
:T(x), S(y), f(n)
{
cout << "I just created a f!" << endl;
foo.set_a(T); <--
foo.set_b(S); <--
}
~bar(){
cout << "A bar was destroyed!" << endl;
}
When a bar is created, i want the given values T and S to be assigned immediately to the foo object-member.At the marked lines i tried to overwrite these values but none of these seems to work and i get the error: "default argument for parameter of type foo has type 'int'".How can i get this to work?
You can use:
bar(int x, int y, foo n=foo(0,0)) : ... { ... }
If you are able to use a C++11 compiler, you can also use:
bar(int x, int y, foo n=foo{0,0}) : ... { ... }
and
bar(int x, int y, foo n={0,0}) : ... { ... }
Instead of:
foo.set_a(T);
foo.set_b(S);
you need to use:
f.set_a(T);
f.set_b(S);
since you need to call set_a and set_b on the member variable f.
A better alternative is to initialize f using:
bar(int x, int y} : T(x), S(y), f(x, y) {}
and leave the body of the constructor empty.

How do I set multiple class members in one statement in C++?

Is it possible to set multiple different class members in one statement? Just an example of how this would be done:
class Animal
{
public:
int x;
int y;
int z;
};
void main()
{
Animal anml;
anml = { x = 5, y = 10, z = 15 };
}
To "convert" Barry's comment into an answer, yes, under the conditions here:
An aggregate is an array or a class (clause 9) with no user-declared
constructors (12.1), no private or protected non-static data members
(clause 11), no base classes (clause 10), and no virtual functions
(10.3).
Example:
class Animal
{
public:
int x;
int y;
int z;
};
int main() {
Animal anml;
anml = { 5, 10, 15 };
return 0;
}
(This Community Wiki answer was added in accordance with this meta post.)
You can always overload constructors or create methods that "set multiple different object properties in one statement":
class Animal {
public:
Animal() {
};
Animal(int a, int b, int c) {
x = a;
y = b;
z = c;
}
void setMembers(int a, int b, int c) {
x = a;
y = b;
z = c;
}
private:
int x;
int y;
int z;
};
int main() {
// set x, y, z in one statement
Animal a(1, 2, 3);
// set x, y, z in one statement
a.setMembers(4, 5, 6);
return 0;
}
Solution 1 for Animal (http://ideone.com/N3RXXx)
#include <iostream>
class Animal
{
public:
int x;
int y;
int z;
Animal & setx(int v) { x = v; return *this;}
Animal & sety(int v) { y = v; return *this;}
Animal & setz(int v) { z = v; return *this;}
};
int main() {
Animal anml;
anml.setx(5).sety(6).setz(7);
std::cout << anml.x << ", " << anml.y << ", " << anml.z << std::endl;
return 0;
}
Solution 2 for any class with x, y (https://ideone.com/xIYqZY)
#include <iostream>
class Animal
{
public:
int x;
int y;
int z;
};
template<class T, class R> T& setx(T & obj, R x) { obj.x = x; return obj;}
template<class T, class R> T& sety(T & obj, R y) { obj.y = y; return obj;}
int main() {
Animal anml;
sety(setx(anml, 5), 6);
std::cout << anml.x << ", " << anml.y << std::endl;
return 0;
}

'B::operator A' uses undefined class 'A'

I have found the following example in one of my C++ courses. When I try to compile it I get the following error:
'B::operator A' uses undefined class 'A'
Why does it say that class A is undefined?
#include<iostream>
using namespace std;
class A;
class B
{
int x;
public: B(int i = 107) { x = i; }
operator A();
};
B::operator A() { return x; }
class A
{
int x;
public: A(int i = 6) { x = i; }
int get_x() { return x; }
};
int main()
{
B b;
A a = b;
cout << a.get_x();
system("Pause");
}
The compiler needs to know what A is here:
B::operator A() { return x; }
But you only have a forward declaration. You need to move the declaration of class A above B
You are only allowed to use pointers to or references of incomplete types which is what have when you forward declare a type
You need to declare A above B, so that the definition of A is visible to B.
#include<iostream>
using namespace std;
class A
{
int x;
public: A(int i = 6) { x = i; }
int get_x() { return x; }
};
class B
{
int x;
public: B(int i = 107) { x = i; }
operator A();
};
B::operator A() { return x; }
int main()
{
B b;
A a = b;
cout << a.get_x();
}
This should work.

Declaring readonly variables on a C++ class or struct

I'm coming to C++ from C# and const-correctness is still new to me. In C# I could declare a property like this:
class Type
{
public readonly int x;
public Type(int y)
{
x = y;
}
}
This would ensure that x was only set during initialization. I would like to do something similar in C++. The best I can come up with though is:
class Type
{
private:
int _x;
public:
Type(int y) { _x = y; }
int get_x() { return _x; }
};
Is there a better way to do this? Even better: Can I do this with a struct? The type I have in mind is really just a collection of data, with no logic, so a struct would be better if I could guarantee that its values are set only during initialization.
There is a const modifier:
class Type
{
private:
const int _x;
int j;
public:
Type(int y):_x(y) { j = 5; }
int get_x() { return _x; }
// disable changing the object through assignment
Type& operator=(const Type&) = delete;
};
Note that you need to initialize constant in the constructor initialization list. Other variables you can also initialize in the constructor body.
About your second question, yes, you can do something like this:
struct Type
{
const int x;
const int y;
Type(int vx, int vy): x(vx), y(vy){}
// disable changing the object through assignment
Type& operator=(const Type&) = delete;
};
Rather than a collection of constants, you could have a constant collection. The property of being constant seems to pertain to your use case, not the data model itself. Like so:
struct extent { int width; int height; };
const extent e { 20, 30 };
It's possible to have specifically constant data members of a class, but then you need to write a constructor to initialize it:
struct Foo
{
const int x;
int & y;
int z;
Foo(int a, int & b) : x(a + b), y(b), z(b - a) { }
};
(The example also shows another type of data member that needs to be initialized: references.)
Of course, structs and classes are the same thing.
You can initialize class const members with constructor. If you need add some other logic in constructor, but in .cpp file not in .h, you can create a private method and call it in constructor.
File.h
class Example
{
private:
const int constantMember1;
const int constantMember2;
const int constantMember3;
void Init();
public:
Example(int a, int b) :constantMember1(a), constantMember2(b), constantMember3(a + b) {
//Initialization
Init();
};
};
File.cpp
void Init()
{
//Some Logic intialization
}
This is not exactly answering the question asked, but if you wanted to have the simplicity of directly accessing member variables in a struct without getters, but wanted to ensure that nobody could modify the values, you could do something like this:
#include <iostream>
using namespace std;
class TypeFriend;
struct Type
{
const int &x;
const int y;
Type (int vx, int vy):x (_x), y (vy), _x (vx)
{
}
private:
friend class TypeFriend;
int _x;
};
struct TypeFriend
{
TypeFriend (Type & t):_t (t)
{
}
void setX (int newX)
{
_t._x = newX;
}
private:
Type & _t;
};
int main ()
{
Type t (1, 2);
TypeFriend tf (t);
cout << t.x << "," << t.y << endl;
// t.x = 6; // error: assignment of read-only location ‘t.Type::x’
// cout<<t.x << ","<<t.y<<endl;
tf.setX (5);
cout << t.x << "," << t.y << endl;
return 0;
}
The result of running this is:
1,2
5,2
Type::x cannot be modified externally, so it is read-only, but via TypeFriend it can be changed. This can be useful if you wanted to expose a simple interface of direct member access for reading, but wanted to restrict how those members could be changed.

Constructor call in composition

I have the following code for composition. It generates an error,
#include <iostream>
using namespace std;
class X
{
private:
int iX;
public:
X(int i=0) : iX(i) { cout <<"Constructing X.."<<endl; }
~X() { cout <<"Destructing X.."<<endl; }
int getIX() { return iX; }
};
class Y
{
private:
X x(3);
int jY;
public:
Y(int j = 0) : jY(j) { cout <<"Constructing Y.."<<endl; }
~Y() { cout <<"Destructing Y.."<<endl; }
void callGetX() { cout <<"iX is "<<(x.getIX())<<endl; }
};
int main()
{
Y yObj(1);
yObj.callGetX();
}
Error:
In member Function void Y::callGetX()
'x' undeclared (first use this function)
Is there anything that i have missed?
Can anyone please tell me the constructor call mechanism for this scenario?
X x(3);
This is not legal in C++ (legal in Java AFAIK). In fact it makes the compiler think that x is a member function that returns an object of class X instead of considering x a member variable of class X.
Instead do this:
Y(int j = 0) : jY(j), x(3) { cout <<"Constructing Y.."<<endl; }
You put the member in your initialization list:
Y(int j = 0) : x(3), jY(j)
Your syntax:
class Y
{
private:
X x(3);
//...
};
is illegal.