C++ friend function not working - c++

I am new to C++ and have been trying to get my head around classes in c++. Recently I tried out this program and instead of returning an integer 9, it returns some garbage value. Can someone please help me out
#include <iostream>
#include <cstring>
#include <math.h>
using namespace std;
class abc;
class xyz
{
int a;
public:
friend int add(xyz, abc);
friend void setval(xyz, int, abc, int);
};
class abc
{
int b;
public:
friend int add(xyz, abc);
friend void setval(xyz, int, abc, int);
};
int add(xyz V1, abc V2)
{ return (V1.a + V2.b);}
void setval(xyz v1, int v11, abc v2, int v22)
{v1.a = v11; v2.b = v22; }
int main()
{
xyz A;
abc B;
setval(A, 4, B, 5);
cout<<add(A, B)<<endl;
return(0);
}

This is happening because you are passing the arguments to setval function by value which will modify the copy of the object that you have passed.
Use the following signature instead:
void setval(xyz& v1, int v11, abc& v2, int v22);
This way you will be sending the reference to your objects instead of copies of those objects made in some separate blobs of memory. Thus, the objects created in your main function will be assigned the values.

friend void setval(xyz, int, abc, int);
Your set functions sets value to an copy of the passed object not the passed object. You need to pass by reference.
friend void setval(xyz &, int, abc &, int);
^^^^^^ ^^^^^^
I may as well suggest starting with a good book:
The Definitive C++ Book Guide and List

Related

Variable is not a type

#include<iostream>
#include<string>
#include<vector>
using namespace std;
class Course
{
public:
string name;
string instructorInCharge;
int numberOfStudents;
int totalMarks;
Course(string u, string v, int p, int q){
this->name=u;
this->instructorInCharge=v;
this->numberOfStudents=p;
this->totalMarks=q;
}
vector<int> studentMarks (numberOfStudents);
};
class Labs:public Course
{
vector<int>labMarks(numberOfStudents);
};
int main()
{
Course c("Rahul","Hota",200,300);
cout<<"hello there";
}
When I compile this code I’m getting the following error:
1.cpp:20:31: error: 'numberOfStudents' is not a type
20 | vector<int> studentMarks (numberOfStudents);
| ^~~~~~~~~~~~~~~~
1.cpp:28:29: error: 'numberOfStudents' is not a type
28 | vector<int>labMarks(numberOfStudents);
| ^~~~~~~~~~~~~~~~
Please tell me what my mistake is.
numberostudents was supposed to be the size of the vector. But not any function.
vector<int> studentMarks (numberOfStudents);
This is a function declaration. The return type is vector<int>, the name is studentMarks and it accepts a single parameter of type numberOfStudents. Except, as the error points out, numberOfStudents is not a type.
You cannot use parentheses to specify a default member initialiser. You have to either use curly braces:
T member {value};
or "equals" initialiser:
T member = value;
Note however, that you don't initialise numberOfStudents member, but rather assign it later in the constructor body. This assignment is after studentMarks has been initialised, and thus the default member initialiser of studentMarks won't reflect the size that was assigned. Rather, the behaviour of the program would be undefined due to the use of an indeterminate value. This can be fixed by initialising numberOfStudents in the member initialiser list.
If you want in-class initialization, you may do this:
vector<int> studentMarks = vector<int>(numberOfStudents);
Now the default constructor will initialize studentMarks with vector<int>(numberOfStudents) when an instance of Course is created.
However, this will cause undefined behavior since numberOfStudents is not initialized before the initialization of studentMarks. You could use the member initalizer list instead:
Course(std::string u, std::string v, int p, int q)
: name(std::move(u)),
instructorInCharge(std::move(v)),
numberOfStudents(p),
totalMarks(q),
studentMarks(numberOfStudents)
{
}
and likewise for the Labs class:
class Labs : public Course {
public:
Labs(std::string u, std::string v, int p, int q)
: Course(u, v, p, q), // initialize the base class part of a `Labs`
labMarks(p) // initialize the added member variable
{
}
std::vector<int> labMarks;
};
You can also use resize method of std::vector.
#include<iostream>
#include<string>
#include<vector>
using namespace std;
class Course
{
public:
string name;
string instructorInCharge;
int numberOfStudents;
int totalMarks;
vector<int> studentMarks;
Course(string u, string v, int p, int q){
this->name = u;
this->instructorInCharge = v;
this->numberOfStudents = p;
this->totalMarks = q;
this->studentMarks.resize(numberOfStudents);
}
};
class Labs : public Course
{
vector<int> labMarks;
public:
Labs(string u, string v, int p, int q) : Course(u, v, p, q)
{
labMarks.resize(p);
}
};
int main()
{
Course c("Rahul","Hota",200,300);
cout<<"hello there";
}

How to pass value from C++ class constructor as a default argment of method of this class?

