When the friendly function add is used to print the value of sum variable of two classes, the correct output is printing. But, when then display function of their respective class are used, garbage value is printing.
What's wrong with the code?
#include <iostream>
using namespace std;
class DB;
class DM {
int m, cm;
float sum;
public:
void read()
{
cout << "Enter meters and centimeters respectively\n";
cin >> m >> cm;
}
void display(void)
{
cout << sum << " meters\n";
}
friend void add(DM p1, DB p2);
};
class DB {
int feet, inch;
float sum;
public:
void read()
{
cout << "Enter feets and inches respectively\n";
cin >> feet >> inch;
}
void display(void)
{
cout << sum << " feets\n";
}
friend void add(DM p1, DB p2);
};
void add(DM p1, DB p2)
{
float a = p2.feet * 12;
float b = a + p2.inch;
float c = b * .3048 + p1.m + p1.cm * .01;
//cout << c << endl;
p1.sum = c;
//cout << p1.sum << endl;
//p2.sum = (c/12)/.3048;
cout << p2.sum << endl;
}
int main()
{
DM obj1;
DB obj2;
obj1.read();
obj2.read();
add(obj1, obj2);
obj1.display();
obj2.display();
}
The problem is that you print sum but you never initialize the sum of obj1 and obj2.
You initialize sum only inside add() but you pass values to add() by copy, so you initialize sum only in temporary objects.
When you print obj1.sum and obj2.sum (through display()), the sum member are still not-initialized.
So the garbage.
Try passing objects by reference
// ..........V........V
void add (DM & p1, DB & p2)
This way the initialization of sum inside add() has effect also for calling objects.
Related
#include < iostream >
#include < iomanip >
using namespace::std;
#include < string.h >
class Human {
char Name[20];
int Age;
float Weight;
public:
Human() {
strcpy(Name, " ");
Age = Weight = 0;
}
Human(int AGE) {
this - > Age = Age;
}
Human(float Weight) {
this - > Weight = Weight;
}
Human(char * s) {
strcpy(this - > Name, s);
}
void GetData() {
cout << endl << "Enter the name : ";
gets(Name);
cout << endl << "Enter the Age : ";
cin >> Age;
cout << endl << "Enter the Weight :";
cin >> Weight;
}
void Display() {
cout << endl << "Name :" << Name;
cout << endl << "Age :" << Age;
cout << endl << fixed << "Weight :" << Weight << " Kg";
}
};
int main() {
Human h1;
h1 = 23; //It will assign 23 in Age
h1 = 67.45 f; //It will assign 67.45 in Weight
h1 = "Jimmy Neutron";
h1.Display();
cin.get();
return 0;
}
There are several issues here but let me start with the one you asked.
Why is the output like this:
Name :Jimmy Neutron Age :4194304 Weight :0.000000 Kg – Udesh
The reason is every time you assign values like this to your object i.e., h1
h1 = 23; //It will assign 23 in Age
h1 = 67.45f; //It will assign 67.45 in Weight
h1 = "Jimmy Neutron";
This is what is happening behind the scene, move assignment operator gets called.
h1.operator=(Human(23));
h1.operator=(Human(67.4499969f));
h1.operator=(Human("Jimmy Neutron"));
So, the other two arguments get overwritten everytime you write one of this.
To understand the problem, try using your display function after every assignment statement and see the output.
Now lets come to other issues.
Please avoid using char array and char pointer. We have the wonderful std::string for the very same purpose, please use it. IIRC, every major compiler warns about string literal to char * conversion.
I do not know if you realized, but the parameter name in one of your constructor that takes int is AGE but you are assigning age.
Please avoid using deprecated functions - [hint: gets]
Having 2 different objects (or instances (I do not know if they have any differences)) of a class, will they instantiate the constructor individually?
For example; Having a constructor that makes a variable z equal to 0. A function of the class adds 10 to z. So when I use the other object to call the same function, z will be 20 (previous value plus 10) or will it be 10 (0+10)?
Many thanks!
If you have a class A and a class B
struct A {
int x = 0;
void inc() { x+=10; }
};
struct B {
static int x;
void inc() { x+=10; }
};
int B::x = 0;
int main() {
A a1;
a1.inc();
std::cout << a1.x << '\n';
A a2;
a2.inc();
std::cout << a2.x << '\n';
B b1;
b1.inc();
std::cout << b1.x << '\n';
B b2;
b2.inc();
std::cout << b2.x << '\n';
}
Output:
10
10
10
20
For instances of class A the member variable x is not shared. Therefore a1.x and a2.x are both 10 after the respective incrementation.
However, for class B the keyword static declares x as a class variable that is shared among all instances. So incrementation in what-so-ever instance always increments the class member. After the first incrementation via b1.inc()the value of B::x is 10 and after the second incrementation via b2.inc() the value is 20.
I made a simple example to test boost bind's interaction with derived classes.
I created two subclasses with different getarea functions. I expected
g1 = boost::bind(boost::mem_fn(&Shape::getarea), Rec)
to print the area of Rectangle(10,20) but instead it printed '1'. I get the same when I instead write Rectangle::getarea. It prints the same even when I input other functions eg. member of Rectangle
double sum(double h,double w){return h+w; }
and use
g1 = boost::bind(boost::mem_fn(&Rectangle::sum), Rec,2,3)
Question 1: Why does it return '1'?Is that a default response for error?
My second problem is to do the same of printing g2 but now Rec is replaced by **iter, i.e. an object of some derived class type from a list of objects. Since getarea is a virtual fcn, once I get the above working it should be fine to just write:
g2= boost::bind(boost::mem_fn(& Shape::getarea , &(**iter));
Question 2: However, I was wondering if there is a way to return the classtype of **iter eg. classof(**iter) and then put it in g2 i.e.
g2= boost::bind(boost::mem_fn(& classof(**iter)::getarea , &(**iter));
When I ran g2 by writing Shape::getarea, I got '1' again for all iter.
#include <memory>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <boost/bind.hpp>
using namespace std;
class Shape {
public:
Shape(double h, double w) :height(h), width(w) {};
virtual double getarea() = 0;
double height;
double width; };
class Rectangle: public Shape {
public:
Rectangle(double h, double w): Shape(h,w) {};
double getarea() override { return height*width; } };
class Triangle : public Shape {
public:
Triangle(double h, double w) :Shape(h,w) {};
double getarea() { return height*width*0.5; }};
int main() {
//create objects
Rectangle Rec(10, 20);
Triangle Tri(2, 3);
//create boost bind function
boost::function<double(double, double)> g1;
g1 = boost::bind(boost::mem_fn(&Shape::getarea), Rec);
//print area and g
cout << Rec.getarea()<<" should be equal to " << g1<< '\n';
//create list
vector<shared_ptr<Shape>> Plist;
Plist.push_back(make_shared<Rectangle>(Rec));
Plist.push_back(make_shared<Triangle>(Tri));
//print each element from the vector list
for (auto iter = Plist.begin(); iter != Plist.end(); iter ++ ) {
boost::function<double(double, double)> g2;
g2= boost::bind(boost::mem_fn(& .... , &(**iter));
//where in dots we need Classtype_of_**iter::getarea
cout << (**iter).getarea()<<"should be equal to " << g2<< '\n';
}
}
You... forget to invoke the functions...
for (auto iter = Plist.begin(); iter != Plist.end(); iter++) {
boost::function<double()> g2;
g2 = boost::bind(&Shape::getarea, iter->get());
cout << (*iter)->getarea() << " should be equal to " << g2() << '\n';
}
What you saw what the implicit conversion to bool (http://www.boost.org/doc/libs/1_60_0/doc/html/boost/function.html#idm45507164686720-bb)
Note also I fixed the signature of g1 and g2: Live On Coliru.
Some further improvements (remove the need for the g2 in the loop?):
auto getarea = boost::mem_fn(&Shape::getarea);
for (auto iter = Plist.begin(); iter != Plist.end(); iter++) {
cout << (*iter)->getarea() << " should be equal to " << getarea(**iter) << '\n';
}
Or, indeed in c++11:
for (auto& s : Plist)
cout << s->getarea() << " should be equal to " << getarea(*s) << '\n';
By this time, you'd wonder why you have this accessor when you can just use the member.
enter code here
# include <iostream>
# include <stdlib.h>
# define MAX 10
void heapsort(int A[]);
void Build_MAX_Heap(int A[]);
void MAX_Heapify(int A[],int i);
int Left(int i);
int Right(int i);
void swap(int *num,int *num2);
using namespace std;
int main()
{
int H[100],i;
for(i=0;i<MAX;i++)
H[i]=rand();
cout << "the given array is::" << " ";
for(i=0;i<MAX;i++)
cout << H[i] << "\n";
cout << "\n" << "\n";
heapsort(H);
cout << "the sorted array is ::" << " ";
for(i=0;i<MAX;i++)
cout << H[i] << "\n";
}
void heapsort(int A[])
{
int i,heapsize;
Build_MAX_Heap(A);
for(i=MAX-1;i>0;i--)
{
swap(&A[0],&A[i]);
heapsize=heapsize-1;
MAX_Heapify(A,0);
}
}
void Build_MAX_Heap(int A[])
{
int heapsize,i;
heapsize=MAX;
for(i=(MAX)/2;i>0;i--)
{
MAX_Heapify(A,i);
}
}
void MAX_Heapify(int A[],int i)
{
int l,r,largest,heapsize;
l=Left(i);
r=Right(i);
if(l<=heapsize && A[l]>A[i])
largest=l;
else
largest=i;
if(r<=heapsize && A[r]>A[i])
largest=r;
if(largest!=i)
{
swap(&A[i],&A[largest]);
MAX_Heapify(A,largest);
}
}
int Left(int i)
{
return (2*i);
}
int Right(int i)
{
return (2*i+1);
}
` void swap(int *num1,int *num2)
{
int temp;
temp=*num1;
*num1=*num2;
*num2=temp;
}
whats wrong in my code.its not sorting.It shows the outout but not in the sorted order.please help.thanks for the same
There are a few flaws in your code.
The notation of left child being (2 * i), and right child being (2 * i + 1), is valid, if you are using your array as 1-indexed. But as you are using your arrays as 0-indexed, you must change them to, left child = (2 * i + 1), right child = (2 * i + 2).
Next thing, the variable 'heapsize' in your function 'MAX_Heapify()' is not initialised. You are using an unassigned variable, which is incorrect.
In your heap sort procedure, you are deleting the max element and decreasing the size of the heap. But your are not using the new size anywhere. You are supposed to pass it to 'MAX_Heapify()' so that the procedure knows its bounds.
Lastly, I think you must run the loop for heapify in Build_MAX_Heap till (i >= 0), i.e., for all the elements above (MAX / 2), including the root.
Correct these and re-write your code and I think you should be fine. If you to learn more about Binary Heaps with sketches and code, you can check my blog post on Binary Heaps.
I hope my answer has helped you, if it did, let me know...! ☺
Xcode gives me 3 "Apple Mach-O Linker (Id) Error" errors. But, when I click them it doesn't direct me to a line in my code, so I don't know what/where the problem is. I know others have asked this question, but all of the solutions that I could find were specific to each individual's code. I am learning C++, so these errors are coming as part of a beginner program I'm working on.
Apple Mach-O Linker (Id) Error
"SensorNode::SensorNode(char*, float, float, float, int, float)", referenced from:
Apple Mach-O Linker (Id) Error
"LOCATION::LOCATION()", referenced from:
Apple Mach-O Linker (Id) Error
Linker command failed with exit code 1 (use -v to see invocation)
If it helps, I'll put my code here:
here's my "sensor_node.h"
#ifndef SENSORNODE_H
#define SENSORNODE_H
#include <iostream>
class LOCATION {
float lat, longi, height;
public:
LOCATION ();
void setx(float xx);
void sety(float yy);
void setz(float zz);
void print();
};
class SensorNode {
char* NodeName;
int NodeID;
LOCATION Node1;
float batt;
int func;
public:
SensorNode(char *n, float x, float y, float z, int i, float ah);
void print();
void setOK(int o);
int getOK();
void setLOC(float longi, float lat, float h);
};
#endif /* defined(__Project_3__sensor_node__) */
here's my sensor_node.cpp:
#include "sensor_node.h"
//#include <iostream>
using namespace std;
void LOCATION::setx(float xx) {
lat = xx;
if (lat > 180.0 || lat < -180.0) {
cout << "Latitude is not in the -180 to 180 degree range";
lat = 0.0;
}
}
void LOCATION::sety(float yy) {
longi = yy;
if (longi > 180.0 || longi < -180.0) {
cout << "Latitude is not in the -180 to 180 degree range";
longi = 0.0;
}
}
void LOCATION::setz(float zz) {
height = zz;
}
void LOCATION::print() {
cout << "(LONGITUDE: " << longi << " ,LATITUDE: " << lat << " ,HEIGHT: " << height << " )";
}
and here's my main.cpp:
#include <iostream>
using namespace std;
#include "sensor_node.h"
int main() {
LOCATION a; SensorNode s1("Pulse",15.9,-30.1,0,157,2.0);
cout << "Beginning LOCATION tests.\n\n";
cout << " After initial construction: ";
a.print();
cout << "\n";
a.setx(-45.3);
a.sety(27.6);
a.setz(3.5);
cout << " After setting x/y/z to -45.3/27.6/3.5: ";
a.print();
cout << "\n";
cout << " After attempting to set longitude to 180.1: ";
a.setx(180.1);
a.print();
cout << "\n";
cout << " After attempting to set longitude to -180.1: ";
a.setx(-180.1);
a.print();
cout << "\n";
cout << " After attempting to set latitude to 180.1: ";
a.sety(180.1);
a.print();
cout << "\n";
cout << " After attempting to set latitude to -180.1: ";
a.sety(-180.1);
a.print();
cout << "\n";
/*
cout << "\n\n\n\nBeginning sensor node tests.\n\n";
cout << " After initial construction:";
s1.print();
cout << "\n Printing the value returned by getOK: " << s1.getOK();
cout << "\n After changing location to 20/30/40:";
s1.setLOC(20,30,40);
s1.print();
cout << "\n After trying to set location illegally:";
s1.setLOC(181, -181, 10);
s1.print();
cout << "\n Node fails, then try to change location:";
s1.setOK(0);
s1.setLOC(5,10,15);
s1.print();
cout << "\n Printing the value returned by getOK: " << s1.getOK();
cout << "\n\n\n End of tests.\n";
cout << "Enter an integer to quit: ";
cin >> hold;
*/
return 0;
}
You haven't written the constructor for the LOCATION class. You declare a LOCATION named a and a SensorNode which contains a LOCATION, but the linker can't figure out where the code for the LOCATION constructor is, so it can't link. Write a constructor for the LOCATION class and you should be good.
You seem to have forgotten to implement SensorNode. In SensorNode.h you declare a class, SensorNode which has data and public methods, but in SensorNode.cpp you are not providing an implementation of SensorNode (constructor), print etc. The linker is unable to find implementations of these since they haven't been implemented, hence the linker error.
Here's some boilerplate you can start out with:
SensorNode::SensorNode(char *n, float x, float y, float z, int i, float ah)
{
}
void SensorNode::print()
{
}
void SensorNode::setOK(int o)
{
}
int SensorNode::getOK()
{
}
void SensorNode::setLOC(float longi, float lat, float h)
{
}