I want to build some program in C++, but I'm quite newbie in OOP and I meet a problem that Google can't help me for right now. I think that the C++ is in version 14, but I'm still not sure how to check this in VS2017. I want to use thevalues passed to the class' constructor as default values for another method of the same class.
Specially for my problem I build simple case program for adding two int's, which is in three separate files and it looks like this:
main.cpp
#include <iostream>
#include "add_this.h"
using namespace std;
int main(int argc, char** argv)
{
Add plus(1, 2);
cout << plus.AddingResult(IF EMPTY, TAKE VALS 1 AND 2 FROM ABOVE plus) << endl;
return 0;
}
add_this.cpp
#include "add_this.h"
Add::Add(int a, int b)
{
}
Add::~Add()
{
}
int Add::AddingResult(int a, int b)
{
return a + b;
}
add_this.h
#pragma once
class Add
{
private:
int a;
int b;
public:
Add(int a, int b);
~Add();
int AddingResult(int a, int b);
};
Ok, if in main.cpp I pass values by hand in example plus.AddingResult(2, 3) I will get 5. My problem is that I want to get method, which will take b or a and b values (or in super method version will take b by hand and pass a from constructor). I try a lot of approaches related with pointers or defining Set and Get methods but all fails in my implementation - I don't say that they are wrong I say that my implementations was wrong. I wont attache them for question clarity.
First, let's give your identifiers better names:
class Adder
{
int lhs_;
int rhs_;
public:
Adder(int lhs, int rhs);
~Adder();
Then we define an overload set for the member function add as we cannot define arguments with non-static member variable as their default value:
int add(int lhs, int rhs);
int add(int lhs);
int add();
};
Then, we need to "save" the values given to Adder's constructor:
Adder::Adder(int lhs, int rhs)
: lhs_(lhs), rhs_(rhs) // 1
{}
The line marked // 1 is the syntax for the member-initializer-list; it initializes the member variables lhs_ and rhs_ with the argument's values. Last step, we use those variables in our overload set:
int Adder::add(int lhs, int rhs)
{
return lhs + rhs;
}
int Adder::add(int lhs)
{
return add(lhs, rhs_);
}
int Adder::add()
{
return add(lhs_, rhs_);
}
Full demo: https://coliru.stacked-crooked.com/a/e08b8860c20d53c9

Char passing in C++ with pointers

Im having unclear image of pointers and char passing with functions. please anyone can tell me where im doing wrong and brief idea about pointers?ex : where should i use them, etc...
#include <iostream>
using namespace std;
class book{
private:
char *CName;
int CFee;
int NoPeople;
int Income;
public:
void setData(char &x,int y,int z){
CName = &x;
CFee = y;
NoPeople = z;
}
void calIncome(){
Income = CFee * NoPeople;
}
void viewIncome(){
cout<<Income;
cout<<CName;
}
};
int main(){
book b1;
b1.setData('DISE',20000,30);
b1.calIncome();
b1.viewIncome();
}
im getting error in this code
//b1.setData('DISE',20000,30); "non-const lvalue reference to type 'char' cannot bind to a temparory of type 'int'"
In your code there is no need for pointers. You should use std::string:
#include <string>
...
string CName
...
void setData(const string& x,int y,int z){
CName = x;
and in setData call you should use double quotes (which are for strings) instead of single quotes (which are for individual characters).
You should change setData() declaration to void setData(const char *x,int y,int z)
As you're currently doing you are expecting a reference to a single char as parameter, which cannot be used to assign a char* pointer that is meant to point at a character array.
Also you aren't specifying a character array literal in the call:
b1.setData('DISE',20000,30);
Needs to be changed to
b1.setData("DISE",20000,30);
// ^ ^
b1.setData('DISE',20000,30);
char is only one char, like 'D', if you have multiple char, that is string, and you need to pass it as "DISE"
With your method signature, void setData(char &x,int y,int z) you can only pass char. That is one character.
setData metod is completely useless here. Its work should be done by a constructor, and the name variable (which should NOT be named CName should be an std::string. viewIncome should automatically call calIncome and a dirty flag should probably be introduced. Otherwise calIncome should be a free/static function and the income member should be removed. The function parameters should also be reasonably captioned.
And I'll even answer the question:
class Book {
std::string name;
int fee;
int noPeople;
int income;
public:
Book(std::string name, int fee, int noPeople) :
name(std::move(name)),
fee(fee),
noPeople(noPeople)
{
}
void calIncome() {
income = fee * noPeople;
}
void viewIncome() {
calIncome();
std:: cout << income << name;
}
};
int main() {
Book b1 ("DISE", 20000, 30);
b1.viewIncome();
}
See it live on Coliru.

Passing compare function for a generic class

I want to create a priority queue for which I am using a heap(using array).The priority queue will be generic thus accept all data types as long as the client pass a compare function through constructor to compare the two types.
How can I create a constructor that will accept the compare function as a parameter? Moreover how can I make the compare function to be called when I check
return (Type a==Type b)
Eg.
struct node{
string val1;
string val2;
vector<node *> connectedNodes;
};
int compareNode(node a,node b){
//describe the compare
}
int main(){
PQueue<node> q(compareNode);
}
The PQueue class is implemented as an array. As the adding,bubbling-up, heapifying needs to compare two ValType I want them to compare using compareNode.
You don't have to do this: don't use an array, use the built-in priority-queue of the STL library in c++. It has its own compare function which you can alter.
Reference: http://www.cplusplus.com/reference/queue/priority_queue/
You can also see topcoder tutorials (for algorithmic usage).
Let me first give you a simple answer and then a more versatile one.
You can simply pass a function as parameter by declaring the type of that parameter to be the type of pointer function. You can also have variables of type pointer to function. For instance, if the declaration of your function is
int compareNode(node a, node b)
then you could do something like this:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
struct node{
string val1;
string val2;
vector<node *> connectedNodes;
};
int compareNode(node a,node b){
//describe the compare
return a.val2.compare(b.val2); // or any other code
}
template <class T>
class PQueue {
protected:
// this declares a protected member named compareFunction of type pointer to a function which takes 2 T parameters and returns a int. Note that all the parenthesis are mandatory
int (*compareFunction)(T, T);
public:
PQueue (int (*compareFunctionParameter)(T, T)) : compareFunction(compareFunctionParameter) {
// this constructor receives a pointer to function and initializes it's member to that pointer. If the constructor initialization list confuses you, you can read 'compareFunction = compareFunctionParameter '
}
int someMethod() {
// call the function through the pointer you have:
node n1, n2;
n1.val1 = "node1_val1";
n1.val2 = "zzz";
n2.val1 = "node2_val1";
n2.val2 = "aaa";
return compareFunction(n1, n2);
}
};
int main() {
PQueue<node> pq(compareNode);
cout << pq.someMethod() << endl;
return 0;
}
http://ideone.com/EPjbya
Hope this you can use this.
Now to the more versatile example.
C++11 introduces lambdas. http://www.cprogramming.com/c++11/c++11-lambda-closures.html http://www.stroustrup.com/C++11FAQ.html#lambda
#include <iostream>
#include <vector>
#include <string>
#include <functional>
using namespace std;
struct node{
string val1;
string val2;
vector<node *> connectedNodes;
};
int compareNode(node a,node b){
//describe the compare
return a.val2.compare(b.val2); // or any other code
}
template <class T, class Comparator>
class PQueue {
protected:
Comparator compareFunction;
public:
PQueue (Comparator compareFunctionParameter) : compareFunction(compareFunctionParameter) {
}
int someMethod() {
// call the function
node n1, n2;
n1.val1 = "node1_val1";
n1.val2 = "zzz";
n2.val1 = "node2_val1";
n2.val2 = "aaa";
return compareFunction(n1, n2);
}
};
int main() {
// queue with pointer to function
PQueue<node, int (*)(node, node)> pq(compareNode);
cout << pq.someMethod() << endl;
// queue with lamda (anonimous function)
PQueue<node, std::function<int (node, node)>> pq_lambda([](node a, node b) -> int {return a.val1.compare(b.val1);} );
cout << pq_lambda.someMethod() << endl;
return 0;
}
http://ideone.com/ryQmAn You need to compile this code for C++11 standard.
Here the template Comparator can be both pointer to function and lambda. If you are interested in lambdas, the two links I provided above should get you started.

Modifying private class variables within a class method?

This is probably a really basic error I'm making, but I'm quite new to c++ so please don't judge!
Basically, I've got two classes as follows:
class A{
private:
vector< vector<int> > images;
public:
int f1(int X, int Y);
}
class B{
private:
int x;
int y;
public:
int f2(A var);
}
I want to be able to call B.f2(A) with defined variables A and B and have f2() call A.f1(x,y). So far, all this works.
But the function f1 assigns values to the vector 'images' which aren't there when f2() returns. Any ideas why?
Here's the code:
int A::f1(int X, int Y){
// Some stuff to resize images accordingly
images[X][Y] = 4;
return 0;
}
int B::f2(A var){
var.f1(x, y);
return 0;
}
int main(){
A var1;
B var2;
// Stuff to set var2.x, var2.y
var2.f2(var1);
// HERE: var1.images IS UNCHANGED?
}
this is because you have passed A by value. instead, pass it by reference.
void fn(A& p);
^ << refer to the original object passed as the parameter.
as it is now, your program creates, and then mutates a copy of var1.
when you do not want to mutate the parameter, you can pass it as a const reference:
void fn(const A& p);
^^^^^ ^